单片机LCD定时闹钟程序
- 格式:docx
- 大小:17.62 KB
- 文档页数:6
单片机电子闹钟程序(亲自编写-可用)————————————————————————————————作者:————————————————————————————————日期:学校电子钟,有闹钟功能,按键可调时间,可调打铃时间,打铃时间长短显示,每个模块有功能注释。
其中正常时间显示和闹钟时间显示可用一个开关来调整。
芯片选择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();}}电路图:分四部分显示:如果在学习这个程序过程中有什么问题,可以发邮件到询问。
#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar code table[]=" 2012-08-17 MON"; //设定开始显示的时间uchar code table1[]=" 12:30:00";uchar code table2[7][3]= {{"MON"},{"TUE"},{"WED"},{"THU"},{"FRI"},{"SAT"},{"SUN"}};//定义二维字符数组sbit wr=P3^6; // 1602液晶的读/写端sbit dula=P2^6; // 数码管段选sbit wela=P2^7; // 数码管位选sbit lcden=P3^4; // 1602液晶使能端sbit lcdrs=P3^5; // 1602液晶命令/数据端sbit key1=P3^0; // 声明s4按键sbit key2=P3^1; // 声明s8按键sbit key3=P3^2; // 声明s12按键sbit key4=P3^3; // 声明s16按键sbit beep=P2^3; // 声明蜂鸣器sbit rd=P3^7; // 声明4个按键的公共端uchar num1,shi=12,fen=30,miao,yue=8,ri=17,shi1,fen1,miao1,keynum1,week; //定义时分秒变量uint nian=2012; //定义年变量void delayms(uint x){uint i,j;for(i=x;i>0;i--) //定义带参数延时函数for(j=110;j>0;j--);}void write_com(uchar com) //1602液晶写指令函数{ wr=0;lcdrs=0;P0=com;delayms(1);lcden=1;delayms(1);lcden=0;}void write_date(uchar date) //1602液晶写数据函数{ wr=0;lcdrs=1;P0=date;delayms(1);lcden=1;delayms(1);lcden=0;}void write_addate1(uchar add,uint date) //定义显示年的函数{ uint qian;uchar bai,shi,ge;qian=date/1000;bai=date%1000/100;shi=date%1000%100/10;ge=date%10;write_com(add+0x80);write_date(0x30+qian);write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge);}void write_addate2(uchar add,uchar date) //定义显示月、日、时、分、秒函数{uchar shi,ge;shi=date/10;ge=date%10;write_com(add+0x80);write_date(0x30+shi);write_date(0x30+ge);}void write_rq(uchar i) //定义显示星期的函数{ uchar x;for(x=0;x<3;x++){ write_date(table2[i][x]);delayms(1);}}void init () //定义初始化函数{dula=0; // 关闭数码管段、位选端wela=0;TMOD=0x01; // 定时器0工作方式为16位TH0=(65536-45872)/256; // 装初值TL0=(65536-45872)%256;EA=1; // 开总中断ET0=1; // 开定时器0中断write_com(0x38); // 设置16*2显示,5*7点阵,8位数据口write_com(0x06); // 写一个字符后地址指针加1write_com(0x0c); // 设置开显示,不显示光标write_com(0x01); // 显示清0,数据清0write_com(0x80); // 使指针指向第1行第1列}void keyscan() // 定义按键函数{uchar keynum;rd=0; //4个按键公共端为低电平if(key1==0) //s4按键被按下{ delayms(3); //去抖延时if(key1==0) //确认s4按键被按下,进入调时间模式{keynum++;while(!key1); //松手检测}if(keynum==1) //s4按下一次{ TR0=0; //关闭定时器0write_com(0x81); //指针指向第1行2列write_com(0x0f); //开启光标显示,光标闪烁}if(keynum==2){write_com(0x86); //光标跳到月份}if(keynum==3){write_com(0x89); //光标跳到日}if(keynum==4){write_com(0x8c); //光标跳到星期}if(keynum==5){write_com(0xc4); //光标跳到时}if(keynum==6){write_com(0xc7); //光标跳到分}if(keynum==7){write_com(0xca); //光标跳到秒}if(keynum==8){ keynum=0; //退出调时间模式TR0=1; //开启定时器0write_com(0x0c); //关闭光标显示}}if(keynum) //当进入调时间模式时{if(key2==0) //s8按键按下{delayms(3); //去抖延时if(key2==0){if(keynum==1){nian++; //s8每按下一次年份加1if(nian==10000) // 加满清0nian=0;write_addate1(1,nian); // 显示年份write_com(0x81); //写完数据指针指向年份原来位置}if(keynum==2){yue++; //s8每按下一次月份加1if(yue==13)yue=0; //加满清0write_addate2(6,yue); //显示月份write_com(0x86); //写完数据指针指向月份原来位置}if(keynum==3){ ri++;if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12) //1,3,5,7,8,10,12月有31天if(ri==32)//加满还原ri=1;if(yue==4||yue==6||yue==9||yue==11) //4,6,9,11月有30天if(ri==31)ri=1;if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0)) //闰年2月有30天if(ri==30)ri=1;if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0)) //非闰年2月有31天if(ri==29)ri=1;write_addate2(9,ri); //显示日write_com(0x89); //写完数据指针指向日原来位置}if(keynum==4){week++;//s8每按下一次星期加1if(week==7)//加满还原week=0;write_rq(week); //显示星期write_com(0x8c); //写完数据指针指向星期原来位置}if(keynum==5){shi++;//s8每按下一次时加1if(shi==24)shi=0;//加满还原write_addate2(0x44,shi); //显示时write_com(0xc4); //写完数据指针指向时原来位置}if(keynum==6){fen++;//s8每按下一次分加1if(fen==60)fen=0;//加满还原write_addate2(0x47,fen); //显示分write_com(0xc7);//写完数据指针指向分原来位置}if(keynum==7){miao++;//s8每按下一次秒加1if(miao==60)miao=0;//加满还原write_addate2(0x4a,miao);//显示秒write_com(0xca);//写完数据指针指向秒原来位置}while(!key2); //松手检测}}if(key3==0){delayms(3);if(key3==0){ //s12按下时减1if(keynum==1){nian--;if(nian==-1)nian=9999;write_addate1(1,nian);write_com(0x81);}if(keynum==2){ yue--;if(yue==-1)yue=12;write_addate2(6,yue);write_com(0x86);}if(keynum==3){ri--;if(ri==0){if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)ri=31;if(yue==4||yue==6||yue==9||yue==11)ri=30;if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0))ri=29;if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0))ri=28;}write_addate2(9,ri);write_com(0x89);}if(keynum==4){week--;if(week==-1)week=6;write_rq(week);write_com(0x8c);}if(keynum==5){shi--;if(shi==-1)shi=23;write_addate2(0x44,shi);write_com(0xc4);}if(keynum==6){fen--;if(fen==-1)fen=59;write_addate2(0x47,fen);write_com(0xc7);}if(keynum==7){miao--;if(miao==-1)miao=59;write_addate2(0x4a,miao);write_com(0xca);}while(!key3); //松手检测}}}if(key4==0) //s16被按下进入调闹钟模式{ delayms(3);if(key4==0){keynum1++;while(!key4);}if(keynum1==1){ write_com(0x01); //清屏,指针清0write_com(0xc6); //在时分之间显示“:”write_date(':');write_com(0xc9); //在分秒之间显示“:”write_date(':');write_com(0x0f); //开启光标write_com(0xc4); //光标指向时}if(keynum1==2){write_com(0xc7);//光标指向分}if(keynum1==3){write_com(0xca); //光标指向秒}if(keynum1==4){ keynum1=0;write_com(0x0c); //关闭光标}}if(keynum1){if(key2==0) //s8按下加1{delayms(3);if(key2==0){if(keynum1==1){shi1++;if(shi1==24)shi1=0;write_addate2(0x44,shi1);write_com(0xc4);}if(keynum1==2){fen1++;if(fen1==60)fen1=0;write_addate2(0x47,fen1);write_com(0xc7);}if(keynum1==3){miao1++;if(miao1==60)miao1=0;write_addate2(0x4a,miao1);write_com(0xca);}while(!key2);}}if(key3==0) //s12每按一次减1{delayms(3);if(key3==0){if(keynum1==1){shi1--;if(shi1==-1)shi1=23;write_addate2(0x44,shi1);write_com(0xc4);}if(keynum1==2){fen1--;if(fen1==-1)fen1=59;write_addate2(0x47,fen1);write_com(0xc7);}if(keynum1==3){miao1--;if(miao1==-1)miao1=59;write_addate2(0x4a,miao1);write_com(0xca);}while(!key3);//松手检测}}}}void main(){ uchar num;init();for(num=0;num<15;num++){ write_date(table[num]);delayms(5);} //显示初始时间write_com(0xc0);for(num=0;num<12;num++){ write_date(table1[num]);delayms(5);}TR0=1; //开启定时器0while(1){ if(shi==shi1&&fen==fen1&&miao==miao1) //闹钟到了蜂鸣器响beep=0;keyscan(); //扫描键盘}}void time() interrupt 1 //中断函数{TH0=(65536-45872)/256;TL0=(65536-45872)%256; //进入中断装初值num1++;if(num1==20) //一秒到了{ num1=0; //清0miao++;if(miao==60) //一分到了{ miao=0; fen++; }if(!keynum1) write_addate2(0x4a,miao); //当调闹钟模式按下时不显示当前时间if(fen==60){ fen=0;shi++;}if(!keynum1) write_addate2(0x47,fen); //当调闹钟模式按下时不显示当前时间if(shi==24){shi=0;ri++;week++;}if(!keynum1) write_addate2(0x44,shi); //当调闹钟模式按下时不显示当前时间if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)if(ri==32){ ri=1; y ue++; }if(yue==4||yue==6||yue==9||yue==11)if(ri==31){ ri=1; yue++; }if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0))if(ri==30){ ri=1; yue++; }if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0))if(ri==29){ ri=1; yue++; }if(!keynum1) write_addate2(9,ri);//当调闹钟模式按下时不显示当前时间if(week==7)week=0;if(!keynum1)//当调闹钟模式按下时不显示当前时间{ write_com(0x8c);write_rq(week);}if(yue==13){ yue=0;nian++;}if(!keynum1)//当调闹钟模式按下时不显示当前时间{write_addate2(6,yue);write_com(0x88);write_date('-');}if(nian==10000)nian=0;if(!keynum1){ write_addate1(1,nian);//当调闹钟模式按下时不显示当前时间write_com(0x85);write_date('-');}}}。
LCD显示的定时闹钟设计方案1.设计要求使用AT89C51单片机结合字符型LCD显示器设计一个简易的定时闹钟LCD 时钟,若LCD选择有背光显示的模块,在夜晚或黑暗的场合中也可使用。
定时闹钟的基本功能如下:显示格式为“时时:分分”。
由LED闪动来做秒计数表示。
一旦时间到则发出声响,同时继电器启动,可以扩充控制家电开启和关闭。
程序执行后工作指示灯LED闪动,表示程序开始执行,LCD显示“ 00:00”,按下操作键K1〜K4动作如下:(1)K1 —设置现在的时间。
(2)K2 —显示闹钟设置的时间。
(3)K3 —设置闹铃的时间。
⑷K4 —闹铃ON/OFF勺状态设置,设置为ON时连续三次发出“哗”的一声,设置为OFF发出“哗”的一声。
设置当前时间或闹铃时间如下。
(1)K1 —时调整。
(2)K2 —分调整。
(3)K3 —设置完成。
(4)K4 —闹铃时间到时,发出一阵声响,按下本键可以停止声响。
本项目的难点在于4 个按键每个都具有两个功能,以最终实现菜单化的输入功能。
采用通过逐层嵌套的循环扫描,实现嵌套式的键盘输入。
2.设计方案2.1 原理本LCD定时闹钟,是以单片机及外围接口电路为核心硬件,辅以其他外围硬件电路,用汇编语言设计的程序来实现的。
根据C51单片机的外围接口特点扩展相应的硬件电路,然后根据单片机的指令设计出数字钟相应的软件,再利用软件执行一定的程序来实现数字钟的功能。
由于采用集成芯片性的单片机来制作电子钟,这样设计制作简单而且功能多、精确度高,也可方便扩充其他功能,实现也十分简单。
本设计是利用AT89C51单片机为主控芯片,由LCD晶振、电阻、电容、发光二极管、开关、喇叭等元件组成硬件电路,通过编写软件程序来实现和控制的数字定时闹钟2.2系统总框图2.3原理及工作过程说明(1)定时闹钟的基本功能如下:(a)启动仿真软件,使用LCD液晶显示器来显示现在的时间。
(b)程序执行之后显示“ 00:00”并且LED闪烁,表示开始已经计时。
单片机实验报告姓名学号时间 2013.1.9实验题目电子数字钟一、实验目的与要求1.电子数字钟必须具有显示年、月、日和显示时、分、秒的功能。
(用LCD显示)。
2.具有按键时间校正功能。
3.具备设定闹钟和定时闹钟功能。
二、实验环境(硬件环境、软件环境)1.硬件环境:单片机开发板一个,计算机一台,单片机主机电源线及与计算机的连接线各一条。
2.软件环境:软件Keil C51和软件Flash Magic。
三、实验电路(P2口输入、P1口输出实验原理图)本次实验主要使用了开发板的4个板块,分别是单片机STC89C52(如图2所示)、矩阵键盘(如图2所示)、1206LCD显示器和蜂鸣器(如图3所示)。
其中单片机芯片通过P0口把总线和矩阵键盘连接;通过P2.2和蜂鸣器间接相连,因为蜂鸣器所在的电路已经连芯片ULN2003,因此用一根杜邦线把P2.2和芯片ULN2003的第一个输入口IN1连起来。
而键盘显示这一块,由于内部已经把键盘显示的电路和单片机芯片连接起来了,所以不需要借助杜邦线了。
图1为实物连线图。
图1 实物连线图图2 单片机机座和矩阵键盘图3 蜂鸣器和1602液晶显示器四、程序流程图主要算法:主函数中先定时中断初始化,利用定时器中断实现走时,调用LCD显示程序和按键处理子函数,再调用显示时间函数显示初始时间值。
同时,在主函数中判断当前的小时和分钟值是否等于闹钟设定的时间,若等于则让蜂鸣器响。
主函数算法的框图如图4所示。
按键处理函数算法:通过键盘扫描函数得到确定哪个键盘按下,得到键盘值,如果键0按下则暂停时钟走时;键1按下则在当前的光标所在的时间单元加1;键2按下则开闹钟;键3按下则实现当前的时间单元左移一位的功能;键4按下则在当前的光标所在的时间单元减1。
时间的年月日算法:通过定时器实现时钟的走时,秒满60,分钟加1;分满60,小时加1;小时满24,日加1;至于每个月的天数根据闰年和非闰年的表格确定当月天数。
LCD电子钟程序(广工单片机课程设计)第一篇:LCD电子钟程序(广工单片机课程设计)#include#define uchar unsigned char#define uint unsigned int#define KEY_IO P3#define LCD_IO P0sbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;sbit SPK = P1^2;sbit LED = P2^4;sbit KEY_0 = P3^7;sbit KEY_1 = P3^6;sbit KEY_2 = P3^5;sbit KEY_3 = P3^4;bit new_s, modify = 0;char t0, sec = 0, min = 0, hour = 0;char code LCD_line1[] = “I LOVE U”;char code LCD_line2[] = “Timer: 00:00:00 ”;char Timer_buf[] = “00:00:00”;char a,b,c,k = 0;//--------------------void delay(uint z){uintx, y;for(x = z;x > 0;x--)for(y = 100;y > 0;y--);}//--------------------void W_LCD_Com(uchar com)//写指令 { LCD_RS = 0;LCD_IO = com;// LCD_RS和R/W都为低电平时,写入指令LCD_EN = 1;delay(5);LCD_EN = 0;//用EN输入一个高脉冲 }//--------------------void W_LCD_Dat(uchar dat)//写数据{LCD_RS = 1;LCD_IO = dat;// LCD_RS为高、R/W为低时,写入数据LCD_EN = 1;delay(5);LCD_EN = 0;//用EN输入一个高脉冲 } //--------------------void W_LCD_STR(uchar *s)//写字符串{while(*s)W_LCD_Dat(*s++);}//--------------------void W_BUFF(void)//填写显示缓冲区{Timer_buf[7] = sec % 10 + 48;Timer_buf[6] = sec / 10 + 48;Timer_buf[4] = min % 10 + 48;Timer_buf[3] = min / 10 + 48;Timer_buf[1] = hour % 10 + 48;Timer_buf[0] = hour / 10 + 48;W_LCD_STR(Timer_buf);}//--------------------uchar read_key(void){ucharx1, x2;KEY_IO = 255;x1 = KEY_IO;if(x1!= 255){delay(100);x2 = KEY_IO;if(x1!= x2)return 255;while(x2!= 255)x2 = KEY_IO;if else if(x1 == 0xbf)return 1;else if(x1 == 0xdf)return 2;else if(x1 == 0xef)return 3;else if(x1 == 0xf7)return 4;}return 255;} //--------------------void Init(){LCD_RW = 0;W_LCD_Com(0x38);delay(50);W_LCD_Com(0x0c);W_LCD_Com( 0x06);W_LCD_Com(0x01);W_LCD_Com(0x80);W_LCD_STR(LCD_li ne1);W_LCD_STR(LCD_line2);TMOD = 0x01;//T0定时方式1TH0 = 0x4c;TR0 = 1;//启动T0 PT0 = 1;//高优先级, 以保证定时精度ET0 = 1;EA = 1;}//--------------------void main(){uint i, j;uchar Key;Init();while(1){//if(new_s){ //如果出现了新的一秒, 修改时间new_s = 0;sec++;sec %= 60;if(!sec){min++;min %=60;if(!min){ hour++;hour %= 24;}}W_BUFF();//写显示W_LCD_Com(0xc0 + 7);(x1 == 0x7f)return 0;W_LCD_Com(0xC0);//if(!sec &&!min){ //整点报时for(i = 0;i < 200;i++){SPK = 0;for(j = 0;j < 100;j++);SPK = 1;for(j = 0;j < 100;j++);} }} //Key = read_key();//读出按键switch(Key){//分别处理四个按键case0: if(KEY_0){min++;min %= 60;W_BUFF();break;}case1: if(KEY_1){hour++;hour %= 24;W_BUFF();break;}case2: if(KEY_2){ a=sec;b=min;c=hour;sec = 0, min = 0, hour = 0;}case3: if(KEY_3){sec=a+sec;if(sec>60){sec=sec-60;min++;}min=b+min;if(min>60){min=min-60;hour++;}hour=c+hour;if(hour>24){hour=hour-24;} }} }} //--------------------void timer0(void)interrupt 1//T0中断函数, 50ms执行一次{TH0 = 0x4c;t0++;t0 %= 20;//20, 一秒钟if(t0 == 0){new_s = 1;LED = ~LED;}if(modify)LED = 0;} K0分加一 K1时加一 K2秒表开始K3秒表结束,恢复正常时间!第二篇:单片机课程设计电子钟课程设计任务书(指导教师填写)课程设计名称电子技术课程设计学生姓名专业班级设计题目数字钟一、课程设计的任务和目的任务:设计一台能显示“时”、“分”、“秒”的数字钟,周期为24小时;具有校时、正点报时功能。
/****************************************************************************/ //头文件#include <AT89X52.h>#include <string.h>/*****************************************************************************/ //灯与蜂鸣器定义sbit led_b = P2^7;sbit led_r = P1^4;sbit led_g1 = P1^3;sbit led_g2 = P1^2;sbit led_g3 = P1^0;sbit led_g4 = P1^1;sbit beep = P3^1;/*****************************************************************************/ //温度传感器定义sbit DQ = P3 ^ 0;//ds18B20/*****************************************************************************/ //键盘引脚定义sbit KEY_1 = P2^3; //左上sbit KEY_2 = P2^4; //左下sbit KEY_3 = P2^6; //右上sbit KEY_4 = P2^5; //右下sbit KEY_I = P3^2; //常0/****************************************************************************/ //引脚定义sbit SID = P2^1; //数据sbit SCLK = P2^2; //时钟/*****************************************************************************/ //定义DS1302时钟接口sbit clock_clk = P3 ^ 5;//ds1302_clk(时钟线)sbit clock_dat = P3 ^ 4;//ds1302_dat(数据线)sbit clock_Rst = P3 ^ 3;//ds1302_Rst(复位线)/*****************************************************************************/ //定义累加器A中的各位sbit a0 = ACC ^ 0;sbit a1 = ACC ^ 1;sbit a2 = ACC ^ 2;sbit a3 = ACC ^ 3;sbit a4 = ACC ^ 4;sbit a5 = ACC ^ 5;sbit a6 = ACC ^ 6;sbit a7 = ACC ^ 7;/****************************************************************************/ //定义全局变量unsigned char yy,mo,dd,xq,hh,mm,ss;//定义时间映射全局变量(专用寄存器)bit w = 0; //调时标志位static unsigned char menu = 0;//定义静态小时更新用数据变量static unsigned char keys = 0;//定义静态小时更新用数据变量static unsigned char timecount = 0;//定义静态软件计数器变量/****************************************************************************/ void DelayM(unsigned int a){//延时函数1MS/次unsigned char i;while( --a != 0){for(i = 0; i < 125; i++); //一个; 表示空语句,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);}。
#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit LCD_RS=P2^6; //复位端液晶sbit LCD_RW=P2^5; //写数据端液晶sbit LCD_EP=P2^7; //使能端液晶sbit key1=P2^0;//键盘1sbit key2=P2^1;//键盘2sbit key3=P2^2;//键盘3sbit key4=P2^3;//键盘4sbit Beep=P1^5;//蜂鸣器uint num;uchar keynum,keynum1,shi1,fen1,miao1,aa,nian,shi2,fen2,miao2; uchar code table[]="2013-07-24-3"; //设定开始显示的时间uchar code table1[]=" 15:57:00";uchar code table2[]="1234567"; //定义二维字符数组uchar miao=00;uchar fen=57;uchar shi=15;uchar yue=07;uchar ri=24;uchar week=3;uchar nian=2013;void delay(uint z)//延时{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void di(){Beep=1;delay(1000);Beep=0;}void write_com(uchar com)//写指令函数液晶{LCD_RS=0;LCD_RW=0;P0=com;delay(5);//E变为以有个时间LCD_EP=1;delay(5);//一个高脉冲LCD_EP=0;}void write_date(uchar date)//写数据函数液晶{LCD_RS=1;LCD_RW=0;P0=date;delay(5);//E变为yi有个时间LCD_EP=1;delay(5);//一个高脉冲LCD_EP=0;}void init()//初始化函数{TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;LCD_EP=0;write_com(0x38);//显示模式write_com(0x0c);//打开显示,光标不开,不闪烁write_com(0x01);//清屏write_com(0x80);//数据指针初始化}void year(uchar date)//显示年{uchar bai,shi,ge;uint qian;qian=2;bai=0;shi=date%1000%100/10;ge=date%10;write_com(0x80);write_date(0x30+qian);write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge);}void xianshi(uchar add,uchar date)//显示月,日,时,分,秒{uchar shi,ge;shi=date/10;ge=date%10;write_com(add+0x80);write_date(0x30+shi);write_date(0x30+ge);}void xingqi()//显示星期{write_com(0x8b);write_date(table2[week-1]);}void key(){if(key1==0){delay(5); //去抖延时if(key1==0) //确认按键1被按下,{keynum++;while(!key1);//松手检测}if(keynum==1)//按下一次{TR0=0; //关闭定时器0write_com(0x83);//光标跳到nian份write_com(0x0f);//开启光标显示,光标闪烁}if(keynum==2){write_com(0x86);//光标跳到yue}if(keynum==3){write_com(0x89);//光标跳到ri}if(keynum==4){write_com(0x8b);//光标跳到xingqi}if(keynum==5){write_com(0x80+0x44);//光标跳到时}if(keynum==6){write_com(0x80+0x47);//光标跳到分}if(keynum==7){write_com(0x80+0x4a); //光标跳到秒}if(keynum==8){ keynum=0; //退出调时间模式TR0=1; //开启定时器0write_com(0x0c); //关闭光标显示}}if(keynum) //当进入调时间模式时{if(key2==0) //2按键按下jia{delay(5); //去抖延时if(key2==0){if(keynum==1)//调nian{nian++;//2每按下一次if(nian==2099)nian=2000; //加满清0year(nian);write_com(0x83); //写完数据指针指向月份原来位置}if(keynum==2)//调月{yue++;//2每按下一次月份加1if(yue==13)yue=1; //加满清0xianshi(5,yue); //显示月份write_com(0x86); //写完数据指针指向月份原来位置}if(keynum==3)//调日{ ri++;if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)//1,3,5,7,8,10,12月有31天if(ri==32)ri=1;//加满还原if(yue==4||yue==6||yue==9||yue==11)//4,6,9,11月有30天if(ri==31)ri=1;if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0))//闰年2月有29天if(ri==30)ri=1;if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0))//非闰年2月有28天if(ri==29)ri=1;xianshi(8,ri);write_com(0x89); //写完数据指针指向日原来位置}if(keynum==4)//调星期{week++; //2每按下一次星期加1if(week==7) //加满还原week=1;xingqi(); //显示星期write_com(0x8b); //写完数据指针指向星期原来位置}if(keynum==5)//调时{shi++;//2每按下一次时加1if(shi==24)shi=0; //加满还原xianshi(0x43,shi); //显示时write_com(0x80+0x44); //写完数据指针指向时原来位置}if(keynum==6)//调分{fen++;//2每按下一次分加1if(fen==60)fen=0;//加满还原xianshi(0x46,fen); //显示分write_com(0x80+0x47); //写完数据指针指向分原来位置}if(keynum==7)//调秒{miao++; //2每按下一次秒加1if(miao==60)miao=0;//加满还原xianshi(0x49,miao);//显示秒write_com(0x80+0x4a); //写完数据指针指向秒原来位置}while(!key2); //松手检测}}if(key3==0){delay(5);//消抖if(key3==0)//3按下时减1{if(keynum==1)//月减一{nian--;if(nian==-1)nian=2000;year(nian);write_com(0x83);}if(keynum==2)//月减一{yue--;if(yue==-1)yue=12;xianshi(5,yue);write_com(0x86);}if(keynum==3)//日减一{ri--;if(ri==0){if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)//1,3,5,7,8,10,12ri=31;if(yue==4||yue==6||yue==9||yue==11)//4,6,9,11ri=30;if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0))//闰年ri=29;if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0))//非闰年ri=28;}xianshi(8,ri);write_com(0x89);}if(keynum==4)//星期减一{week--;if(week==-1)week=6;xingqi();write_com(0x8b);}if(keynum==5)//时减一{shi--;if(shi==-1)shi=23;xianshi(0x43,shi);write_com(0xc4);}if(keynum==6)//分减一{fen--;if(fen==-1)fen=59;xianshi(0x46,fen);write_com(0xc7);}if(keynum==7)//秒减一{miao--;if(miao==-1)miao=59;xianshi(0x49,miao);write_com(0xca);}while(!key3); //3松手检测}}}if(key4==0)//4被按下进入调闹钟模式{ delay(5);//消抖if(key4==0){keynum1++;while(!key4);//松手}if(keynum1==1){ write_com(0x01);//清屏,指针清0write_com(0x80+0x45);//在时分之间显示":"write_date(':');write_com(0x80+0x48);//在分秒之间显示":"write_date(':');write_com(0x0f);//开启光标write_com(0xc4);//光标指向时}if(keynum1==2){write_com(0xc7);//光标指向分}if(keynum1==3){write_com(0xca);//光标指向秒}if(keynum1==4){ xianshi(0x43,shi1);xianshi(0x46,fen1);xianshi(0x49,miao1);}if(keynum1==5){ keynum1=0;write_com(0x0c);//关闭光标}}if(keynum1)//进入了调闹钟模式{if(key2==0)//2按下加1{delay(5);if(key2==0)//确实按下{if(keynum1==1)//调闹钟的时{shi1++;if(shi1==24)shi1=0;xianshi(0x43,shi1);write_com(0xc4);}if(keynum1==2)//调闹钟de分{fen1++;if(fen1==60)fen1=0;xianshi(0x46,fen1);write_com(0xc7);}if(keynum1==3){miao1++;if(miao1==60)miao1=0;xianshi(0x49,miao1);write_com(0xca);}while(!key2);//松手检测}}if(key3==0)//3每按一次减1{delay(5);if(key3==0){if(keynum1==1){shi1--;if(shi1==-1)shi1=23;xianshi(0x43,shi1);write_com(0xc4);}if(keynum1==2){fen1--;if(fen1==-1)fen1=59;xianshi(0x46,fen1);write_com(0xc7);}if(keynum1==3){miao1--;if(miao1==-1)miao1=59;xianshi(0x49,miao1);write_com(0xca);}while(!key3);//松手检测}}}}void daole(){if(aa==19)//一秒到了{ aa=0; //清0miao++;}if(miao==60) //一分了{ miao=0;fen++; }if(!keynum1) xianshi(0x49,miao); //当调闹钟模式按下时不显示当前时间if(fen==60){ fen=0;shi++;}if(!keynum1){xianshi(0x46,fen);write_com(0x80+0x48);//在分秒之间显示":"write_date(':') ;} //当调闹钟模式按下时不显示当前时间if(shi==24){shi=0;ri++;week++;}if(!keynum1){xianshi(0x43,shi);write_com(0x80+0x45);//在时分之间显示":"write_date(':') ;} //当调闹钟模式按下时不显示当前时间if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)if(ri==32){ri=1;yue++;}if(yue==4||yue==6||yue==9||yue==11)if(ri==31){ri=1;yue++;}if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0))if(ri==30){ri=1;yue++;}if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0))if(ri==29){ri=1;yue++;}if(!keynum1) xianshi(8,ri); //当调闹钟模式按下时不显示当前时间if(week==7)week=0;if(!keynum1) //当调闹钟模式按下时不显示当前时间{xingqi();write_com(0x8a);write_date('-');}if(yue==13){yue=0;nian++;}if(!keynum1) //当调闹钟模式按下时不显示当前时间{xianshi(5,yue);write_com(0x87);write_date('-');write_com(0x84);write_date('-');}if(!keynum1) //当调闹钟模式按下时不显示当前时间year(nian);}}void main(){init();for(num=0;num<12;num++){ write_date(table[num]);delay(5);} //显示初始时间write_com(0x80+0x40);for(num=0;num<11;num++){ write_date(table1[num]);delay(5);}TR0=1;while(1){if(shi==shi1&&fen==fen1&&miao==miao1) //闹钟到了蜂鸣器响{di();if(key4==0)//4被按下{ delay(5);//消抖if(key4==0)Beep=0;TR0=1;while(!key4);//松手}}daole();key();}}void time() interrupt 1 //中断函数{TH0=(65536-45872)/256;TL0=(65536-45872)%256;//进入中断装初值aa++;}。
#i nclude<reg51.h> //包含单片机寄存器的头文件#i nclude<i ntrin s.h> 〃包含_no p_()函数定义的头文件〃1602端口定义//寄存器选择位,将 RS 位定义为P2.0引脚〃读写选择位,将 RW 位定义为P2.1引脚 //使能信号位,将E 位定义为P2.2引脚 //忙碌标志位,,将BF 位定义为P0.7引脚 //AD 端口定义 sbit CLK=P2A3;sbit start=P2A4;sbit oe=P2A5;sbit eoc=P2A7;sbit out_pulse=P2A 6;//5us 脉冲sbit p30=P3A0;#defi ne uchar un sig ned char#defi ne uint un sig ned intuchar n=0;uchar flag=0;//1s 标志位/*****************************************************函数功能:延时1ms***************************************************/ void delay1ms(){unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<33;j++)/*****************************************************函数功能:延时若干毫秒入口参数:n***************************************************/void delay (un sig ned int n){un sig ned int i;for(i=0;i< n;i++)delay1ms();} /*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result o result=1,忙碌;result=0,不忙sbit RS=P2A0; sbit RW=P2A1;sbit E=P2A2;************************************************刘bit BusyTest(void){bit result;RS=0; 〃根据规定,RS为低电平,RW为高电平时,可以读状态RW=1;E=1; 〃E=1,才允许读写_n op_();〃空操作_n op_();_n op_();_n op_(); 〃空操作四个机器周期,给硬件反应时间result=BF; //将忙碌标志电平赋给resultE=0;return result;}/*****************************************************函数功能:将模式设置指令或显示地址写入液晶模块入口参数:dictate***************************************************/void Write_com (un sig ned char dictate){while(BusyTest()==1); // 如果忙就等待RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令RW=0;E=0; 〃E置低电平(写指令时,//就是让E从0到1发生正跳变,所以应先置"0"_n op_();_no p_(); 〃空操作两个机器周期,给硬件反应时间P仁dictate; //将数据送入P0 口,即写入指令或地址_n op_();_n op_();_n op_();_n op_(); 〃空操作四个机器周期,给硬件反应时间E=1; 〃E置高电平_n op_();_n op_();_n op_();_n op_(); 〃空操作四个机器周期,给硬件反应时间E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:指定字符显示的实际地址入口参数:x************************************************刘void WriteAddress( un sig ned char x) {Write_com(x|0x80); //显示位置的确定方法规定为"80H+地址码x"}/*****************************************************函数功能:将数据(字符的标准ASCII码)写入液晶模块入口参数:y(为字符常量)***************************************************/void WriteData( un sig ned char y){while(BusyTest()==1);RS=1; //RS为高电平,RW为低电平时,可以写入数据RW=0;E=0; 〃E置低电平(写指令时,,//就是让E从0到1发生正跳变,所以应先置"0"P1=y; 〃将数据送入P0 口,即将数据写入液晶模块_n op_();_n op_();_n op_();_n op_(); //空操作四个机器周期,给硬件反应时间E=1; //E置高电平_n op_();_n op_();_n op_();_n op_(); //空操作四个机器周期,给硬件反应时间E=0; //当E由咼电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:对LCD的显示模式进行初始化设置***************************************************/void Lcdln t(void){delay(15); 〃延时15ms,首次写指令时应给LCD 一段较长的反应时间Write_com(0x38); //显示模式设置:16 >2显示,5 X7点阵,8位数据接口delay(5); //延时5msWrite_com(0x0c); delay(5);Write_com(0x06); delay(5);Write_com(0x01); delay(5);//显示模式设置:显示开,有光标,光标闪烁〃清屏幕指令,将以前的显示内容清除void sys in it()TMOD = 0x21; //设定定时器 T1工作方式 TH1=0xfd; II 利用T1中断产生CLK 信号TL1=0xfd;//50khzEA = 1; //开总中断ET 仁 1;TR1=1; //启动定时器 T1TH0=0x45;TL0=0x00;//50MS 定时ET0=1;TR0=1;start=0; // START : A / D 转换启动信号,输入,高电平有效。
oe=0; 〃数据输出允许信号,输入,高电平有效。
当 A / D 转换结束时,此端输入一个高电平,才能打开输出三态门,输出数字量。
} /***********T0 中断服务程序 ************/ void t0(void) in terrupt 1{ET0=0;TH0=0X45;//46TL0=0X00;//50MS 定时 n++;if(n==20) {flag=1;n=0;}ET0=1;}void t1(void) in terrupt 3 {ET1=0;CLK=~CLK;ET 仁 1;}//0808数据采集*******始■^化 *********T0工作方式1un sig ned char adc() {un sig ned char Temp; start=1;// delay(1);//do not delay start=0; //启动信号while (!eoc);// A / D转换结束信号P0=0xff;// delay(1);oe=1;Temp=P0;〃读取采集数据oe=0;// delay(4); return(Temp);//返回采集数据} void display(uint a)// 显示子函数{uint bai,shi,ge;bai=a/100; shi=(a-bai*100)/10;ge=a%10;WriteAddress(2);WriteData(0x30+bai);〃显示百位WriteData(0x30+shi);〃显示十位WriteData(0x30+ge);〃显示个位}void mai n(){uint temp1,temp2;uchar f=0;LcdI nt();delay(5);sys in it();CLK=0;WriteAddress(O);//从第0行开始显示WriteData('f);// 显示fWriteData(':');〃显示:WriteAddress(5);//从第5行开始显示WriteData('H'); 〃显示HWriteData('z');// 显示zwhile(1){temp2=temp1;temp1=adc();//ad 采集if(((temp1>=128) &&(temp2<=128))||((temp1<=128)&&(temp2>=128))) {f++;〃out_pulse=1;_n op_();_n op_();_n op_();_n op_();_n op_();out_pulse=0;〃产生5us的脉冲信号}if(flag==1)//到达1s后计算频率{flag=0;f=f/2;display(f);// 显示频率f=0;}}}。