51单片机简易可调的数码管电子钟程序

合集下载

51单片机作的电子钟程序及电路图

51单片机作的电子钟程序及电路图

51单片机作的电子钟程序在很多地方已经有了介绍,对于单片机学习者而言这个程序基本上是一道门槛,掌握了电子钟程序,基本上可以说51单片机就掌握了80%。

常见的电子钟程序由显示部分,计算部分,时钟调整部分构成。

时钟的基本显示原理:时钟开始显示为0时0分0秒,也就是数码管显示000000,然后每秒秒位加1 ,到9后,10秒位加1,秒位回0。

10秒位到5后,即59秒,分钟加1,10秒位回0。

依次类推,时钟最大的显示值为23小时59分59秒。

这里只要确定了1秒的定时时间,其他位均以此为基准往上累加。

开始程序定义了秒,十秒,分,十分,小时,十小时,共6位的寄存器,分别存在30h,31h,32h,33h,34h,35h单元,便于程序以后调用和理解。

6个数码管分别显示时、分、秒,一个功能键,可以切换调整时分秒、增加数值、熄灭节电等功能全部集一键。

以下是部分汇编源程序,购买我们产品后我们用光盘将完整的单片机汇编源程序和烧写文件送给客户。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 中断入口程序 ;; (仅供参考) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ORG 0000H ;程序执行开始地址LJMP START ;跳到标号START执行ORG 0003H ;外中断0中断程序入口RETI ;外中断0中断返回ORG 000BH ;定时器T0中断程序入口LJMP INTT0 ;跳至INTTO执行ORG 0013H ;外中断1中断程序入口RETI ;外中断1中断返回ORG 001BH ;定时器T1中断程序入口LJMP INTT1 ;跳至INTT1执行ORG 0023H ;串行中断程序入口地址RETI ;串行中断程序返回;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 主程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;START: MOV R0,#70H ;清70H-7AH共11个内存单元MOV R7,#0BH;clr P3.7 ;CLEARDISP: MOV @R0,#00H ;INC R0 ;DJNZ R7,CLEARDISP ;MOV 20H,#00H ;清20H(标志用)MOV 7AH,#0AH ;放入"熄灭符"数据MOV TMOD,#11H ;设T0、T1为16位定时器MOV TL0,#0B0H ;50MS定时初值(T0计时用)MOV TH0,#3CH ;50MS定时初值MOV TL1,#0B0H ;50MS定时初值(T1闪烁定时用)MOV TH1,#3CH ;50MS定时初值SETB EA ;总中断开放SETB ET0 ;允许T0中断SETB TR0 ;开启T0定时器MOV R4,#14H ;1秒定时用初值(50M S×20)START1: LCALL DISPLAY ;调用显示子程序JNB P3.7,SETMM1 ;P3.7口为0时转时间调整程序SJMP START1 ;P3.7口为1时跳回START1 SETMM1: LJMP SETMM ;转到时间调整程序SETMM; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 1秒计时程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;T0中断服务程序INTT0: PUSH ACC ;累加器入栈保护PUSH PSW ;状态字入栈保护CLR TR0 ;关闭定时器T0MOV A,#0B7H ;中断响应时间同步修正ADD A,TL0 ;低8位初值修正MOV TL0,A ;重装初值(低8位修正值)MOV A,#3CH ;高8位初值修正ADDC A,TH0 ;MOV TH0,A ;重装初值(高8位修正值)SETB TR0 ;开启定时器T0DJNZ R4, OUTT0 ;20次中断未到中断退出ADDSS: MOV R4,#14H ;20次中断到(1秒)重赋初值MOV R0,#71H ;指向秒计时单元(71H-72H)ACALL ADD1 ;调用加1程序(加1秒操作)MOV A,R3 ;秒数据放入A(R3为2位十进制数组合)CLR C ;清进位标志CJNE A,#60H,ADDMM ;ADDMM: JC OUTT0 ;小于60秒时中断退出ACALL CLR0 ;大于或等于60秒时对秒计时单元清0MOV R0,#77H ;指向分计时单元(76H-77H)ACALL ADD1 ;分计时单元加1分钟MOV A,R3 ;分数据放入ACLR C ;清进位标志CJNE A,#60H,ADDHH ;ADDHH: JC OUTT0 ;小于60分时中断退出ACALL CLR0 ;大于或等于60分时分计时单元清0MOV R0,#79H ;指向小时计时单(78H-79H)ACALL ADD1 ;小时计时单元加1小时MOV A,R3 ;时数据放入ACLR C ;清进位标志CJNE A,#24H,HOUR ;HOUR: JC OUTT0 ;小于24小时中断退出ACALL CLR0 ;大于或等于24小时小时计时单元清0OUTT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移MOV 73H,77H ;入对应显示单元MOV 74H,78H ;MOV 75H,79H ;POP PSW ;恢复状态字(出栈)POP ACC ;恢复累加器RETI ;中断返回; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 闪动调时程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;T1中断服务程序,用作时间调整时调整单元闪烁指示INTT1: PUSH ACC ;中断现场保护PUSH PSW ;MOV TL1, #0B0H ;装定时器T1定时初值MOV TH1, #3CH ;DJNZ R2,INTT1OUT ;0.3秒未到退出中断(50MS中断6次)MOV R2,#06H ;重装0.3秒定时用初值CPL 02H ;0.3秒定时到对闪烁标志取反JB 02H,FLASH1 ;02H位为1时显示单元"熄灭"MOV 72H,76H ;02H位为0时正常显示MOV 73H,77H ;MOV 74H,78H ;MOV 75H,79H ;INTT1OUT: POP PSW ;恢复现场POP ACC ;RETI ;中断退出FLASH1: JB 01H,FLASH2 ;01H位为1时,转小时熄灭控制MOV 72H,7AH ;01H位为0时,"熄灭符"数据放入分MOV 73H,7AH ;显示单元(72H-73H),将不显示分数据MOV 74H,78H ;MOV 75H,79H ;AJMP INTT1OUT ;转中断退出FLASH2: MOV 72H,76H ;01H位为1时,"熄灭符"数据放入小时MOV 73H,77H ;显示单元(74H-75H),小时数据将不显示MOV 74H,7AH ;MOV 75H,7AH ;AJMP INTT1OUT ;转中断退出; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 加1子程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ADD1: MOV A,@R0 ;取当前计时单元数据到ADEC R0 ;指向前一地址SWAP A ;A中数据高四位与低四位交换ORL A,@R0 ;前一地址中数据放入A中低四位ADD A,#01H ;A加1操作DA A ;十进制调整MOV R3,A ;移入R3寄存器ANL A,#0FH ;高四位变0MOV @R0,A ;放回前一地址单元MOV A,R3 ;取回R3中暂存数据INC R0 ;指向当前地址单元SWAP A ;A中数据高四位与低四位交换ANL A,#0FH ;高四位变0MOV @R0,A ;数据放入当削地址单元中RET ;子程序返回; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 清零程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;............. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 时钟调整程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;当调时按键按下时进入此程序SETMM: cLR ET0 ;关定时器T0中断CLR TR0 ;关闭定时器T0LCALL DL1S ;调用1秒延时程序JB P3.7,CLOSEDIS ;键按下时间小于1秒,关闭显示(省电)MOV R2,#06H ;进入调时状态,赋闪烁定时初值SETB ET1 ;允许T1中断SETB TR1 ;开启定时器T1SET2: JNB P3.7,SET1 ;P3.7口为0(键未释放),等待SETB 00H ;键释放,分调整闪烁标志置1SET4: JB P3.7,SET3 ;等待键按下LCALL DL05S ;有键按下,延时0.5秒JNB P3.7,SETHH ;按下时间大于0.5秒转调小时状态MOV R0,#77H ;按下时间小于0.5秒加1分钟操作LCALL ADD1 ;调用加1子程序MOV A,R3 ;取调整单元数据CLR C ;清进位标志CJNE A,#60H,HHH ;调整单元数据与60比较HHH: JC SET4 ;调整单元数据小于60转SET4循环LCALL CLR0 ;调整单元数据大于或等于60时清0CLR C ;清进位标志AJMP SET4 ;跳转到SET4循环CLOSEDIS: SETB ET0 ;省电(LED不显示)状态。

