当前位置:文档之家› 七段数码管显示实验

七段数码管显示实验

单片机实验报告实验九七段数码管显示实验一、实验目的1.学习七段数码管的工作原理;2.学习数码管与8051单片机的接口方法;3.掌握动态扫描显示技术。

二、实验原理如图4.9-1所示,LED数码管由7个发光二极管组成,此外,还有一个圆点型发光二极管(在图中以dp表示),用于显示小数点。

通过七段发光二极管亮共阴极接法共阳极接法图4.9-1暗的不同组合,可以显示多种数字、字母以及其它符号。

LED数码管中的发光二极管共有两种连接方法:1)共阴极接法:把发光二极管的阴极连在一起构成公共阴极。

使用时公共阴极接地,这样阳极端输入高电平的段发光二极管就导通点亮,而输入低电平的则不点亮。

实验中使用的LED显示器为共阴极接法2)共阳极接法:把发光二极管的阳极连在一起构成公共阳极。

使用时公共阳极接+5V。

这样阴极端输入低电平的段发光二极管就导通点亮,而输入高电平的则不点亮。

为了显示数字或符号,要为LED显示器提供代码,因为这些代码是为显示字形的,因此称之为字形代码。

七段发光二极管,再加上一个小数点位,共计八段。

因此提供给LED显示器的字形代码正好一个字节。

若a、b、c、d、e、f、g、dp 8个显示段依次对应一个字节的低位到高位,即D0、D1、D2、D3、D4、D5、D6、D7,则用共阴极LED数码管显示十六进制数时所需的字形代码如表4.9-1所示。

表4.9-1 共阴极LED 数码管字形代码 字型 共阴极字形代码 字型 共阴极字形代码字型共阴极字形代码0 3FH 6 7DH C 39H 1 06H 7 07H d 5EH 2 5BH 8 7FH E 79H 3 4FH 9 6FH F 71H 4 66H A 77H 灭 00H 56DHb7CH*实际上试验中使用的是共阳极数码管,这里就不一一列出。

2、动态显示按图4.9-2(b )连接线路,通过交替选中LED1和LED0循环显示两位十进制数。

七段数码管段码连接不变,位码驱动输入端S1、S0接8255A C 口的PC1、PC0,通过C 口的这两位交替输出1和0,以便交替选中LED1和LED0,从而实现两位十进制数的交替显示。

请编程实现在两个LED 数码管上循环显示00 99,程序流程图如图4.9-3(b)所示。

(a) 静态显示程序流程图 (b) 动态显示程序流程图 图4.9-3 十位数的段码至A 口 个位数的段码至A 口 开始 开始返回DOS 返回DOS 延时并修改要显示的数字三、实验电路图第一部分电路图:第二部分电路图:四、实验设备微型计算机、单片机仿真器、实验仪、示波器(各一台);实验连线(若干)。

五、实验内容*由于汇编语言程序中已经做了相应的注释,C语言的编程原理与之相同处不再做重复注释,仅作个别注释,请见谅。

1.编程在8位数码管上面显示“12345678”8个数字,每经过1秒8个数字循环左移一位显示。

