收藏 分销(赏)

51单片机汇编语言与C语言经典实例.doc

上传人:二*** 文档编号:4513693 上传时间:2024-09-26 格式:DOC 页数:31 大小:2.51MB 下载积分:5 金币
下载 相关 举报
51单片机汇编语言与C语言经典实例.doc_第1页
第1页 / 共31页
本文档共31页,全文阅读请下载到手机保存,查看更方便
资源描述
3 / 31 51单片机汇编语言与C语言经典实例 实验与课程设计 51单片机汇编语言与C语言经典实例 一、闪烁灯 如图1 所示为一简单单片机系统原理图:在 P1.0 端口上接一个发光二极管 L1,使 L1 在不停地一亮一灭,一亮一灭的时间间隔为 0.2 秒。 延时程序的设计方法,作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为 0.2 秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程 序是如何设计呢?下面具体介绍其原理:如图 4.1.1 所示的石英晶体为 12MHz,因此,1 个机器周期为 1 微秒,机器周期 微秒如图 1 所示,当 P1.0 端口输出高电平,即 P1.0=1 时,根据发光二极管的单向导电性可知,这时发光二极管 L1 熄灭;当 P1.0 端口输出低电平,即 P1.0=0 时,发光二极管 L1 亮;我们可以使用 SETB P1.0 指令使 P1.0端口输出高电平,使用 CLR P1.0 指令使 P1.0 端口输出低电平。 C 语言源程序 #include <AT89X51.H> sbit L1=P1^0; void delay02s(void) //延时 0.2 秒子程序 { 图1 单片机原理图 unsigned char i,j,k; for(i=20;i>0;i--) for(j=20;j>0;j--) for(k=248;k>0;k--); } void main(void) { while(1) { L1=0; delay02s(); L1=1; delay02s(); } 汇编源程序 ORG 0 START: CLR P1.0 LCALL DELAY 图2 程序设计流程图 SETB P1.0 LCALL DELAY LJMP START DELAY: MOV R5,#20 ;延时子程序,延时 0.2 秒 D1: MOV R6,#20 D2: MOV R7,#248 DJNZ R7,$ DJNZ R6,D2 DJNZ R5,D1 RET END 二、多路开关状态指示 如图 3 所示,AT89S51 单片机的 P1.0-P1.3 接四个发光二极管 L1-L4, P1.4-P1.7 接了四个开关 K1-K4,编程将开关的状态反映到发光二极管上。 (开关闭合,对应的灯亮,开关断开,对应的灯灭)。 对于开关状态检测,相对单片机来说,是输入关系,我们可轮流检测每个开关状 态,根据每个开关的状态让相应的发光二极管指示,可以采用 P1.X,REL 或 JNB P1.X,REL 指令来完成;也可以一次性检测四路开关状态,然后让其指 示,可以采用 MOV A,P1 指令一次把 P1 端口的状态全部读入,然后取高 4 位的状态来指示。 方法1(汇编源程序) ORG 00H START: MOV A,P1 ANL A,#0F0H RR A RR A RR A RR A ORL A,#0F0H MOV P1,A SJMP START END 方法1(C语言程序) 图4 程序流程图 #INClude <AT89X51.H> unsigned char temp; void main(void) { while(1) { temp=P1>>4; temp=temp | 0xf0; P1=temp; } } 方法2(汇编源程序) ORG 00H START: P1.4,NEXT1 CLR P1.0 SJMP NEX1 图3 单片机原理图 NEXT1: SETB P1.0 NEX1: P1.5,NEXT2 CLR P1.1 SJMP NEX2 NEXT2: SETB P1.1 NEX2: P1.6,NEXT3 CLR P1.2 SJMP NEX3 NEXT3: SETB P1.2 NEX3: P1.7,NEXT4 CLR P1.3 SJMP NEX4 NEXT4: SETB P1.3 NEX4: SJMP START END 方法2(C 语言源程序) #INClude <AT89X51.H> void main(void) { while(1) { if(P1_4==0) { P1_0=0; } Else { P1_0=1; } if(P1_5==0) { P1_1=0; } else { P1_1=1; } if(P1_6==0) { P1_2=0; } else { P1_2=1; } if(P1_7==0) { P1_3=0; } else 图5 单片机原理图 三、广告灯的设计 利用取表的方法,使端口 P1 做单一灯的变化:左移 2 次,右移 2 次,闪烁 2 次 (延时的时间 0.2 秒)。 利用 MOV DPTR,#DATA16 的指令来使数据指针寄存器指到表的开 头。 利用 MOVC A,@A+DPTR 的指令,根据累加器的值再加上 DPTR 的 值,就可以使程序计数器 PC 指到表格所要取出的数据。因此,只要把控制码建成一个表,而利用 MOVC A,@A+DPTR 做取码的操作, 就可方便地处理一些复杂的控制动作,取表过程如下图所示: 汇编源程序 ORG 0 START: MOV DPTR,#TABLE LOOP: CLR A MOVC A,A+DPTR CJNE A,#01H,LOOP1 JMP START LOOP1: MOV P1,A MOV R3,#20 LCALL DELAY INC DPTR JMP LOOP DELAY: MOV R4,#20 D1: MOV R5,#248 图6 程序流程图 DJNZ R5,$ DJNZ R4,D1 DJNZ R3,DELAY R RET TABLE: DB 0FEH,0FDH,0FBH,0F7H DB 0EFH,0DFH,0BFH,07FH DB 0FEH,0FDH,0FBH,0F7H DB 0EFH,0DFH,0BFH,07FH DB 07FH,0BFH,0DFH,0EFH DB 0F7H,0FBH,0FDH,0FEH DB 07FH,0BFH,0DFH,0EFH DB 0F7H,0FBH,0FDH,0FEH DB 00H, 0FFH,00H, 0FFH DB 01H END C 语言源程序 #INClude <AT89X51.H> unsigned char code table[]={0xfe,0xfd,0xfb,0xf7, 0xef,0xdf,0xbf,0x7f,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f, 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x7f,0xbf,0xdf,0xef, 0xf7,0xfb,0xfd,0xfe,0x00,0xff,0x00,0xff,0x01}; unsigned char i; void delay(void) { unsigned char m,n,s; for(m=20;m>0;m--) for(n=20;n>0;n--) for(s=248;s>0;s--); } void main(void) { while(1) { if(table[i]!=0x01) { P1=table[i]; i++; delay(); } else { i=0; } } } 四、 00-59 秒计时器 如下图8所示,在 AT89S51 单片机的 P0 和 P2 端口分别接有两个共阴数码管,P0 口驱动显示秒的时间的十位,而 P2 口驱动显示秒的时间的个位。在设计过程中我们用一个存储单元作为秒计数单元,当一秒钟到来时,就让秒计数单元加 1,当秒计数达到 60 时,就自动返回到 0,重新秒计数。 对于秒计数单元中的数据要把它十位数和个位数分开,方法仍采用对 10 整除和对 10 求余。 汇编源程序 Second EQU 30H ORG 0000H START: MOV Second,#00H NEXT: MOV A,Second MOV B,#10 DIV AB MOV DPTR,#TABLE MOVC A,A+DPTR MOV P0,A MOV A,B MOVC A,A+DPTR MOV P2,A LCALL DELY1S INC Second MOV A,Second CJNE A,#60,NEXT 图7 程序流程图 LJMP START DELY1S: MOV R5,#100 D2: MOV R6,#20 D1: MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 DJNZ R5,D2 RET TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH END C 语言源程序 #include <AT89X51.H> unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char Second; void delay1s(void) { unsigned char i,j,k; for(k=100;k>0;k--) for(i=20;i>0;i--) for(j=248;j>0;j--); } void main(void) { Second=0; P0=table[Second/10]; P2=table[Second%10]; while(1) { delay1s(); Second++; if(Second==60) { Second=0; } P0=table[Second/10]; P2=table[Second%10]; } } 图8 单片机原理图 五、动态数码显示技术 如图9所示,P0 端口接动态数码管的字形码笔段,P2 端口接动态数码管的数位选择端,P1.7 接 一个开关,当开关接高电平时,显示“12345”字样;当开关接低电平时,显示“HELLO”字样。 动态扫描方法:动态接口采用各数码管循环轮流显示的方法,当循环显示频率较高时,利用人眼的暂留特性,看不出闪烁显示现象,这种显示需要一个接口完成字形码的输出(字形选择),另一接口完成各数码管的轮流点亮(数位选择)。 在进行数码显示的时候,要对显示单元开辟 8 个显示缓冲区,每个显示缓冲区装有显示的不同数据即可。对于显示的字形码数据我们采用查表方法来完成。 汇编源程序 图9 单片机原理图 ORG 0000H START: P1.7,DIR1 MOV DPTR,#TABLE1 SJMP DIR DIR1: MOV DPTR,#TABLE2 DIR: MOV R0,#00H MOV R1,#01H NEXT: MOV A,R0 MOVC A,A+DPTR MOV P0,A MOV A,R1 MOV P2,A LCALL DAY INC R0 RL A MOV R1,A CJNE R1,#0DFH,NEXT SJMP START DAY: MOV R6,#4 D1: MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 图10 单片机原理图 RET TABLE1: DB 06H,5BH,4FH,66H,6DH TABLE2: DB 78H,79H,38H,38H,3FH END C 语言源程序 #include <AT89X51.H> Unsigned char code table1[]={0x06,0x5b,0x4f,0x66,0x6d}; Unsignedcharcode table2[]={0x78,0x79,0x38,0x38,0x3f}; Unsignedchar i; Unsignedchar a,b; Unsignedchar temp; void main(void) { while(1) { temp=0xfe; for(i=0;i<5;i++) { if(P1_7==1) { P0=table1[i]; } else { P0=table2[i]; } P2=temp; a=temp<<(i+1); b=temp>>(7-i); temp=a|b; for(a=4;a>0;a--) for(b=248;b>0;b--); } } 六、4×4 矩阵式键盘识别技术 如图11所示,用 AT89S51 的并行口 P1 接 4×4 矩阵键盘,以 P1.0-P1.3作输入线,以 P1.4-P1.7 作输出线;在数码管上显示每个按键的“0-F”序。对应的按键的序号排列如图12所示每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。矩阵的行线和列线分别通过两并行接口和 CPU 通信。每个按键的状态同样需变成数字量“0”和“1”,开关的一端(列线)通过电阻接 VCC,而接地是通过程序输出数字“0”实现的。键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么; 还要消除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的 功能。 汇编源程序 KEYBUF EQU 30H ORG 00H START: MOV KEYBUF,#2 WAIT: MOV P3,#0FFH CLR P3.4 MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY1 LCALL DELY10MS MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY1 MOV A,P3 ANL A,#0FH CJNE A,#0EH,NK1 MOV KEYBUF,#0 LJMP DK1 NK1: CJNE A,#0DH,NK2 MOV KEYBUF,#1 LJMP DK1 NK2: CJNE A,#0BH,NK3 MOV KEYBUF,#2 LJMP DK1 NK3: CJNE A,#07H,NK4 MOV KEYBUF,#3 LJMP DK1 NK4: NOP DK1: MOV A,KEYBUF MOV DPTR,#TABLE MOVC A,A+DPTR MOV P0,A DK1A: MOV A,P3 ANL A,#0FH XRL A,#0FH JNZ DK1A NOKEY1: MOV P3,#0FFH CLR P3.5 MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY2 LCALL DELY10MS MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY2 MOV A,P3 ANL A,#0FH CJNE A,#0EH,NK5 MOV KEYBUF,#4 LJMP DK2 NK5: CJNE A,#0DH,NK6 MOV KEYBUF,#5 LJMP DK2 NK6: CJNE A,#0BH,NK7 MOV KEYBUF,#6 LJMP DK2 NK7: CJNE A,#07H,NK8 MOV KEYBUF,#7 LJMP DK2 NK8: NOP DK2: MOV A,KEYBUF MOV DPTR,#TABLE MOVC A,A+DPTR MOV P0,A DK2A: MOV A,P3 ANL A,#0FH XRL A,#0FH JNZ DK2A NOKEY2: MOV P3,#0FFH CLR P3.6 MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY3 LCALL DELY10MS MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY3 MOV A,P3 ANL A,#0FH CJNE A,#0EH,NK9 MOV KEYBUF,#8 LJMP DK3 NK9: CJNE A,#0DH,NK10 MOV KEYBUF,#9 LJMP DK3 NK10: CJNE A,#0BH,NK11 MOV KEYBUF,#10 LJMP DK3 NK11: CJNE A,#07H,NK12 MOV KEYBUF,#11 LJMP DK3 NK12: NOP DK3: MOV A,KEYBUF MOV DPTR,#TABLE MOVC A,A+DPTR MOV P0,A DK3A: MOV A,P3 ANL A,#0FH XRL A,#0FH JNZ DK3A NOKEY3: MOV P3,#0FFH CLR P3.7 MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY4 LCALL DELY10MS MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY4 MOV A,P3 ANL A,#0FH CJNE A,#0EH,NK13 MOV KEYBUF,#12 LJMP DK4 NK13: CJNE A,#0DH,NK14 MOV KEYBUF,#13 LJMP DK4 NK14: CJNE A,#0BH,NK15 MOV KEYBUF,#14 LJMP DK4 NK15: CJNE A,#07H,NK16 MOV KEYBUF,#15 LJMP DK4 NK16: NOP DK4: MOV A,KEYBUF MOV DPTR,#TABLE MOVC A,A+DPTR MOV P0,A DK4A: MOV A,P3 ANL A,#0FH XRL A,#0FH JNZ DK4A NOKEY4: LJMP WAIT DELY10MS: MOV R6,#10 D1: MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 RET TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H END C 语言源程序 #INClude <AT89X51.H> unsigned char code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; unsigned char temp; unsigned char key; unsigned char i,j; void main(void) { while(1) { P3=0xff; P3_4=0; temp=P3; temp=temp & 0x0f; if (temp!=0x0f) { for(i=50;i>0;i--) for(j=200;j>0;j--); temp=P3; temp=temp & 0x0f; if (temp!=0x0f) { temp=P3; temp=temp & 0x0f; switch(temp) { case 0x0e: key=7; break; case 0x0d: key=8; break; case 0x0b: key=9; break; case 0x07: key=10; break; } temp=P3; P1_0=~P1_0; P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) { temp=P3; temp=temp & 0x0f; } } } P3=0xff; P3_5=0; temp=P3; temp=temp & 0x0f; if (temp!=0x0f) { for(i=50;i>0;i--) for(j=200;j>0;j--); temp=P3; temp=temp & 0x0f; if (temp!=0x0f) { temp=P3; temp=temp & 0x0f; switch(temp) { case 0x0e: key=4; break; case 0x0d: key=5; break; case 0x0b: key=6; break; case 0x07: key=11; break; } temp=P3; P1_0=~P1_0; P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) { temp=P3; temp=temp & 0x0f; } } } P3=0xff; P3_6=0; temp=P3; temp=temp & 0x0f; if (temp!=0x0f) { for(i=50;i>0;i--) for(j=200;j>0;j--); temp=P3; temp=temp & 0x0f; if (temp!=0x0f) { temp=P3; temp=temp & 0x0f; switch(temp) { case 0x0e: key=1; break; case 0x0d: key=2; break; case 0x0b: key=3; break; case 0x07: key=12; break; } temp=P3; P1_0=~P1_0; P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) { temp=P3; temp=temp & 0x0f; } } } P3=0xff; P3_7=0; temp=P3; temp=temp & 0x0f; if (temp!=0x0f) { for(i=50;i>0;i--) for(j=200;j>0;j--); temp=P3; temp=temp & 0x0f; if (temp!=0x0f) { temp=P3; temp=temp & 0x0f; switch(temp) { case 0x0e: key=0; break; case 0x0d: key=13; break; case 0x0b: key=14; break; case 0x07: key=15; break; } temp=P3; P1_0=~P1_0; P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) { temp=P3; temp=temp & 0x0f; } } } } } 七、按键识别方法 每按下一次开关 SP1,计数值加 1,通过AT89S51 单片机的 P1 端口的 P1.0 到 P1.3 显示出其二进制计数值。 *程序设计方法:作为一个按键从没有按下到按下以与释放是一个完整的过程,也就是说,当我们按下一个按键时,总希望某个命令只执行一次,而在按键按下的 过程中,不要有干扰进来,因为,在按下的过程中,一旦有干扰过来,可能造成误触发过程,这并不是我们所想要的。因此在按键按下的时候,要把我们手上的干扰信号以与按键的机械接触等干扰信号给滤除掉,一般情况下,我们可以采用电容来滤除掉这些干扰信号,但实际上,会增加硬件成本与硬件电路的体积,这是我们不希望,总得有个办法解决这个问题,因此我们可以采用软件滤波的方法去除这些干扰信号,一般情况下,一个按键按下的时候,总是在按下的时刻存在着一定的干扰信号,按下之后就基本上进入了稳定的状态。具体的一个按键从按下到释放的全过程的信号图如上图所示:从图中可以看出,我们在程序设计时,从按键被识别按下之后,延时 5ms 以上,从而避开了干扰信号区域,我们再来检测一次,看按键是否真得已经按下,若真得已经按下,这时肯定输出为低电平,若这时检测到的是高电平,证明刚才是由于干扰信号引起的误触发,CPU 就认为是误触发信号而舍弃这次的按键识别过程。从而提高了系统的可靠性。 由于要求每按下一次,命令被执行一次,直到下一次再按下的时候,再执行一次命令,因此从按键被识别出来之后,我们就可以执行这次的命令,所以要有一个等待按键释放的过程,显然释放的过程,就是使其恢复成高电平状态。 1. 汇编源程序 ORG 0000H START: MOV R1,#00H ;初始化 R1 为 0,表示从 0 开始计数 MOV A,R1 ; CPL A ;取反指令 MOV P1,A ;送出 P1 端口由发光二极管显示 REL: P3.7,REL ;判断 SP1 是否按下 LCALL DELAY10MS ;若按下,则延时 10ms 左右 P3.7,REL ;再判断 SP1 是否真得按下 INC R1 ;若确实按下,则进行按键处理,使 MOV A,R1 ;计数容加 1,并送出 P1 端口由 CPL A ;发光二极管显示 MOV P1,A ; JNB P3.7,$ ;等待 SP1 释放 SJMP REL ;继续对 K1 按键扫描 DELAY10MS: MOV R6,#20 ;延时 10ms 子程序 L1: MOV R7,#248 DJNZ R7,$ DJNZ R6,L1 RET END 2. C 语言源程序 #include <AT89X51.H> unsigned char count; void delay10ms(void) { unsigned char i,j; for(i=20;i>0;i--) for(j=248;j>0;j--); } void main(void) { while(1) { if(P3_7==0) { delay10ms(); if(P3_7==0) { count++; if(count==16) { count=0; } P1=~count; while(P3_7==0); } } } } 八、数字钟 (1. 开机时,显示 12:00:00 的时间开始计时; (2. P0.0/AD0 控制“秒”的调整,每按一次加 1 秒; (3. P0.1/AD1 控制“分”的调整,每按一次加 1 分; (4. P0.2/AD2 控制“时”的调整,每按一次加 1 个小时 6. 汇编源程序 SECOND EQU 30H MINITE EQU 31H HOUR EQU 32H HOURK BIT P0.0 MINITEK BIT P0.1 SECONDK BIT P0.2 DISPBUF EQU 40H DISPBIT EQU 48H T2SCNTA EQU 49H T2SCNTB EQU 4AH TEMP EQU 4BH ORG 00H LJMP START ORG 0BH LJMP INT_T0 START: MOV SECOND,#00H MOV MINITE,#00H MOV HOUR,#12 MOV DISPBIT,#00H MOV T2SCNTA,#00H MOV T2SCNTB,#00H MOV TEMP,#0FEH LCALL DISP MOV TMOD,#01H MOV TH0,#(65536-2000) / 256 MOV TL0,#(65536-2000) MOD 256 SETB TR0 SETB ET0 SETB EA WT: SECONDK,NK1 LCALL DELY10MS SECONDK,NK1 INC SECOND MOV A,SECOND CJNE A,#60,NS60 MOV SECOND,#00H NS60: LCALL DISP JNB SECONDK,$ NK1: MINITEK,NK2 LCALL DELY10MS MINITEK,NK2 INC MINITE MOV A,MINITE CJNE A,#60,NM60 MOV MINITE,#00H NM60: LCALL DISP JNB MINITEK,$ NK2: HOURK,NK3 LCALL DELY10MS HOURK,NK3 INC HOUR MOV A,HOUR CJNE A,#24,NH24 MOV HOUR,#00H NH24: LCALL DISP JNB HOURK,$ NK3: LJMP WT DELY10MS: MOV R6,#10 D1: MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 RET DISP: MOV A,#DISPBUF ADD A,#8 DEC A MOV R1,A MOV A,HOUR MOV B,#10 DIV AB MOV R1,A DEC R1 MOV A,B MOV R1,A DEC R1 MOV A,#10 MOVR1,A DEC R1 MOV A,MINITE MOV B,#10 DIV AB MOV R1,A DEC R1 MOV A,B MOV R1,A DEC R1 MOV A,#10 MOVR1,A DEC R1 MOV A,SECOND MOV B,#10 DIV AB MOV R1,A DEC R1 MOV A,B MOV R1,A DEC R1 RET INT_T0: MOV TH0,#(65536-2000) / 256 MOV TL0,#(65536-2000) MOD 256 MOV A,#DISPBUF ADD A,DISPBIT MOV R0,A MOV A,R0 MOV DPTR,#TABLE MOVC A,A+DPTR MOV P1,A MOV A,DISPBIT MOV DPTR,#TAB MOVC A,A+DPTR MOV P3,A INC DISPBIT MOV A,DISPBIT CJNE A,#08H,KNA MOV DISPBIT,#00H KNA: INC T2SCNTA MOV A,T2SCNTA CJNE A,#100,DONE MOV T2SCNTA,#00H INC T2SCNTB MOV A,T2SCNTB CJNE A,#05H,DONE MOV T2SCNTB,#00H INC SECOND MOV A,SECOND CJNE A,#60,NEXT MOV SECOND,#00H INC MINITE MOV A,MINITE CJNE A,#60,NEXT MOV MINITE,#00H INC HOUR MOV A,HOUR CJNE A,#24,NEXT MOV HOUR,#00H NEXT: LCALL DISP DONE: RETI TABLE: DB 3FH,06H,5BH,4FH,66H,6DH, 7DH,07H,7FH,6FH,40H TAB: DB 0FEH,0FDH,0FBH,0F7H,0EFH, 0DFH,0BFH,07FH END 7. C 语言源程序 #INClude <AT89X51.H> unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; unsigned char dispbitcode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; unsigned char dispbuf[8]={0,0,16,0,0,16,0,0}; unsigned char dispbitcnt; unsigned char second; unsigned char minite; unsigned char hour; unsigned int tcnt; unsigned char mstcnt; unsigned char i,j; void main(void) { TMOD=0x02; TH0=0x06; TL0=0x06; TR0=1; ET0=1; EA=1; while(1) { if(P0_0==0) { for(i=5;i>0;i--) for(j=248;j>0;j--); if(P0_0==0) { second++; if(second==60) { second=0; } dispbuf[0]=second%10; dispbuf[1]=second/10; while(P0_0==0); } } if(P0_1==0) { for(i=5;i>0;i--) for(j=248;j>0;j--); if(P0_1==0) { minite++; if(minite==60) { minite=0; } dispbuf[3]=minite%10; dispbuf[4]=minite/10; while(P0_1==0); } } if(P0_2==0) { for(i=5;i>0;i--) for(j=248;j>0;j--); if(P0_2==0) { hour++; if(hour==24) { hour=0; } dispbuf[6]=hour%10; dispbuf[7]=hour/10; while(P0_2==0); } } } } void t0(void) interrupt 1 using 0 { mstcnt++; if(mstcnt==8) { mstcnt=0; P1=dispcode[dispbuf[dispbitcnt]]; P
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 通信科技 > 开发语言

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服