基于51单片机的简易电子时钟

基于51单片机的简易电子时钟

基于51单片机的简易电子时钟设计摘要今天,电子时钟是生活中不可或缺的一部分。

电子时钟通过数码管显示,具有整点报时等功能,可以使得我们的生活变得更加有序。

电子时钟也通过不断地改进,变得功能越来越强大。

本次设计的电子时钟利用单片机STC89C51进行控制的,利用单片机自身的定时器功能,采用数码管显示,可对电子时钟进行调整校准。

此设计具有相当重要的现实意义和实用价值。

基于单片机STC89C51的电子时钟,采用数码管显示“时“分“秒”而且可用按键进行调整校准。

此次设计与传统的机械表相比,它具有走的更精准,显示更直观等特点,而且单片机的数字时钟具有灵活编程,便于功能扩充等特点。

本次所设计主要有三个模块:显示模块,按键模块,闹铃模块。

该时钟采用STC89C51单片机自身定时器进行计时,按键模块采用独立式键盘(4个按键),闹铃部分由8550三极管和蜂鸣器构成,显示时、分、秒用两个四位共阴极数码管显示,具有可调整时间功能和设定闹钟功能,在设计过程中硬件和软件应同时进行。

关键词:电子时钟,单片机,闹钟,蜂鸣器SIMPLE ELECTRONIC CLOCK DESIGN BASED ON 51MCUABSTRACTToday , the electronic clock is an integral part of life . Through the digital display electronic clock , with the whole point timekeeping function , can make our life more orderly . The electronic clock also through continuous improvement , has become more and more powerful .The design of the electronic clock using STC89C51 MCU to control the use of single-chip , self timer function , the use of digital tube display , can adjust the calibration of the electronic clock . Has very important realistic significance and practical value of this design .The electronic clock based on MCU STC89C51 , using digital tube display " when " " seconds " and the button can be used to adjust the calibration . And the design of the traditional mechanical watch , it has to go more accurate , more intuitive display characteristics , and the digital clock has flexible programming , easy to function expansion and so on .This design has three main modules : the display module , keyboard module , alarm module . The clock uses STC89C51 microcontroller timer timing , key module with separate keyboard (4 buttons), the alarm is composed of 8550 transistors and a buzzer , when the display is divided bytwo seconds , four common cathode digital display , which can adjust the time and set the alarm function , hardware and software in the design process should be carried out at the same time .Key Words : electronic clock , microcontroller , alarm clock , a buzzer目录第一章绪论....................................................... - 1 -1.1 课题背景及意义.............................................. - 1 -1.2 课题内容.................................................... - 1 -1.2.1 题目及要求 ............................................ - 1 -1.2.2 主要部分 .............................................. - 2 - 第二章方案....................................................... - 3 -2.1 功能要求.................................................... - 3 -2.3 数码管显示方案.............................................. - 3 - 第三章电子时钟的硬件设计......................................... - 5 -3.1 电子时钟的组成.............................................. - 5 -3.2 单片机最小系统图............................................ - 5 -3.3 STC89C51引脚功能 ........................................... - 6 -3.4 数码管显示模块.............................................. - 7 -3.5 闹铃部分.................................................... - 7 -3.6 按键模块.................................................... - 8 - 第四章电子时钟的软件设计......................................... - 9 -4.1 电子时钟程序流程框图........................................ - 9 -4.2 按键调整流程图............................................. - 10 -4.3 子程序的设计............................................... - 11 -4.3.1 数码管显示模块 ....................................... - 11 -4.3.2 按键子模块 ........................................... - 11 -4.3.3 主程序 ............................................... - 12 - 第五章硬件的制作与测试分析...................................... - 13 -5.1 电子时钟的硬件制作......................................... - 13 -5.2 硬件测试................................................... - 13 -5.3 软件调试................................................... - 13 -5.4 测试结果分析与结论......................................... - 14 -5.4.1 数码管测试结果分析 ................................... - 14 -5.4.2 按键测试结论 ......................................... - 14 -5.4.3测试结论.............................................. - 15 - 总结与致谢....................................................... - 17 - 参考文献......................................................... - 19 - 附录............................................................. - 21 - 附录一分组表.................................................. - 21 - 附录二程序.................................................... - 22 - 附录三电子时钟实物图.......................................... - 33 -第一章绪论1.1 课题背景及意义二十一世纪的今天,电子时钟已经融入到千千万万户家庭中,它已经成为了人们生活中不可或缺的一部分。