依次为:1234578、23456781、34567812.......汇编语言程序代码:O RG 0000HSTART:M OV R4,#00HFLASH:M OV R2,#01HM OV R0,#30HM OV DPTR,#TABFLA ;把字形表首地址给外部寻址寄存器LOPFLA:M OV A,R2 ;输出位型M OV P2,AM OV A,@R0M OVC A,@A+DPTR ;在程序段中查表得到字形M OV P1,A ;输出字形M OV R3,#0D JNZ R3,$ ;循环等待延时M OV P1,#0FFH ;关显示M OV A,R2 ;位型左移一位R L AM OV R2,AI NC R0 ;下一个字形C JNE R0,#38H,GOONM OV R0,#30HGOON:C JNE A,#01H,LOPFLA ;若已经显示一遍则初始化I NC R4C JNE R4,#7FH,GOON1M OV A,30H ;显示表左移更新M OV 30H,31HM OV 31H,32HM OV 32H,33HM OV 33H,34HM OV 34H,35HM OV 35H,36HM OV 36H,37HM OV 37H,AM OV R4,#00HGOON1:A JMP FLASHTABFLA: ;字形表D B 0C0H,0F9H,0A4H,0B0H,99HD B 92H,82H,0F8H,80H,90H,88HD B 83H,0C6H,0A1H,86H,8EHENDC语言程序代码:#include<reg51.h>data unsigned char disadd _at_ 0x30;const unsigned char LED_TAB[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};data unsigned char j;void delay(){u nsigned char i=0xFF;w hile(i--){;}}void change_s(){u nsigned char *k;u nsigned char m;k=&disadd;m=*k; //显示表移位*k=*(k+1);*(k+1)=*(k+2);*(k+2)=*(k+3);*(k+3)=*(k+4);*(k+4)=*(k+5);*(k+5)=*(k+6);*(k+6)=*(k+7);*(k+7)=m;j=0x00; //计数值初始化}main(){u nsigned char i;u nsigned char disbit;u nsigned char *disnum,*n;S P=0x40;j=0x00;n=&disadd;*(n)=0x01; //显示设置初值为1~8 *(n+1)=0x02;*(n+2)=0x03;*(n+3)=0x04;*(n+4)=0x05;*(n+5)=0x06;*(n+6)=0x07;*(n+7)=0x08;w hile(1){disbit=0x01;disnum=&disadd;for(i=0;i<8;i++){P2=0x00;P1=LED_TAB[*disnum];P2=disbit;delay();disbit=disbit<<1;disnum++;}j++;if(j==0x3f){change_s(); //调用显示表移位子程序}}}2.用8255的PA口作为段码输出口,编写程序,利用定时器T0作为时间基准控制电子钟走时,电子钟的格式为:XX—XX—XX分钟—秒钟—百分秒汇编语言程序代码:C OM_ADD XDATA 0F003HP A_ADD XDATA 0F000HP B_ADD XDATA 0F001HP C_ADD XDATA 0F002HO RG 0000HA JMP STARTO RG 000BHA JMP T0INTO RG 0030HSTART:M OV SP,#60H ;设置堆栈M OV TMOD,#01H ;设置定时器T0的控制字M OV TH0,#0F0H ;设置定时器计数初值M OV TL0,#07FHM OV R7,#00H ;显示寄存器置初值M OV R6,#00HM OV R5,#00HM OV R4,#00HM OV R3,#00HM OV R2,#00HM OV 32H,#16 ;设置显示分隔符M OV 35H,#16S ETB ET0 ;允许中断(T0内部中断)S ETB EAS ETB TR0 ;开始计数CONTINUE:M OV 37H,R7 ;进位判断,R7表示百分之一秒(之后的以此类推)M OV 36H,R6C JNE R6,#0AH,NOREACHM OV R6,#00HM OV 36H,R6I NC R5M OV 34H,R5C JNE R5,#0AH,NOREACHM OV R5,#00HM OV 34H,R5I NC R4M OV 33H,R4C JNE R4,#06H,NOREACHM OV R4,#00HM OV 33H,R4I NC R3M OV 31H,R3C JNE R3,#0AH,NOREACHM OV R3,#00HM OV 31H,R3I NC R2M OV 30H,R2C JNE R2,#06H,NOREACHM OV R2,#00HM OV 30H,R2NOREACH:A CALL DISPLAY ;调用显示子程序A JMP CONTINUE;中断子程序T0INT:I NC R7 ;R7表示百分之一秒(之后的以此类推)C JNE R7,#0AH,NOREACH_SM OV R7,#00HI NC R6NOREACH_S:M OV TH0,#0F0H ;计数完一次后再次置计数初值M OV TL0,#07FHR ETI;数码管显示子程序DISPLAY:M OV R1,#01H ;位型输出指针M OV R0,#30HM OV DPTR,#COM_ADDM OV A,#80HM OVX @DPTR,ALOPFLA:M OV DPTR,#PB_ADDM OV A,R1M OVX @DPTR,AM OV DPTR,#TABFLAM OV A,@R0M OVC A,@A+DPTR ;在程序段中查表得到字形M OV DPTR,#PA_ADDM OVX @DPTR,AM OV A,#00HWAIT:D EC AC JNE A,#00H,WAIT ;等待延时M OV DPTR,#PA_ADDM OV A,#0FFHM OVX @DPTR,A ;关显示M OV A,R1 ;位型左移一位R L AM OV R1,AI NC R0 ;下一个字形C JNE A,#01H,LOPFLA ;若已经显示一遍则初始化R ETTABFLA:D B 0C0H,0F9H,0A4H,0B0H,99HD B 92H,82H,0F8H,80H,90H,88HD B 83H,0C6H,0A1H,86H,8EHD B 0BFHENDC语言程序代码:#include<reg51.h>#define TIMEINT 0x01#define TIMEH 0xf0#define TIMEL 0x7fxdata unsigned char con_address _at_ 0xf003;xdata unsigned char pa _at_ 0xf000;xdata unsigned char pb _at_ 0xf001;xdata unsigned char pc _at_ 0xf002;data unsigned char disadd _at_ 0x30;const unsigned char LED_TAB[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xBF};data unsigned char r2,r3,r4,r5,r6,r7; //显示变量设置为全局变量void delay(){u nsigned char i=0xFF;w hile(i--){;}}void timer0(void) interrupt 1 using 1 //中断子程序{r7++;i f(r7==0x0A){r7=0x00;r6++;}T H0=TIMEH;T L0=TIMEL;}void display() //显示子程序{u nsigned char i;u nsigned char disbit;u nsigned char *disnum;disbit=0x01;disnum=&disadd;for(i=0;i<8;i++){pb=0x00;pa=LED_TAB[*disnum];pb=disbit;delay();disbit=disbit<<1;disnum++;}}main(){u nsigned char *n;S P=0x40;c on_address=0x80;T MOD=TIMEINT;T H0=TIMEH;T L0=TIMEL;n=&disadd;r7=0x00;r6=0x00;r5=0x00;r4=0x00;r3=0x00;r2=0x00;*(n+2)=16;*(n+5)=16;E T0=1;E A=1;T R0=1;w hile(1){*(n+7)=r7; //显示进位判断*(n+6)=r6;if(r6==0x0A){r6=0x00;*(n+6)=r6;r5++;*(n+4)=r5;if(r5==0x0A){r5=0x00;*(n+4)=r5;r4++;*(n+3)=r4;if(r4==0x06){r4=0x00;*(n+3)=r4;r3++;*(n+1)=r3;if(r3==0x0A){r3=0x00;*(n+1)=r3;r2++;*n=r2;if(r6==0x06){r2=0x00;*n=r2;}}}}}display();}}六、实验小结通过本次试验,我基本上掌握了数码管显示的程序流程,学会编写一些程序调用相应的相应的子程序,显示所需内容,了解了动态扫描显示的程序执行过程,结合定时器的设置和中断的返回,来实现最基本的百分秒显示,从而完成时钟显示,由此,结合前面所学的知识,巩固了数码管显示的知识,增强了我的程序调试能力,为下一步的学习打下了坚实基础。

相关主题