单片机课设定时闹钟代码及注解
- 格式:docx
- 大小:5.53 KB
- 文档页数:2
单片机课程设计定时闹钟-CAL-FENGHAI-(2020YEAR-YICAI)_JINGBIAN一、任务说明本设计师定时闹钟的设计,由单片机AT89C51芯片和LCD、LED显示器,辅以必要的的电路,构成一个单片机定时闹钟。
电子钟可采用数字电路实现,也可以采用单片机来完成。
LCD显示“时”,“分”,LED闪动来做秒计数,定时时间到能发出警报声或者启动继电器,从而控制电器的启停。
现在是自动化高度发达的时代,特别是电子类产品都是靠内部的控制电路来实现对产品的控制,达到自动运行的目的,这就需要我们这里要做的设计中的电器元件及电路的支持。
在这次设计中主要是用AT89S51来进行定时,也结合着其他辅助电路实施控制,在定时的时候,按一下控制小时的键对小时加一;按一下控制分钟的键对分钟加一;到达预设的时间,此电路就会发出报警声音提示已经到点。
二、原理图绘制说明1、原理及工作过程说明(1)定时闹钟的基本功能如下:(a)使用LCD液晶显示器来显示现在的时间。
(b)程序执行之后显示“Time:00:00”;并且LED闪烁,表示开始已经计时。
(c)由LED闪动来做秒计数表示。
(2)按键功能如下:按键K1设置现在的时间和时调整;按键K2显示闹钟设置的时间和分调整;按键K3设置闹铃的时间和设置完成;按键K4闹铃ON/OFF的状态设置,设置为ON时连续三次发出“哗”的一声,设置为OFF发出“哗”的一声和闹铃时间到时,发出一阵声响,按下本键可以停止声响。
(3)调整计时器时间如下:按下K1键,然后按K1调整小时,K2调整分钟,按下K3表示时间设置完成。
(4)调整闹钟时间设置如下 :再次按下K3开始闹中设置,LCD下一行显示“Alarm:00:00”按下K1设置小时,按一下K2设置分钟,再次按下K3设置完成,并且设置时间消失,当再次按一下K2时“Alarm:00:00再次显示并马上消失。
按一下K4关闭闹钟,再次按下打开闹钟。
2、原理总框图图1 总原理图3、元器件功能说明AT89C51单片机引脚功能说明本设计的核心硬件就是8051芯片,这里选择了AT89C51,AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。
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设置闹铃时间。
学校电子钟,有闹钟功能,按键可调时间,可调打铃时间,打铃时间长短显示,每个模块有功能注释。
其中正常时间显示和闹钟时间显示可用一个开关来调整。
芯片选择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();}}电路图:分四部分显示:如果在学习这个程序过程中有什么问题,可以发邮件到******************询问。
河南理工大学单片机课程设计报告定时闹钟姓名:XXX学号:XXX专业班级:XXX指导老师:XXX所在学院:电气工程与自动化学院XXX年6月30日本设计是用单片机原理及其相关硬件的运用实现的定时闹钟。
数字电子钟设计与制作可采用数字电路实现,也可以采用单片机来完成。
若用数字电路完成,所设计的电路相当复杂,大概需要十几片数字集成块,其功能也主要依赖于数字电路的各功能模块的组合来实现,焊接的过程比较复杂,成本也非常高。
若用单片机来设计制作完成,由于其功能的实现主要通过软件编程来完成,那么就降低了硬件电路的复杂性,而且其成本也有所降低,所以在该设计与制作中采用单片机AT89C51,它是低功耗、高性能的CMOS型8位单片机。
片内带有4KB的Flash存储器,且允许在系统内改写或用编程器编程。
另外, AT89C51的指令系统和引脚与8051完全兼容,片内有128B 的RAM、32条I/O口线、2个16位定时计数器、5个中断源、一个全双工串行口等。
显示部分采用六位一体的共阳极数码管,运用同相三态双向总线收发器74LS245作为输出驱动显示部件的元件。
在编写程序的过程采用了定时程序和时间调整程序对称的编写方法。
并且在时间的调整或设置过程中本设计采用了长按进行调时或调分的选择,短按是进行在选择后进行加1,每短按一次,该单位加1.调整完毕以后再次长按原设置键即可跳出设置循环,显示部分――共阳极数码管显示正常走时的时间。
但是该程序在硬件的仿真过程中有点瑕疵。
在仿真开始时警示灯直接亮,必须通过闹钟定时键K2的闹钟设置以后时间才可以正常走时。
之后可以进行时间的调整或闹钟的重新调整。
1 概述 (3)1.1设计任务 (3)1.2设计要求 (3)1.3设计意义 (3)2 系统总体方案与硬件选择设计 (4)2.1系统总体方案 (4)2.2硬件选择设计 (4)3 软件设计 (9)3.1程序流程图 (9)3.2程序模块 (10)4 PROTEUS软件仿真 (17)5 课程设计体会 (19)参考文献 (19)附1:源程序代码 (21)附2:系统原理图 (33)1概述1.1 设计任务在熟练掌握单片机及其仿真系统的使用方法的基础上,综合应用单片机原理,微机原理,微机接口技术等专业知识,设计采用一个AT89C51单片机控制的定时闹钟。
摘要本设计是简单定时闹钟系统,不仅能实现系统要求的功能:(1)能显示时时-分分-秒秒,(2)能设定和修改定时时间,(3)定时时间到后能发出报警声;而且还有附加功能,即还能设定和修改当前所显示的时间。
本设计采用单片机AT89C51作为核心元件,12MHZ晶振,由P0口输出所要显示的字形段码,由P2口输出字位信号。
在其基础上扩展外围芯片与电路,附加时钟电路及LED电路。
LED采用共阴极接法,低电平有效选中相应的LED。
单片机具有集成度高、功能强、通用性好、特别是它能耗低、价格便宜、可靠性高、抗干扰能力强和使用方便等独特的优点,所以单片机现在广泛的应用到家用电器、机电产品、儿童玩具、机器人、办公自动化产品等领域。
为了进一步的熟悉并掌握单片机的应用及开发,认真的做好此次课程设计非常必要。
一个单片机的定时闹钟系统离不开软件和硬件,硬件是软件的依托,软件是硬件的内核。
设计硬件电路时应该先设计一个单片机的最小系统,它是单片机应用系统的设计基础,然后在此基础上添加外围器件,如显示器、按键等构成闹钟的硬件电路图。
在设计应用程序时遵循模块化的设计方法,在明确了设计方向之后按照分成的几大模块分别画出流程图,然后根据流程图写出程序,在每个模块编写好之后分别调试、修改、完善。
最后在主程序下调用再次调试、修改。
软硬件都设计好之后在Proteus环境下仿真,看它们是否配套,只有在Proteus下仿真没有出现问题才能说明设计的定时闹钟成功了。
本次设计严格按照上面的步骤,经过多次的修改、完善后终于可以在Proteus下很好的运行,设计成功。
通过这次设计让我更深入了解单片机基本电路、如何控制和定时器和中断编程的基本方法,从而锻炼了我学习、设计和开发软、硬件的能力。
目录1.概述 (4)1.1单片机简介 (4)1.2 本设计简介 (5)2.系统总体方案及硬件设计 (6)2.1本设计总体方案 (6)2.2单片机AT89C51简介 (6)2.3 数码管显示电路 (9)2.4 本设计输入输出电路 (11)3 软件设计 (13)3.1系统软件设计说明 (13)3.2 LED的编程思想 (13)3.3 程序调试 (13)3.4 程序流程图 (14)4 Proteus软件仿真 (16)4.1仿真步骤 (16)4.2 仿真过程中出现的错误及解决措施 (16)4.3仿真结果 (16)(1)设定当前时间 (17)(2)设定定时时间 (18)5 课程设计体会 (23)参考文献 (24)附1:源程序代码 (25)附2:系统原理图 (34)1.概述1.1单片机简介◆单片机基本概念单片机是一种特殊的计算机,它是在一块半导体上集成了CPU、存储器、以及输入输出接口电路,这种芯片被称为单片微型计算机,简称单片机。
实时电子闹钟功能:可以在液晶上显示时间星期日期,并按秒实时更新,具有闹钟设定及到时闹钟报警提示功能,闹钟响铃时按任意键可以取消响铃,拓展了四个按键,用于功能选择,数值增大或减小及闹钟查看,每次按键均会有短“滴”声,断电时间不停,再次上电仍将准确显示在液晶上照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟实时电子闹钟程序#include <reg52.h>#define uchar unsigned char#define uint unsigned int//按键sbit s1=P3^4; //设置sbit s2=P3^5; //减sbit s3=P3^6; //增sbit s4=P3^7; //闹钟sbit beep=P2^4; //蜂鸣器//1602位声明(实验板)sbit rs1602=P2^5;sbit rw1602=P2^6;sbit en1602=P2^7;/*uchar code table0[9]={"2010-4-13"};uchar code table1[8]={"11:03:05"};*///定义全局变量uchar shi,fen,miao,nian,yue,ri,week,s1num,num,flag,flag_di,flag1,amiao,afen,ashi;//延时x*1msvoid delay(uint x){uint a,b;for(a=0;a<x;a++)for(b=0;b<63;b++);}//转换函数uchar Convert(uchar In_Date){uchar i,Out_Date=0,temp=0;for(i=0;i<8;i++){temp=(In_Date>>i)&0x01;Out_Date|=(temp<<(7-i));}return Out_Date;}//1602写操作//写指令void write1602com(uchar com){rs1602=0;rw1602=0;en1602=0;P0=0xff;P0=Convert(com);delay(2);en1602=1;delay(2);en1602=0;delay(2);rs1602=1;}//写数据void write1602data(uchar adata) {rs1602=1;rw1602=0;en1602=0;P0=0xff;P0=Convert(adata);delay(2);en1602=1;delay(2);en1602=0;delay(2);rs1602=0;}//1602初始化设置void init_1602(){rs1602=0;rw1602=0;en1602=0;write1602com(0x38);write1602com(0x0c);write1602com(0x06);write1602com(0x01);write1602com(0x80);//外部中断EA=1;EX0=1;IT0=1;//闹钟标志位flag1=0;flag=0;flag_di=1;s1num=0;}//在1602中显示时分秒void lcd_sfm(uchar add,uchar adata){uchar shiwei,gewei;shiwei=adata/10;gewei=adata%10;write1602com(0x80+0x40+add); //在高位停留// delay(10);write1602data(shiwei+0x30);write1602data(gewei+0x30);}//在1602中显示年月日void lcd_nyr(uchar add,uchar adata){uchar shiwei,gewei;shiwei=adata/10;gewei=adata%10;write1602com(0x80+add); //在高位停留// delay(10);write1602data(shiwei+0x30);write1602data(gewei+0x30);}//1602时钟横杠等字符的显示void lcd1602showsign(){lcd_nyr(0,20);write1602com(0x80+4);write1602data('-');write1602com(0x80+7);write1602data('-');write1602com(0x80+0x40+2);write1602data(':');write1602com(0x80+0x40+5);write1602data(':');}//DS12887部分程序//位申明sbit ds12887_ds=P2^3;sbit ds12887_rw=P2^2;sbit ds12887_as=P2^1;sbit ds12887_cs=P2^0;sbit ds12887_irq=P3^2;//ds12887写数据及指令操作void ds12887_write(uchar add,uchar adata) {ds12887_as=0;ds12887_ds=1;ds12887_rw=1;ds12887_cs=0;ds12887_as=1;P1=add;ds12887_as=0;ds12887_rw=0;P1=adata;ds12887_rw=1;ds12887_as=1;}//ds12887读数据操作uchar ds12887_read(uchar add){uchar k;ds12887_ds=1;ds12887_rw=1;ds12887_as=1;ds12887_cs=0;P1=add;ds12887_as=0;ds12887_ds=0;P1=0xff;k=P1;ds12887_ds=1;ds12887_cs=1;ds12887_as=1;return k;}//设置ds12887初始时间void set_time(){ds12887_write(0x00,50); //secondds12887_write(0x02,59); //minuteds12887_write(0x04,23); //hourds12887_write(0x06,3); //dayds12887_write(0x07,16); //dateds12887_write(0x08,4); //monthds12887_write(0x09,10); //year}//闹钟滴滴响声void didi(){beep=0;delay(100);beep=1;delay(100);beep=0;delay(100);beep=1;}//ds12887初始化void init_ds12887(){ds12887_write(0x0a,0x20);ds12887_write(0x0B,0x26);//SET置1还是置0??set_time();}//闹钟设定void set_alarm(uchar hour,uchar minute,uchar second) {ds12887_write(1,second);ds12887_write(3,minute);ds12887_write(5,hour);}//读取闹钟数据void read_alarm(){amiao=ds12887_read(1);afen=ds12887_read(3);ashi=ds12887_read(5);}//显示星期void show_week(){switch(week){case 1:write1602com(0x80+11);write1602data('M');write1602data('O');write1602data('N');break;case 2:write1602com(0x80+11);write1602data('T');write1602data('U');write1602data('S');break;case 3:write1602com(0x80+11);write1602data('W');write1602data('E');write1602data('N');break;case 4:write1602com(0x80+11);write1602data('T');write1602data('H');write1602data('U');break;case 5:write1602com(0x80+11);write1602data('F');write1602data('R');write1602data('I');break;case 6:write1602com(0x80+11);write1602data('S');write1602data('A');write1602data('T');break;case 7:write1602com(0x80+11);write1602data('S');write1602data('U');write1602data('N');break;}}//清除设置星期时的数字型显示void clearnumofweek(){write1602com(0x80+14);write1602data(' ');write1602data(' ');}//按键扫描void keyscan(){if(flag_di==0){if((s1==0)||(s2==0)||(s3==0)||(s4==0)) {delay(5);if((s1==0)||(s2==0)||(s3==0)||(s4==0)) {while(!(s1&&s2&&s3&&s4));didi();flag_di=1;}}// flag_di=1;}if(s1==0){delay(10);if(s1==0){s1num++;if(flag1==1){if(s1num==4){s1num=1;// write1602com(0x80+0x40+7);// write1602com(0x0f);}}// s1num++;flag=1;while(!s1);beep=0;delay(50);beep=1;switch(s1num){case 1:write1602com(0x80+0x40+7);write1602com(0x0f);break;case 2:write1602com(0x80+0x40+4);write1602com(0x0f);break;case 3:write1602com(0x80+0x40+1);write1602com(0x0f);break;case 4:write1602com(0x80+15);write1602com(0x0f);break;case 5:write1602com(0x80+9);write1602com(0x0f);break;case 6:write1602com(0x80+6);write1602com(0x0f);break;case 7:write1602com(0x80+3);write1602com(0x0f);break;case 8:ds12887_write(0x00,miao); //secondds12887_write(0x02,fen); //minuteds12887_write(0x04,shi); //hourds12887_write(0x06,week); //dayds12887_write(0x07,ri); //dateds12887_write(0x08,yue); //monthds12887_write(0x09,nian); //year// delay(100);flag=0;s1num=0;break;}}if(s1num!=0){if(s2==0){delay(5);if(s2==0){while(!s2);beep=0;delay(50);beep=1;switch(s1num){case 1:miao++;if(miao==60)miao=0;lcd_sfm(6,miao);write1602com(0 x80+0x40+7);break;case 2:fen++;if(fen==60)fen=0;lcd_sfm(3,fen);write1602com(0 x80+0x40+4);break;case 3:shi++;if(shi==24)shi=0;lcd_sfm(0,shi);write1602com(0 x80+0x40+1);break;case 4:week++;if(week==8)week=1;lcd_nyr(14,week);write1602com(0 x80+15);break;case 5:ri++;if(ri==32)ri=1;lcd_nyr(8,ri);write1602com(0break;case 6:yue++;if(yue==13)yue=1;lcd_nyr(5,yue);write1602com(0 x80+6);break;case 7:nian++;if(nian==100)nian=0;lcd_nyr(2,nian);write1602com(0 x80+3);break;}}}if(s3==0){delay(5);if(s3==0){while(!s3);beep=0;delay(50);beep=1;switch(s1num){case 1:miao--;if(miao==-1)miao=59;lcd_sfm(6,miao);write1602com(0 x80+0x40+7);break;case 2:fen--;if(fen==-1)fen=59;lcd_sfm(3,fen);write1602com(0 x80+0x40+4);break;case 3:shi--;if(shi==-1)shi=23;lcd_sfm(0,shi);write1602com(0 x80+0x40+1);break;case 4:week--;if(week==0)week=7;lcd_nyr(14,week);write1602com(0 x80+15);break;case 5:ri--;if(ri==0)ri=31;lcd_nyr(8,ri);write1602com(0 x80+9);break;case 6:yue--;if(yue==0)yue=12;lcd_nyr(5,yue);write1602com(0 x80+6);break;case 7:nian--;if(nian==-1)nian=99;lcd_nyr(2,nian);write1602com(0 x80+3);break;}}}if(s4==0){delay(5);if(s4==0){// while(!s4);beep=0;delay(50);beep=1;num++;while(!s4);beep=0;delay(50);beep=1;// flag1=1;// flag1=~flag1;if(num==1)// if(flag1==1) //设置闹钟{flag1=1;write1602com(0x80+0x40+7);write1602com(0x0f);read_alarm();miao=amiao;fen=afen;shi=ashi;write1602com(0x80+0x40+9);write1602data('D');write1602data('i');// write1602com(0x80+0x40+7);// write1602com(0x0f);lcd_sfm(0,ashi);lcd_sfm(3,afen);lcd_sfm(6,amiao);}// else //退出闹钟设置,并把设置的时间输入进DS12C887中if(num==2){// delay(50);num=0;s1num=0;write1602com(0x80+0x40+9);write1602data(' ');write1602data(' ');// write1602com(0x0c);// ds12887_write(1,miao);// ds12887_write(3,fen);// ds12887_write(5,shi);set_alarm(shi,fen,miao);flag1=0;flag=0;}}}}}void main(){/*uchar i;init_1602();for(i=0;i<9;i++){write1602data(table0[i]);delay(5);}delay(10);write1602com(0x80+0x40);for(i=0;i<8;i++){write1602data(table1[i]);delay(5);}while(1);*/init_1602();lcd1602showsign();init_ds12887();while(1){keyscan();if(flag_di==0){// delay(100);didi();// delay(200);// flag_di=1;}// delay(10);if((flag==0)&&(flag1==0)){keyscan();// delay(10);shi=ds12887_read(0x04);fen=ds12887_read(0x02);miao=ds12887_read(0x00);nian=ds12887_read(0x09);yue =ds12887_read(0x08);ri =ds12887_read(0x07);week=ds12887_read(0x06);lcd_sfm(0,shi);lcd_sfm(3,fen);lcd_sfm(6,miao);lcd_nyr(2,nian);lcd_nyr(5,yue);lcd_nyr(8,ri);// lcd_nyr(14,week);show_week();clearnumofweek();}}}void exter0() interrupt 0{uchar c;flag_di=0;c=ds12887_read(0x0c);}。
单片机闹钟程序设计这个是在之前的电子时钟上功能的扩展,主要加入闹钟模块。
即到达预定时间响铃一分钟,一分钟后自动停止,也可以按下已设定的键实现手动停止。
数码管方面的学习就到此为此吧,下一步是对液晶显示的学习。
单片机闹钟程序设计如下:#i nclude;#define uchar unsigned charunsigned char codetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//数码管数字编码uchari,j,k,second,tcount,minute,hour,tminute,thour,rin g;sbit beep=P2^6;sbitS2=P3^4;//---------------------------------------------------延时子程序,大约延时 n MSdelay(uchar n){for(j=n;j>;0;j--)for(k=125;k>;0;k--);}//---------------------------------------------------中断子程序void timer0() interrupt 1 using 0{TH0=(65536-50000)/256;//中断设置初始化TL0=(65536-50000)%256;tcount++;if(tcount==20)//满1秒{tcount=0;second++;beep=0;//秒数加1 if(second==60)//满1分{second=0;minute++;//分数加1,秒数归零if(minute==60)//满1小时{minute=0;hour++;//小时数加1,分数归零if(hour==24){hour=0;}}} }}void timer1() interrupt 3 using 1{TH1=0x3c; //中断设置初始化TL1=0xb0;if(minute==tminute & hour==thour & ring==1) {beep=0;}//到预设时间自动响铃,持续一分钟后自己关闭if(S2==0){ring=0;//铃声中断}}//---------------------------------------------------void main(){tminute=1;thour=0;//预置响铃时间second=55;minute=0;hour=0;//给电子时钟赋初值,即启动时显示的时间ring=1; //启动响铃功能TH0=(65536-50000)/256;//中断设置初始化TL0=(65536-50000)%256;EA=1;ET0=1;TMOD=0x21;TR0=1;//开中断总开关,计数器0允许中断,设置中断模式,启动计数器0ET1=1;TR1=1;while(1)//死循环,进入显示,主要是动态显示原理{ P0=table[(second%10)]; P2=0xdf; delay(5);P0=table[(second/10)]; P2=0xef; delay(5);P0=table[(minute%10)]; P2=0xf7; delay(5);P0=table[(minute/10)]; P2=0xfb; delay(5);P0=table[(hour%10)]; P2=0xfd; delay(5);P0=table[(hour/10)]; P2=0xfe; delay(5); }}。
设计总说明这次课程设计的任务是是利用MCS51系列单片外加必要的辅助电路从而设计一个带有LCD显示的定时闹钟。
该闹钟应具有的功能是:当定时闹钟到了人为设定好的时间后,它就发出声音,并且在LCD显示器上显示出你所设定的闹钟时间以及当前时间,并能够随时调整时间。
本课设所用器件有:AT89C52单片机、LCD显示器(LM016L)、上拉电阻(Respack-8)、晶振电路、复位电路(带有复位键)以及四个控制键。
1、在控制时分电路设计中,分别设置了四个键:K1键-用来设置当前时间以及在设置中用来设置时钟K2键-显示闹钟时间以及在设置中用来设置分钟K3键-设置闹钟时间K4键-控制闹铃的开关2、在控制时分秒电路的设计中,分别设置了五个键,即在1的基础上增加了一个控制秒的按键。
当然本课程设计中所用到的元器件还可以应用其他的一些器件。
比如AT89C52完全可以用AT89C51来代替,LM016L型号的LCD显示器可以用LM017L 型号的LCD显示器来代替(其他一些显示器也可以用),上来电阻也可以用分电阻来表示。
初次做课程设计,肯定会有许多不足之处,希望老师们指点!关键字: AT89C52单片机 LCD显示器闹钟目录1、主要内容 (3)2、目的和意义 (3)3、基本要求 (3)、显示时-分功能 (3)、显示时-分-秒功能 (3)4、系统设计AT89C52单片机简介 (4)电路总体设计 (6)主程序流程图 (7)5、详细设计设计电路图 (7)程序代码 (12)5.2.1 时-分程序代码 (12)5.2.2 时-分-秒程序代码 (23)6、结论结果分析 (33)心得体会 (33)7、设计总结 (34)8、参考文献 (34)1、主要内容:本次课程设计的内容为设计一个以MCS51单片机为核心的带有LCD显示的定时闹钟,完成原理图设计,软件编制及设计报告。
设使用AT89C52单片机结合字符型LCD显示器设计一个简易的定时闹钟LCD时钟,若LCD 选择有背光显示的模块,在夜晚或黑暗的场合中也可以使用。
姚辉虎的毕业设计--基于单片机的智能数字闹钟程序代码程序代码main.c#include <reg51.h>#include <intrins.h>#include <yf.h>unsigned char clock_data[4]。
sbit speaker = P2^4。
// 蜂鸣器sbit bell = P2^2。
//铃响bit bell_on=0。
bit key_ok=0。
unsigned char bell_time=0x20。
uchar week_clock_set。
#define FIRST_ADDR 0//定义全局变量unsigned char yy,mo,dd,xq,hh,mm,ss。
// 定义时间映射全局变量<专用寄存器)uchar j。
/****************************************************************************///函数声明extern unsigned char read_clock(unsigned char ord>。
extern void lcdwc(unsigned char cmdcode>。
extern void hzkdis(unsigned char code *s>。
extern void hzkdis2(unsigned char *s>。
extern char Read_One_Byte(unsigned char addr>。
extern void Write_One_Byte(unsigned char addr,unsigned char thedata>。
void lcm_w_ss(void>。
extern void lcdreset(void>。
extern void Init_DS18B20(void>。
#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define LED P0 // 数码管的段选#define LIGHT P1 // 时分秒位的指示灯#define WS P2 // 数码管的位选sbit key1=P3^0; // 时间暂停/开始sbit key2=P3^1; // 时间/闹钟设置sbit key3=P3^2; // 增加sbit key4=P3^3; // 减少sbit alarm=P3^6; // 闹铃uchar tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 0-9uchar tab_dp[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; // 0.-9.(带小数点)uchar data1[]={0,0,0,0,0,0};uchar data2[]={0,0,0,0,0,0};uint t,k,kk,k1,flag;uint bbh,bbm,bbs,bbh1,bbm1,bbs1;uint sec,min,hour,sec1,min1,hour1; // 定义秒,分,时void init();void display();void display_bb();void delay( uint );void keyscan();void main(){init();while(1){keyscan();if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if((bbh==hour)&&(bbm==min)&&data1[4]==0&&data1[5]==5) // 5s报时{alarm=~alarm;delay(1);}if((bbs==sec)&&(bbm==min)&&(bbh==hour)) // 可调报时{alarm=~alarm;delay(1);}}}void init(){WS=LIGHT=flag=0;sec=min=hour=0; // 将0赋给时分秒TMOD=0x01; // 方式1 P129(见课本)TH0=0x3c; // 65536-50000=15536=0x3cb0(50ms) P128(见课本)TL0=0xb0;EA=1; // 开总中断P161(见课本)TR0=1; // 定时/计数器0开启ET0=1; // 定时器/计数器0溢出中断启动P161(见课本)}void delay( unsigned int t) // 延时函数{unsigned int i;while(t--)for(i=0;i<125;i++);}void display() // 显示时间函数{if(TF0==1) // 定时器/计数器溢出P130(见课本){TF0=0; // 清中断标志位t++;if(t==20) // (50ms*20=1s){t=0;sec++; // 秒加1if(sec==60) // 秒为60,则清零,分加1{sec=0;min++;}if(min==60) // 分为60,则清零,时加1{min=0;hour++;}if(hour==24)// 时为24,则清零{hour=0;}}}data1[5]=sec%10;data1[4]=sec/10;data1[3]=min%10;data1[2]=min/10;data1[1]=hour%10;data1[0]=hour/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data1[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data1[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data1[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data1[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data1[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data1[0]];delay(1);}void display_bb() // 显示闹钟函数{data2[5]=bbs%10;data2[4]=bbs/10;data2[3]=bbm%10;data2[2]=bbm/10;data2[1]=bbh%10;data2[0]=bbh/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data2[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data2[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data2[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data2[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data2[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data2[0]];delay(1);}void keyscan() // 键盘扫描{if(key1==0) // 暂停/开始{++kk;while(!key1){display();if(kk==1){TR0=0;if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if(key2==0) // 模式选择(调节时间/闹钟){k1++;while(!key2){if(k1==1) // 第1次按下{sec1=sec; // 保存秒的数值sec=88; // 显示88,表示可以调节秒的数值了display(); // 显示88sec=sec1; // 恢复前一刻秒的数值}if(k1==2){min1=min;min=88;display();delay(1);min=min1;}if(k1==3){hour1=hour;hour=88;delay(1);hour=hour1;}if(k1==4){sec1=bbs; // 保存秒的数值bbs=66; // 显示66,表示可以调节秒的数值了display_bb(); // 显示66bbs=sec1; // 恢复前一刻秒的数值}if(k1==5){min1=bbm;bbm=66;display_bb();delay(10);bbm=min1;}if(k1==6){hour1=bbh;bbh=66;display_bb();delay(10);bbh=hour1;}if(k1==7){k1=0;display();}}}if(key3==0) // 时间/闹钟增加设置{while(!key3){if(k1==1){sec++;// 秒加1if(sec==60)sec=0;display();}if(k1==2){min++;delay(60);if(min==60)min=0;display();}if(k1==3){hour++;delay(60);if(hour==24)hour=0;display();}if(k1==4){bbs++; // 秒加1delay(60);if(bbs==60)bbs=0;display_bb();}if(k1==5){bbm++;delay(60);if(bbm==60)bbm=0;display_bb();}if(k1==6){bbh++;delay(60);if(bbh==24)bbh=0;display_bb();if(k1==7){k1=0;display();}}}if(key4==0) // 时间/闹钟减少设置{while(!key4){if(k1==1){sec--; // 秒加1delay(60);if(sec==0)sec=60;display();}if(k1==2){min--;delay(60);if(min==0)min=60;display();}if(k1==3){hour--;delay(60);if(hour==0)hour=24;display();}if(k1==4){bbs--; // 秒减1delay(60);if(bbs==0)bbs=60;display_bb();if(k1==5){bbm--;delay(60);if(bbm==0)bbm=60;display_bb();}if(k1==6){bbh--;delay(60);if(bbh==0)bbh=24;display_bb();}if(k1==7){k1=0;display();}}}}}if(kk==2){kk=0;k1=0;TR0=1;}}}。
#include<reg52.h>#define uint unsigned int#define uchar unsigned charuintmiao,fen,fen1,shi,shi1,flag1,flag2,flag3,aa,K1num,K2num,K3num,K4num,N;//K1num-K1按键被按下的标记变量,K2num-K2按键被按下的标记变量,K3num=0-K3按键被按下的标记变量uchar code table[]=" TIMING CLOCK"; //定义初始上电时液晶默认显示状态sbit K1=P1^0; //四个按键sbit K2=P1^1;sbit K3=P1^2;sbit K4=P1^3;sbit rs=P2^6;sbit lcden=P2^7;sbit led=P2^3; //发光二极管控制端sbit beep=P1^5; //蜂鸣器控制端sbit relay=P2^5; //继电器控制端void delay(uint z) //延时函数{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com) //液晶写命令函数{rs=0;lcden=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_date(uchar date) //液晶写数据函数{rs=1;lcden=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void write_sfm(uchar add,uchar date) //液晶写时分秒函数{uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}void init() //初始化函数{uint num; //写液晶的循环控制变量aa=0; //中断次数标志K1num=0; //K1按键被按下的标记变量K2num=0; //K2按键被按下的标记变量K3num=0; //K3按键被按下的标记变量K4num=0;flag1=1; //控制lcd屏刷新的变量flag2=1; //控制闹钟响闹和继电器开启关闭的标记flag3=1; //控制闹钟响起时,按下K4停止闹钟响闹的标记led=1; //发光二极管初始化relay=0; //继电器初始化N=100; //系统启动时,闹钟时间到发出的声音为连续三次发出“哗”的一声miao=0; //系统初始化时间fen=0;shi=0;fen1=1; //初始化闹钟的时间shi1=0;beep=0; //蜂鸣器初始化lcden=0; //液晶使能端初始化//1602液晶初始化,设置16*2显示。
ORG 0000HLJMP MAINORG 000BHLJMP TIME;×××××主程序部分:×××××ORG 0100HMAIN:MOV SP,#50HMOV 20H,#00H ;秒钟BINMOV 21H,#00H ;分钟BINMOV 22H,#00H ;小时BINMOV 23H,#01HMOV 24H,#01HMOV 25H,#00HMOV 30H,#00HMOV 31H,#00HMOV 32H,#00HMOV 33H,#00HMOV 34H,#00HMOV 35H,#00HMOV 36H,#01HMOV 37H,#00HMOV 38H,#01HMOV 39H,#00HMOV TMOD,#01H ;16位计数器MOV TH0,#03CH ;赋计数初值MOV TL0,#0B0HMOV IE,#10000111BSETB TR0 ;T0启动计数MOV R2,#14HMOV P2,#0FFHLOOP: LCALL TIMEPROLCALL DISPLAY1JB P1.1,M1LCALL SETTIME ;调用设定时间程序LJMP LOOPM1:JB P1.2,M2LCALL SETA TIME ;调用设定时间程序LJMP LOOPM2:JB P1.4,M4LCALL LOOKATIME ;调用设定闹钟时间程序M4:LJMP LOOPDELAY:MOV R4,#030H ;延时时间DL00:MOV R5,#0FFHDL11:MOV R6,#9HDL12:DJNZ R6,DL12DJNZ R5,DL11DJNZ R4,DL00RET;×××××设定时间程序:×××××SETTIME:L0:LCALL DISPLAY1 ;调用时间允许程序MM1: JB P1.2,L1MOV C,P1.2JC MM1LCALL DELAY1 ;调用延时JC MM1MSTOP1: MOV C,P1.2JNC MSTOP1 ;判断P1.2是否释放?释放则继续LCALL DELAY1 ;调用延时MOV C,P1.2JNC MSTOP1INC 22H ;小时增加1MOV A,22HCJNE A,#18H,GO12 ;判断小时是否到24时?未到继续循环MOV 22H,#00H ;小时复位MOV 34H,#00HMOV 35H,#00HLJMP L0L1:JB P1.3,L2MOV C,P1.3JC L1LCALL DELAY1 ;延时JC L1MSTOP2: MOV C,P1.3JNC MSTOP2 ;判断P1.3是否释放?释放则继续LCALL DELAY1 ;调用延时MOV C,P1.3JNC MSTOP2INC 21H ;分钟增加一MOV A,21HCJNE A,#3CH,GO11MOV 21H,#00H ;分钟复位MOV 32H,#00HMOV 33H,#00HLJMP L0GO11:MOV B,#0AH ;将A中的内容分成高低两部分DIV ABMOV 32H,BMOV 33H,ALJMP L0GO12: MOV B,#0AHDIV ABMOV 34H,BMOV 35H,ALJMP L0L2:JB P1.4,L0MOV C,P1.4JC L2LCALL DELAY1 ;调用延时MOV C,P1.4JC L2STOP1: MOV C,P1.4 ;判断按键P1.4是否释放?JNC STOP1LCALL DELAY1 ;调用延时MOV C,P1.4JNC STOP1LJMP LOOP;×××××设置闹钟时间×××××SETATIME:LCALL DISPLAY2 ;调用时间运行N0:LCALL DISPLAY2MM2: JB P1.3,N1 ;判断P1.3是否按下?MOV C,P1.3JC MM2LCALL DELAY1JC MM2MSTOP3: MOV C,P1.3 ;判断P1.3是否释放?JNC MSTOP3LCALL DELAY1MOV C,P1.3JNC MSTOP3INC 24H ;设定小时增加1MOV A,24HCJNE A,#24,GO22MOV 24H,#00H ;时钟复位MOV 38H,#00HMOV 39H,#00HLJMP N0N1:JB P1.1,N2 ;判断P1.1是否按下?MOV C,P1.1JC N1LCALL DELAY1JC N1MSTOP4: MOV C,P1.1 ;判断P1.1是否释放?JNC MSTOP4LCALL DELAY1MOV C,P1.1JNC MSTOP4INC 23H ;设定闹钟分钟增加1MOV A,23HCJNE A,#60,GO21 ;判断A是否到60分?MOV 23H,#00H ;分钟复位MOV 36H,#00HMOV 37H,#00HLJMP N0GO21:MOV B,#0AH ;将A中的内容分成高低两部分DIV ABMOV 36H,BMOV 37H,ALJMP N0GO22: MOV B,#0AHDIV ABMOV 38H,BMOV 39H,ALJMP N0N2:JB P1.4 ,N0 ;判断P1.4是否按下?MOV C,P1.4JC N2LCALL DELAY1MOV C,P1.4JC N2STOP2: MOV C,P1.4 ;判断P1.4是否释放?JNC STOP2LCALL DELAY1MOV C,P1.4JNC STOP2LJMP LOOPTIMEPRO:MOV A,21HMOV B,23HCJNE A,B,BK ;判断分钟是否运行到设定的闹钟的分钟?MOV A,22HMOV B,24HCJNE A,B,BK ;判断时钟是否运行到设定的闹钟的时钟?SETB 25H.0MOV C,25H.0JC XXXX: LCALL TIMEOUT ;调用时间闹钟响应程序BK:RETTIMEOUT:X1:LCALL BZ ;调用喇叭响应程序LCALL DISPLAY2CLR 25H.0JB P1.4, X1 ;判断P1.4是否按下?LCALL DELAYCLR 25H.0LJMP DISPLAY1BZ: CLR P3.7 ;喇叭响应程序MOV R7,#250 ;响应延时时间T2: MOV R6,#124T3: DJNZ R6,T3DJNZ R7,T2SETB P3.7RETLOOKATIME:LCALL DISPLAY2 ;调用时间运行程序MM: JB P1.4,LOOKATIME ;判断按键P1.4是否按下MOV C,P1.4JC MMLCALL DELAY1MOV C,P1.4JC MMSTOP3: MOV C,P1.4JNC STOP3LCALL DELAY1MOV C,P1.4JNC STOP3LJMP LOOPDELAY1: MOV R4,#14H ;时间延时DL001: MOV R5,#0FFHDL111: DJNZ R5,DL111DJNZ R4,DL001RET;×××××时间运行程序×××××TIME: PUSH ACC ;现场保护PUSH PSWMOV TH0,#03CH ;赋初值MOV TL0,#0B0HDJNZ R2,RET0MOV R2,#14HMOV A,20HCLR CINC A ;秒钟自加1CJNE A,#3CH,GO1 ;判断秒钟是否到60秒?MOV 20H,#0 ;到60秒复位MOV 30H,#0MOV 31H,#0MOV A,21HINC A ;分钟自加1CJNE A,#3CH,GO2 ;判断分钟是否到60分?MOV 21H,#0H ;到60分复位MOV 32H,#0MOV 33H,#0MOV A,22HINC A ;时钟自加1CJNE A,#18H,GO3 ;判断时钟是否到24时?MOV 22H,#00H ;到24时复位MOV 34H,#0MOV 35H,#0AJMP RET0GO1: MOV 20H,AMOV B,#0AHDIV ABMOV 31H,AMOV 30H,BAJMP RET0GO2: MOV 21H,AMOV B,#0AHDIV ABMOV 33H,AMOV 32H,BAJMP RET0GO3: MOV 22H,AMOV B,#0AHDIV ABMOV 35H,AMOV 34H,BRET0: POP PSW ;恢复现场POP ACCRETI;×××××运行部分×××××DISPLAY1: MOV R0,#30HMOV R3,#0FEHMOV A,R3PLAY1: MOV P2,AMOV A,@R0MOV DPTR,#DSEG1 ;表首地址送DPTRMOVC A,@A+DPTRMOV P0,ALCALL DL1MOV P2,#0FFH ;送高电平到P2MOV A,R3RL A ;JNB ACC.6,LD1INC R0MOV R3,ALJMP PLAY1 ;调用查表程序LD1: RETDISPLAY2: PUSH ACC ;现场保护PUSH PSWMOV R0,#36HMOV R3,#0FBHMOV A,R3PLAY2: MOV P2,AMOV A,@R0MOV DPTR,#DSEG1 ;表首地址送DPTRMOVC A,@A+DPTR ;查ASCII特码MOV P0,A ;查表结果送ALCALL DL1MOV P2,#0FFH ;送高电平到P2MOV A,R3RL AJNB ACC.6,LD2INC R0LJMP PLAY2LD2: POP PSW ;恢复现场POP ACCRET;×××××延时时间×××××DL1: MOV R7,#02H ;延时时间DL: MOV R6,#0200HDL6: DJNZ R6,$DJNZ R7,DLRETDSEG1:DB 3FH,06H,5BH,4FH,66HDB 6DH,7DH,07H,7FH,6FHEND。
#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit w1=P0^0;sbit w2=P0^1;sbit w3=P0^2;sbit w4=P0^3;sbit k1=P0^4;//定义按键sbit k2=P0^5;sbit k3=P0^6;sbit k4=P0^7;sbit fm=P3^4;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0--9十六进制数共阴void timetune();//时间校正函数void delayms(uint);//延迟函数void keyscan();//闹钟设置函数void keyscan1();//闹钟检测函数void display(uint anum,uint anum1,uint anum2,uint anum3);//显示函数uintnum0,num,num1,num2,num3,anum,anum1,anum2,anum3,temp,temp0,temp1, temp2,temp3,temp4,s,s1,s2,s3,s4;void main(){TMOD=0x01;//设置定时器0为工作方式1(0000 0001)TH0=(65536-45872)/256;//装初值50毫秒中断一次TL0=(65536-45872)/256;EA=1;//开总中断ET0=1;//开定时器0终中断TR0=1;//开定时器while(1)//中断后进入死循环时间永不停止计时{timetune();//调用时间设置函数keyscan();//调用闹钟设置函数if(num0==20){num0=0;num++;if(num==10){num1++;num=0;if(num1==6){num2++;num1=0;if(num2==10)//和下面if必须分开,否则时间到24小时后不会清0继续走下去{num3++;num2=0;}}}}if(num3==2&&num2==4)//当时间走到24小时后自动清0{num3=0;num2=0;num=0;num1=0;}if(temp0==1)//为了防止闹钟时间显示和正常时间显示同时显示出现数码管显示不清晰,所以display(s1,s2,s3,s4);//写两个对立的if条件判断语句(temp==1和temp!=1)来作为限制条件.if(temp0!=1)display(num,num1,num2,num3);//keyscan1();}}void display(uint anum,uint anum1,uint anum2,uint anum3)//时间显示函数{P2=table[anum3];w1=1;delayms(1);w1=0;P2=table[anum2];w2=1;delayms(1);w2=0;P2=table[anum1];w3=1;delayms(1);w3=0;P2=table[anum];w4=1;delayms(1);w4=0;}void timetune()//时间校正程序{if(k4==0){//当每按下第四个键后会出现temp不同的值,然后用delayms(10);//不同的值作为不同的条件给四个数码管加减值来校正时间if(k4==0){temp++;while(!k4);}}if(temp==1){if(k2==0){delayms(10);//按键时由于会产生机械振动,为了准确检测到按键if(k2==0)//按下所以要延时{num++;if(num==10)num=0;while(!k2);}}}if(temp==2) {if(k2==0) {delayms(10); if(k2==0) {num1++;if(num1==6) num1=0; while(!k2); }}}if(temp==3) {if(k2==0) {delayms(10); if(k2==0) {num2++;if(num2==10) num2=0; while(!k2); }}}if(temp==4) {if(k2==0) {delayms(10); if(k2==0) {num3++;if(num3==3) num3=0; while(!k2); }以}}}if(num3==2&&num2>=4)//前面由于num2可以加到十,但是num2最多只能是4,所{//当num3加到2时,num2只能最大为4,大于4后要清0num2=0;}if(temp==5){}temp=0;//为了让时间能够反复校正,temp要清0void keyscan1()//闹钟判断程序{if(s1==num&&s2==num1&&s3==num2&&s4==num3&&temp0==2)//闹钟判断条件{temp0=0;//当闹钟判断条件成立后,第一次闹钟响了后,为了能够进行第二次闹钟的设置,所以temp0要清0fm=0;//蜂鸣器}}void keyscan()//闹钟调整程序{if(k3==0){delayms(10);if(k3==0){temp0++;while(!k3);//按键释放}}if(k1==0){delayms(10);if(k1==0){s++;while(!k1);}}if(s==1){if(k2==0){delayms(10);if(k2==0){s1++;if(s1==10)s1=0;while(!k2); }}}if(s==2) {if(k2==0) {delayms(10); if(k2==0) {s2++;if(s2==6)s2=0;while(!k2); }}}if(s==3) {if(k2==0) {delayms(10); if(k2==0) {s3++; }}}if(s3==10) s3=0;while(!k2); if(s==4) {if(k2==0) {delayms(10); if(k2==0) {s4++;if(s4==3)s4=0;while(!k2);}}}if(s4>=3&&s3>=5)//同时间调整程序一样{s3=0;}if(s==5){s=0;}}void delayms(uint xms){uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);}void T0_time() interrupt 1//中断服务程序{EA=0;TH0=(65536-45872)/256; TL0=(65536-45872)/256; }num0++;EA=1;。