51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)

51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)

51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)效果图:程序如下://51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)#include<reg51.h>#include<absacc.h>#define uchar unsigned char#define uint unsigned int/*七段共阴管显示定义*///此表为LED 的字模,共阴数码管0-9 -uchar code dispcode[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //段码控制/*定义并初始化变量*/uchar seconde=0;//秒uchar minite=0;//分uchar hour=12; //时uchar shi=0;//闹铃功能uchar fen=0;uchar bjcs;//报警次数sbit P1_0=P1^0; //second 调整定义sbit P1_1=P1^1; //minite调整定义sbit P1_2=P1^2; //hour调整定义sbit P1_5=P1^5; //整点报时sbit P1_3=P1^3; //闹铃功能,调整时间sbit P1_6=P1^6; //调整时sbit P1_7=P1^7; //调整分sbit P1_4=P1^4; //关闭闹铃/*函数声明*/void delay(uint k ); //延时子程序void time_pro( ); //时间处理子程序void display( ); //显示子程序void keyscan( ); //键盘扫描子程序/*xx子程序*/void delay (uint k){uchar j;while((k--)!=0){for(j=0;j<125;j++){;}}}/*时间处理子程序*/void time_pro(void){if(seconde==60){seconde=0;minite++;if(minite==60){minite=0;hour++;if(hour==24){hour=0;}}}}/*显示子程序*/void display(void){if(P1_3==1){P2=0XFE; P0=dispcode[seconde%10];//秒个位delay(1);P2=0XFD;P0=dispcode[seconde/10];//秒十位delay(1);P2=0XFB;P0=dispcode[10];//间隔符-delay(1);P2=0XF7;P0=dispcode[minite%10];//分个位delay(1);P2=0XEF;P0=dispcode[minite/10];//分十位delay(1);P2=0XDF;P0=dispcode[10];//间隔符-delay(1);P2=0XBF;P0=dispcode[hour%10];//时个位delay(1);P2=0X7F;P0=dispcode[hour/10];//时十位delay(1);}}/*键盘扫描子程序*/void keyscan(void){if(P1_0==0)//秒位的调整{delay (30);if(P1_0==0){seconde++;if(seconde==60){seconde=0;}}delay(250);}if(P1_1==0)//分位的调整{delay(30);if(P1_1==0){minite++;if(minite==60){minite=0;}}delay(250);}if(P1_2==0)//时位的调整{delay(30);if(P1_2==0){hour++;if(hour==24){hour=0;}}delay(250);}}/*整点报警*/void zhengdian (void){if((seconde==0)&(minite==0))//整点报时{P1_5=0;delay(1000);P1_5=1;}}/*定时闹钟*/void dingshi(void){if(P1_3==0)//按住P1_3BU不松,显示闹铃设置界面,分别按P1_6、P1_7设置闹铃时间。

51单片机电子闹钟程序(亲自编写,可用)

51单片机电子闹钟程序(亲自编写,可用)

学校电子钟,有闹钟功能,按键可调时间,可调打铃时间,打铃时间长短显示,每个模块有功能注释。

其中正常时间显示和闹钟时间显示可用一个开关来调整。

芯片选择STC89C52程序:#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//定义显示段码uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};uchar codebbtime[]={0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar clock[]={0,0,0,0};uchar clock1[]={12,30,0};uchar weikong[6];uchar bbduration=4;uchar lingtime=9;//学校打铃时间组uchar shangwu1[]={8,30};uchar shangwu2[]={10,0};uchar shangwu3[]={10,20};uchar shangwu4[]={11,50};uchar xiawu1[]={13,30};uchar xiawu2[]={15,00};uchar xiawu3[]={15,15};uchar xiawu4[]={16,45};//按键定义sbit mode=P1^7;sbit sec_clr=P1^0;sbit min_set_add=P1^3;sbit min_set_sub=P1^4;sbit hour_set_add=P1^1;sbit hour_set_sub=P1^2;sbit bb_set_add=P1^5;sbit bb_set_sub=P1^6;sbit speaker=P2^6;//延时函数void delay(unsigned int t){while(t--);//时钟进位函数void clockjinwei(){clock[0]++;if(clock[0]==20){clock[1]++;clock[0]=0;if(clock[1]==60){clock[2]++;clock[1]=0;if(clock[2]==60){clock[3]++;clock[2]=0;if(clock[3]==24)clock[3]=0;}}}}//定时器0中断服务函数void timer0(void) interrupt 1 using 1 {TMOD=0x01;TH0=0x3c;TL0=0xb0;clockjinwei();}//时钟分位显示函数void fenwei(){weikong[0]=clock[3]/10;weikong[1]=clock[3]%10;weikong[2]=clock[2]/10;weikong[3]=clock[2]%10;weikong[4]=clock[1]/10;weikong[5]=clock[1]%10;}//闹钟分位显示函数void naofen(){weikong[0]=clock1[0]/10;weikong[1]=clock1[0]%10;weikong[2]=clock1[1]/10;weikong[3]=clock1[1]%10;weikong[4]=clock1[2]/10;weikong[5]=clock1[2]%10; }//闹钟定时显示函数void naozhongdisplay(){uchar z,s;uchar x=0x01;naofen();for(z=0;z<6;z++){P2=0;P0=table[weikong[z]];P2=x;x=_crol_(x,1);for(s=0;s<255;s++);}}//时钟显示函数void display(){uchar i,j;uchar x=0x01;fenwei();for(i=0;i<6;i++){P2=0;P0=table[weikong[i]];P2=x;x=_crol_(x,1);for(j=0;j<255;j++);}}//总显示函数void zhongxian(){if(mode==1)delay(100);if(mode==1)display();if(mode==0)delay(100);if(mode==0)naozhongdisplay();}//按键处理程序void key_set(){zhongxian();P1=0xff;if(min_set_add==0){delay(100);if(min_set_add==0){if(mode==1){clock[2]++;if(clock[2]==60){clock[2]=0;}while(min_set_add==0)zhongxian();}}if(mode==0){clock1[1]++;if(clock1[1]==60){clock1[1]=0;}while(min_set_add==0)zhongxian();}}//if(min_set_sub==0){delay(100);if(min_set_sub==0){if(mode==1){clock[2]--;if(clock[2]==0)clock[2]=59;}while(min_set_sub==0)zhongxian();if(mode==0){clock1[1]--;if(clock1[1]==0)clock1[1]=59;}while(min_set_sub==0)zhongxian();}}//if(hour_set_add==0){delay(100);if(hour_set_add==0){if(mode==1){clock[3]++;if(clock[3]==24){clock[3]=0;}while(hour_set_add==0)zhongxian();}if(mode==0){clock1[0]++;if(clock1[0]==24){clock1[0]=0;}while(hour_set_add==0)zhongxian();}}}//if(hour_set_sub==0){delay(100);if(hour_set_sub==0){if(mode==1){clock[3]--;if(clock[3]==0)clock[3]=23;}while(hour_set_sub==0)zhongxian();if(mode==0){clock1[0]--;if(clock1[0]==0)clock1[0]=23;}while(hour_set_sub==0)zhongxian();}}//if(sec_clr==0){delay(100);if(sec_clr==0){clock[1]=0;}while(sec_clr==0)zhongxian();}}//闹钟响铃函数void bb(){if(clock[1]<=bbduration){speaker=1;delay(100);speaker=0;}else speaker=0;}//打铃函数void daling(){if(clock[1]<=lingtime){speaker=1;delay(100);speaker=0;}else speaker=0;}//时间比较函数void bijiao(){if(clock[3]==shangwu1[0]){if(clock[2]==shangwu1[1])daling();}if(clock[3]==shangwu2[0]){if(clock[2]==shangwu2[1])daling();}if(clock[3]==shangwu3[0]){if(clock[2]==shangwu3[1])daling();}if(clock[3]==shangwu4[0]){if(clock[2]==shangwu4[1])daling();}if(clock[3]==xiawu1[0]){if(clock[2]==xiawu1[1])daling();}if(clock[3]==xiawu2[0]){if(clock[2]==xiawu2[1])daling();}if(clock[3]==xiawu3[0]){if(clock[2]==xiawu3[1])daling();}if(clock[3]==xiawu4[0]){if(clock[2]==xiawu4[1])daling();}}//闹钟比较void naobijiao(){if(clock[3]==clock1[0]){if(clock[2]==clock1[1]||clock[2]==clock1[1]+1||clock[2]==clock1[1]+2) bb();}}//响铃时长显示函数void bbtimeshow(){P3=bbtime[bbduration];if(bbduration>15)bbduration=0;}//响铃按键处理函数void bbtime_set(){bbtimeshow();if(bb_set_add==0){delay(100);if(bb_set_add==0)bbduration++;while(bb_set_add==0)bbtimeshow();}if(bb_set_sub==0){delay(100);if(bb_set_sub==0)bbduration--;while(bb_set_sub==0)bbtimeshow();}}//主程序void main(){EA=1;ET0=1;TR0=1;while(1){key_set();bijiao();bbtime_set();naobijiao();}}电路图:分四部分显示:如果在学习这个程序过程中有什么问题,可以发邮件到******************询问。

51单片机可调时电子时钟程序

51单片机可调时电子时钟程序

//*******************基于51单片机的可调时电子时钟实验**********************////***电子时钟前两位为分钟,后两位为秒钟,逢38秒进1分***********************////***按下调时键第一次,秒钟闪烁,进入编辑状态******************************////***按下调时键第二次,分钟闪烁,进入编辑状态******************************////***按下调时键第三次,则确定**********************************************////***在编辑状态下,按下增/减按钮,闪烁位则进行加/减操作********************////***若在编辑状态下,按下增/减按钮时间超过1S,则闪烁位以0.5秒的速度自加1***//#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit wela1=P2^4;sbit wela2=P2^5;sbit wela3=P2^6;sbit wela4=P2^7;sbit key1=P1^5;sbit key2=P1^6;sbit key3=P1^7;//位定义uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};uchar miao,fen,mode,modeflag;//模式标志位bit flag,flash,miao_long,fen_long;//*********延时子函数*************// void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}//********定时器T0和变量的初始化****// void T0_init(){miao=00;fen=00;mode=0;modeflag=0;flash=0;flag=0;P2=0x0f;//锁存允许接口全部置低电平TMOD=0x01;//选择定时器工作方式TH0=(65536-2000)/256;TL0=(65536-2000)%256;//赋初值EA=1;//开总中断ET0=1;//开定时器中断TR0=1;//启动定时器}//*******数码管显示子函数***********// void display(){if(flag==0)//闪烁标志位为0时不闪烁{wela1=1;P0=table[fen/10];wela1=0;wela2=1;P0=table[fen%10];wela2=0; //送数给分位显示wela3=1;P0=table[miao/10];wela3=0;wela4=1;P0=table[miao%10];wela4=0; //送数给秒位显示}else //闪烁标志位为1时闪烁{if(mode==1)//模式为1,即调秒{if(miao_long==0)//没有长按加、减按钮{if(flash==0)//当闪烁等于0时{wela3=1;P0=table[miao/10];wela3=0;wela4=1;P0=table[miao%10];wela4=0;}else//当闪烁等于1时{P0=0xff;wela3=0;wela4=1;P0=0xff;wela4=0;}}else//长按了加、减按钮{wela3=1;P0=table[miao/10];wela3=0;wela4=1;P0=table[miao%10];wela4=0;}}else//模式为2,即调分{wela3=1;P0=table[miao/10];wela3=0;wela4=1;P0=table[miao%10];wela4=0; //在秒位熄灭的那一刻,按下调时键时,要把秒位点亮if(fen_long==0)//没有长按加、减按钮{if(flash==0){P0=table[fen/10];wela1=0;wela2=1;P0=table[fen%10];wela2=0;}else{wela1=1;P0=0xff;wela1=0;wela2=1;P0=0xff;wela2=0;}}else//长按了加、减按钮{wela1=1;P0=table[fen/10];wela1=0;wela2=1;P0=table[fen%10];wela2=0;}}}}//*********key1按钮子程序**************//void key1_scan(){if(key1==0){delay(10);//消抖if(key1==0){modeflag++;//模式标志位自加1flag=1;//闪烁标志位打开mode++;//模式自加1if(mode==3)//只在模式1:调秒,模式2:调分中间选择mode=0;while(!key1);//松手检测}}else if(modeflag==3)//按键次数到了第三次{modeflag=0;flag=0;while(!key1);}}//************key2,key3子程序**************//void key23_scan(){if(key2==0)//加数的操作{delay(10);if(key2==0){if(mode==1)//如果是模式1的话,key2键对秒加1{miao++;if(miao==38)//38秒进1分miao=0;delay(1000);//若按下的时间超过了1S钟,则视为长按while(!key2){miao_long=1;miao++;if(miao==38)miao=0;delay(200);}miao_long=0;//跳出长按,恢复短按的状态}else if(mode==2)//如果是模式2的话,key2键对分加一{fen++;if(fen==60)//60分钟进1fen=0;delay(1000);//若按下的时间超过了1S钟,则视为长按while(!key2){fen_long=1;fen++;if(fen==60)fen=0;delay(200);}fen_long=0;//跳出长按,恢复短按的状态}}else if(key3==0)//减数的操作{delay(10);if(key3==0){if(mode==1)//如果是模式1的话,key3键对秒减一{miao--;if(miao==0)miao=37;delay(1000);//若按下的时间超过了1S钟,则视为长按while(!key3){miao_long=1;miao--;if(miao==0)miao=37;delay(200);}miao_long=0;//跳出长按,恢复短按的状态}else if(mode==2)//如果是模式2的话,key3键对分减一{fen--;if(fen==0)fen=59;delay(1000);//若按下的时间超过了1S钟,则视为长按while(!key3)fen_long=1;fen--;if(fen==0)fen=59;delay(200);}fen_long=0;//跳出长按,恢复短按的状态}}}}void main(){T0_init();while(1){key1_scan();key23_scan();}}void T0_time() interrupt 1{static uchar t=0;static uint i=0;TH0=(65536-50000)/256;TL0=(65536-50000)%256;if(flag==0)//时间显示调整{i++;if(i==20){i=0;miao++;if(miao==38){miao=0;fen++;if(fen==60){fen=0;}}}}t++;if(t==10){t=0;flash=~flash;//闪烁标志位取反}display();}。

51单片机数字钟实验(原理图及程序)

51单片机数字钟实验(原理图及程序)

51单片机数字钟实验(原理图及程序)1.实验任务(1.开机时,显示12:00:00的时间开始计时;(2.P0.0/AD0控制“秒”的调整,每按一次加1秒;(3.P0.1/AD1控制“分”的调整,每按一次加1分;(4.P0.2/AD2控制“时”的调整,每按一次加1个小时;2.电路原理图图4.20.13.系统板上硬件连线(1.把“单片机系统”区域中的P1.0-P1.7端口用8芯排线连接到“动态数码显示”区域中的A-H端口上;(2.把“单片机系统:区域中的P3.0-P3.7端口用8芯排线连接到“动态数码显示”区域中的S1-S8端口上;(3.把“单片机系统”区域中的P0.0/AD0、P0.1/AD1、P0.2/AD2端口分别用导线连接到“独立式键盘”区域中的SP3、SP2、SP1端口上;4.相关基本知识(1.动态数码显示的方法(2.独立式按键识别过程(3.“时”,“分”,“秒”数据送出显示处理方法5.程序框图6.汇编源程序SECOND EQU 30HMINITE EQU 31HHOUR EQU 32HHOURK BIT P0.0MINITEK BIT P0.1SECONDK BIT P0.2DISPBUF EQU 40HDISPBIT EQU 48HT2SCNTA EQU 49HT2SCNTB EQU 4AHTEMP EQU 4BHORG 00HLJMP STARTORG 0BHSTART: MOV SECOND,#00HMOV MINITE,#00HMOV HOUR,#12MOV DISPBIT,#00HMOV T2SCNTA,#00HMOV T2SCNTB,#00HMOV TEMP,#0FEHLCALL DISPMOV TMOD,#01HMOV TH0,#(65536-2000) / 256 MOV TL0,#(65536-2000) MOD 256 SETB TR0SETB ET0SETB EAWT: JB SECONDK,NK1LCALL DELY10MSJB SECONDK,NK1INC SECONDMOV A,SECONDCJNE A,#60,NS60MOV SECOND,#00HNS60: LCALL DISPJNB SECONDK,$NK1: JB MINITEK,NK2LCALL DELY10MSJB MINITEK,NK2INC MINITECJNE A,#60,NM60 MOV MINITE,#00H NM60: LCALL DISPJNB MINITEK,$ NK2: JB HOURK,NK3LCALL DELY10MS JB HOURK,NK3INC HOURMOV A,HOURCJNE A,#24,NH24 MOV HOUR,#00H NH24: LCALL DISPJNB HOURK,$NK3: LJMP WTDELY10MS:MOV R6,#10D1: MOV R7,#248DJNZ R7,$DJNZ R6,D1RETDISP:MOV A,#DISPBUF ADD A,#8DEC AMOV R1,AMOV A,HOURMOV B,#10MOV @R1,ADEC R1MOV A,BMOV @R1,ADEC R1MOV A,#10MOV@R1,ADEC R1MOV A,MINITE MOV B,#10DIV ABMOV @R1,ADEC R1MOV A,BMOV @R1,ADEC R1MOV A,#10MOV@R1,ADEC R1MOV A,SECOND MOV B,#10DIV ABMOV @R1,ADEC R1MOV A,BMOV @R1,ADEC R1INT_T0:MOV TH0,#(65536-2000) / 256 MOV TL0,#(65536-2000) MOD 256 MOV A,#DISPBUFADD A,DISPBITMOV R0,AMOV A,@R0MOV DPTR,#TABLEMOVC A,@A+DPTRMOV P1,AMOV A,DISPBITMOV DPTR,#TABMOVC A,@A+DPTRMOV P3,AINC DISPBITMOV A,DISPBITCJNE A,#08H,KNAMOV DISPBIT,#00HKNA: INC T2SCNTAMOV A,T2SCNTACJNE A,#100,DONEMOV T2SCNTA,#00HINC T2SCNTBMOV A,T2SCNTBCJNE A,#05H,DONEMOV T2SCNTB,#00HINC SECONDMOV A,SECONDCJNE A,#60,NEXTMOV SECOND,#00HINC MINITEMOV A,MINITECJNE A,#60,NEXTMOV MINITE,#00HINC HOURMOV A,HOURCJNE A,#24,NEXTMOV HOUR,#00HNEXT: LCALL DISPDONE: RETITABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H TAB: DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FHEND7.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]]; P3=dispbitcode[dispbitcnt];dispbitcnt++;if(dispbitcnt==8){dispbitcnt=0;}}tcnt++;if(tcnt==4000){tcnt=0;second++;if(second==60){second=0;minite++;if(minite==60){minite=0;hour++;if(hour==24) {hour=0; }}}dispbuf[0]=second%10; dispbuf[1]=second/10; dispbuf[3]=minite%10; dispbuf[4]=minite/10; dispbuf[6]=hour%10; dispbuf[7]=hour/10; }}。

基于51单片机的简易电子钟设计

基于51单片机的简易电子钟设计

基于51单片机的简易电子钟设计一、设计目的现代社会对于时间的要求越来越精确,电子钟成为家庭和办公场所不可缺少的设备之一、本设计基于51单片机,旨在实现一个简易的电子钟,可以显示当前的时间,并且能够通过按键进行时间的调整和设置闹钟。

二、设计原理本设计主要涉及到51单片机的IO口、定时器、中断、LCD显示技术等方面知识。

1.时钟模块时钟模块采用定时器0的中断进行时间的累加和更新。

以1秒为一个时间单位,每当定时器0中断发生,就将时间加1,并判断是否需要更新小时、分钟和秒的显示。

同时,根据用户按键的操作,可以调整时间的设定。

2.显示模块显示模块采用16x2字符LCD显示屏,通过51单片机的IO口与LCD连接。

可以显示当前时间和设置的闹钟时间。

初次上电或者重置后,LCD显示时间为00:00:00,通过定时器中断和键盘操作,实现时间的更新和设定闹钟功能。

3.键盘模块键盘模块采用矩阵键盘连接到51单片机的IO口上,用于用户进行时间的调整和设置闹钟。

通过查询键盘的按键状态,根据按键的不同操作,实现时间的调整和闹钟设定功能。

4.中断模块中断模块采用定时器0的中断,用于1秒的定时更新时间。

同时可以添加外部中断用于响应用户按键操作。

三、主要功能和实现步骤1.系统初始化。

2.设置定时器,每1秒产生一次中断。

3.初始化LCD显示屏,显示初始时间00:00:00。

4.查询键盘状态,判断是否有按键按下。

5.如果按键被按下,根据不同按键的功能进行相应的操作:-功能键:设置、调整、确认。

-数字键:根据键入的数字进行时间的调整和闹钟设定。

6.根据定时器的中断,更新时间的显示。

7.判断当前时间是否与闹钟设定时间相同,如果相同,则触发闹钟,进行提示。

8.循环执行步骤4-7,实现连续的时间显示和按键操作。

四、系统总结和改进使用51单片机设计的简易电子钟可以显示当前时间,并且实现时间的调整和闹钟设定功能。

但是由于硬件资源有限,只能实现基本的功能,不能进行其他高级功能的扩展,例如闹铃的音乐播放、温度、湿度的显示等。

51单片机c语言电子钟已加入调时闹铃整点报时功能

51单片机c语言电子钟已加入调时闹铃整点报时功能

51 单片机 c 语言电子钟(已加入调时、闹铃、整点报时功能)效果图:程序如下://51 单片机c 语言电子钟(已加入调时、闹铃、整点报时功能)#include<reg51.h>#include<absacc.h>#define uchar unsigned char #define uint unsigned int /* 七段共阴管显示定义*/ // 此表为LED 的字模,共阴数码管0-9 - uchar code dispcode[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; // 段码控制/* 定义并初始化变量*/ uchar seconde=0;// 秒uchar minite=0;// 分uchar hour=12; // 时uchar shi=0;// 闹铃功能uchar fen=0;uchar bjcs;// 报警次数sbit P1_0=P1A0; //second 调整定义sbit P1_仁P1A1;//minite 调整定义sbit P1_2二PM2; //hour 调整定义sbitP1_5=P1A5; //整点报时sbit P1_3=P1A3; //闹铃功能,调整时间sbit P1_6=P1A6; //调整时sbit P1_7=P1A7; //调整分sbit P1_4=P1A4; //关闭闹铃/* 函数声明*/void delay(uint k ); // 延时子程序void time_pro( ); // 时间处理子程序void display( ); // 显示子程序void keyscan( ); // 键盘扫描子程序/*xx 子程序*/void delay (uint k){uchar j;while((k--)!=0){for(j=0;j<125;j++){;}}}/* 时间处理子程序*/void time_pro(void){if(seconde==60){seconde=0; minite++;if(minite==60){minite=0;hour++;if(hour==24){hour=0;}}}}/* 显示子程序*/void display(void){if(P1_3==1){P2=0XFE;PO=dispcode[seco nde%10];/秒个位delay(1);P2=0XFD;P0=dispcode[seco nde/10];〃秒十位delay(1);P2=0XFB;P0=dispcode[10];// 间隔符-delay(1);P2=0XF7;P0=dispcode[mi nite%10];〃分个位delay(1);P2=0XEF;P0=dispcode[minite/10];// 分十位delay(1);P2=0XDF;P0二dispcode[10];〃间隔符-delay(1);P2=0XBF;P0=dispcode[hour%10];〃时个位delay(1);P2=0X7F;P0=dispcode[hour/10];// 时十位delay(1);}}/* 键盘扫描子程序*/void keyscan(void){if(P1_0==0)//秒位的调整{delay (30);if(P1_0==0){seconde++;if(seconde==60){seconde=0;}}delay(250);}if(P1_仁=0)//分位的调整{delay(30);if(P1_1==0){minite++;if(minite==60){minite=0;}}delay(250);}if(P1_2==0)// 时位的调整{delay(30);if(P1_2==0){hour++;if(hour==24){hour=0;}}delay(250);}}/* 整点报警*/void zhengdian (void){if((seconde==0)&(minite==0))〃整点报时{P1_5=0;delay(1000);P1_5=1;}}/* 定时闹钟*/void dingshi(void){if(P1_3==0)〃按住P1_3BU不松,显示闹铃设置界面,分别按P1_6、P1_7设置闹铃时间。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include <reg52.h>
sbit KEY1=P3^0;
sbit KEY2=P3^1;
sbit KEY3=P3^2;
sbit KEY4=P3^3;
sbit LED=P1^2;
code unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//共阳数码管0-9
unsigned char StrTab[8]; //定义缓冲区
unsigned char minute=30,hour=12,second; //定义并且初始化值12:30:00
void delay(unsigned int cnt)//延时函数
{
while(--cnt);
}
void Displaypro(void)
{
StrTab[0]=tab[hour/10]; //显示正常时间
StrTab[1]=tab[hour%10];
StrTab[2]=0xBF;
StrTab[3]=tab[minute/10];
StrTab[4]=tab[minute%10];
StrTab[5]=0xBF;
StrTab[6]=tab[second/10];
StrTab[7]=tab[second%10];
}
main()//主函数
{
TMOD |=0x01;//定时器0 10ms in 12M crystal 用于计时
TH0=0xd8;
TL0=0xf0;
ET0=1;
TR0=1;
TMOD |=0x10; //定时器1用于动态扫描
TH1=0xF8;
TL1=0xf0;
ET1=1;
TR1=1;
EA =1;
Displaypro();
while(1)//主循环
{
/////////////////////////////////////////////////////////////////
if(!KEY1) //按键1去抖以及动作
{
delay(10000);
if(!KEY1)
{
hour++;if(hour==24)hour=0; //正常时间小时加1
Displaypro();
}
}
////////////////////////////////////////////////////////////////
if(!KEY2) //按键2去抖以及动作
{
delay(10000);
if(!KEY2)
{
hour--;if(hour==0)hour=23; //正常时间小时减1
Displaypro();
}
}
////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
if(!KEY3) //按键去抖以及动作
{
delay(10000);
if(!KEY3)
{
minute++;if(minute==59)minute=0;//分加1
Displaypro();
}
}
/////////////////////////////////////////////////////////////////
if(!KEY4) //按键去抖以及动作
{
delay(10000);
if(!KEY4)
{
minute--;if(minute==0)minute=59; //分减1
Displaypro();
}
}
}
}
////////////////////////////////////////////////////////////////
/********************************/
/* 定时中断1 */
/********************************/
void time1_isr(void) interrupt 3 using 0//定时器1用来动态扫描
{
static unsigned char num;
TH1=0xF8;//重入初值
TL1=0xf0;
switch (num){
case 0:P2=0xFE;P0=StrTab[num];break; //分别调用缓冲区的值进行扫描case 1:P2=0xFD;P0=StrTab[num];break;
case 2:P2=0xFB;P0=StrTab[num];break;
case 3:P2=0xF7;P0=StrTab[num];break;
case 4:P2=0xEF;P0=StrTab[num];break;
case 5:P2=0xDF;P0=StrTab[num];break;
case 6:P2=0xBF;P0=StrTab[num];break;
case 7:P2=0x7F;P0=StrTab[num];break;
default:break;
}
num++; //扫描8次,使用8个数码管
if(num==8)
num=0;
}
//////////////////////////////////////////////////////////////////
/********************************/
/* 定时中断0 */
/********************************/
void tim(void) interrupt 1 using 1
{
static unsigned char count;//定义内部静态变量
TH0=0xd8;//重新赋值
TL0=0xf0;
count++;
switch (count)
{
case 0:
case 20:
case 40:
case 60:
case 80:Displaypro(); //隔一定时间调用显示处理
break;
case 50:LED=!LED; //半秒LED闪烁
break;
default:break;
}
if (count==100)
{
count=0;
second++;//秒加1
if(second==60)
{
second=0;
minute++; //分加1
if(minute==60)
{
minute=0;
hour++; //时加1
if(hour==24)
hour=0;
}
}
}
}
本程序是基于51单片机简易可调的数码管电子时钟程序,按键可以调整当时时间,按键可以调节定时时间,定时时间到继电器吸合,8位数码管显示时间格式格式12-08-00 标示12点08分00秒,S1 用于小时加1操作,S2 用于小时减1操作,S3 用于分钟加1操作,S4 用于分钟减1操作。

相关文档
最新文档