《[单片机]c51数字时钟(带年月日显示).doc》由会员分享,可在线阅读,更多相关《[单片机]c51数字时钟(带年月日显示).doc(13页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、【单片机】c51数字时钟(带年月日显示)显示当前时间:9点58分34秒 (第一个零表示闹钟未开启)当前日期:10年4月六日摘要:本设计以单片机为核心,LED数码管动态扫描显示。采用矩阵式键盘输入能任意修改当前时间日期和设定闹钟时间。具有显示年月日(区分闰年和二月),闹钟报警和整点报时功能说明系统的功能选择由7个按键完成。其中P3.0,P3.1分别对应调整当前时间的时和分,P3.2为外部中断0,控制闹钟功能的开启/关闭(开启时数码管第一位显示字母c)P3.3用作外部中断1,当前时间的显示与闹铃时间显示切换,闹钟显示时按P3.0,P3.1可进行闹钟时分的设定,此时,led1灯灭。闹铃时间到切闹钟开
2、关开启时,闹铃响一分钟。P3.5P3.6P3.7对年月日进行调整(第一次按P3.5,就进入了年月日的显示,现在就可对日期进行调整)。按P3.1回到当前时间的显示状态。整点到时:报警对应小时的次数。程序如下:#include#include#include#define uchar unsigned char#define uint unsigned intuchar data keyvalue; /查到的键值uchar data keys; /转换出的数字uchar dis8;uchar code seg=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f
3、,0x67,0x40,0x00,0x39,0xf7; / 0 1 2 3 4 5 6 7 8 9 - 灭灯 cnsbit led_duan=P26;/段选通sbit led_wei=P27;/位选通sbit speaker=P23;/蜂鸣器sbit minitek=P30;/分校正 按键sbit hourk=P31;/小时校正 按键sbit p3_4=P34;/sbit yeark=P35;/年sbit monthk=P36;/月sbit dayk=P37;/日uchar data wei,i;bit leap_year;/闰年标志位bit dis_nyr;bit cal_year=1;bit
4、 calculate=1;/显示年月日 与 当前时间切换标志uchar data c_min;/闹钟分寄存单元uchar data c_hou;/闹钟、小时寄存单元uchar data second;/秒uchar data minite;/分变量uchar data hour;/小时变量uchar data year,month,day;/定义年月日变量uchar data CNTA;uchar data speaker_num; /蜂鸣次数 bit beep; /整点报时标志bit run; /运行标志bit flash; /灭灯标志bit clarm_switch; /闹钟开关标志bit
5、 baoshi; /报时开关标志sbit led1=P16; / 按键标识指示灯sbit led2=P17; / 运行标志指示灯sbit P3_2=P32;sbit P3_3=P33;uint n,k;/*10微秒级延时*/void delay_10us(uchar n) do _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); while(-n);/*毫秒级延时 */void delay_ms(uint n) do delay_10us(131); while(-n);/* 当前时间转换*/clk_to_dis() dis0=second%10;dis1
6、=second/10; if(flash)dis2=10; else dis2=11;dis3=minite%10;dis4=minite/10;dis5=hour%10;dis6=hour/10;/*定时闹钟显示译码(用于七段码显示)*/clarm_to_dis() dis0=c_min%10;dis1=c_min/10;if(flash)dis2=10;/亮灯 else dis2=11; /灭灯dis3=c_hou%10;dis4=c_hou/10;dis5=10;dis6=13;/*年月日显示译码*/nyr_to_dis() dis0=day%10;dis1=day/10;dis2=10
7、;/显示-dis3=month%10;dis4=month/10;dis5=10; / -dis6=year%10;dis7=year/10;/*主函数*/void main()P2=0xff;P1=0XFF;p3_4=0;run=1;led2=0;/运行指示灯亮led1=1;flash=0x00;dis2=10; /第三位显示“-”wei=0x7f;/选通低位 i=0;second=21;minite=58;hour=9;CNTA=0x00;year=10;month=4;day=5;clk_to_dis();TMOD=0x11;TH0=15560/256;TL0=15560%256;TH1
8、=0xfc;TL1=0x18;EA=1; PT0=1;EX0=1; /开中断;EX1=1;ET0=1;ET1=1;TR0=1;TR1=1;while(1) while(run=1) clk_to_dis(); if(calculate) if(month=1|month=3|month=5|month=7|month=8|month=10|month=12)day+;if(day31)day=0x01;month+; if(month=13)month=1;year+;cal_year=1;led1=0; /指示灯亮 if(month=4|month=6|month=9|month=11) d
9、ay+; if(day30)day=0x01;month+; led1=0; /指示灯亮 if(month=2) if(leap_year=1)day+;if(day=30)day=1;else day+;if(day=29)day=1; while(cal_year) if(year+2000)%400=0) leap_year=1; / 被400整除为闰年 else if(year+2000)%100=0) leap_year=0; /不能被400整除 能被100整除 不是闰年 else if(year+2000)%4=0) leap_year=1; /不能被400、100整除 能被4整除
10、 是闰年 else leap_year=0; cal_year=0;calculate=0;led1=1;while(!minitek)for(n=0;n1000;n+);if(!minitek=0)break; /延时防抖minite+;second=0x00;led1=0; for(n=0;n20;n+) speaker=!speaker; delay_10us(50); /蜂鸣器响 if(minite=60)minite=0x00;while(!minitek); /等待键松开 led1=1;/显示灯 while(!hourk)for(n=0;n1000;n+);if(!hourk=0)
11、break;hour+;second=0x00;led1=0;for(n=0;n30;n+)speaker=!speaker;delay_10us(30); /蜂鸣器响if(hour=24) hour=0x00;while(!hourk);led1=1; while(!yeark)/yeark键复用 进入年月日调整for(n=0;n1000;n+);if(!yeark=0)break;dis_nyr=1;while(!yeark);while(dis_nyr) nyr_to_dis(); while(!yeark)for(n=0;n1000;n+);if(!yeark=0)break;year
12、+;led1=0;for(n=0;n30;n+)speaker=!speaker;delay_10us(30); /蜂鸣器响 if(year+2000)%400=0) leap_year=1; / 被400整除为闰年 else if(year+2000)%100=0) leap_year=0; /不能被400整除 能被100整除 不是闰年 else if(year+2000)%4=0) leap_year=1; /不能被400、100整除 能被4整除 是闰年 else leap_year=0; while(!yeark);led1=1; while(!monthk)for(n=0;n1000;
13、n+);if(!monthk=0)break;month+;if(month=13)month=1;led1=0;for(n=0;n30;n+)speaker=!speaker;delay_10us(30); /蜂鸣器响while(!monthk);led1=1; while(!dayk)for(n=0;n31)day=0x01;led1=0; /指示灯亮 if(month=4|month=6|month=9|month=11) day+; if(day30)day=0x01; led1=0; /指示灯亮 if(month=2) if(leap_year=1)day+;if(day=30)da
14、y=1;else day+;if(day=29)day=1;led1=0;for(n=0;n30;n+)speaker=!speaker;delay_10us(30); /蜂鸣器响while(!dayk);led1=1;while(!hourk) for(n=0;n1000;n+); if(hourk) break; dis_nyr=0; while(!hourk);if(clarm_switch)dis7=12;/开启显示 C else dis7=11;/关闭 不显示 dis6=11; clk_to_dis(); if(clarm_switch)/闹铃时间到,指示灯闪烁 蜂鸣器长响if(c_
15、min=minite&c_hou=hour)speaker_num=60;beep=1;while(beep& clarm_switch)led1=!led1;delay_ms(100);clk_to_dis();led1=1;beep=0; while(run=0)/闹钟时间设定 clarm_to_dis();/while(!minitek)for(n=0;n1000;n+);if(!minitek=0)break;/延时防抖c_min+;led1=0; for(n=0;n20;n+) speaker=!speaker; delay_10us(50);/蜂鸣器响 if(c_min=60)c_
16、min=0x00;while(!minitek); /等待键松开 led1=1;/显示灯 while(!hourk)for(n=0;n1000;n+);if(!hourk=0)break;c_hou+;led1=0;for(n=0;n7)speaker_num=2*hour; /整点到 设定报时次数 蜂鸣标志 置1 beep=1;if(hour=24)hour=0;calculate=1;/0点到,日期标志加一 TR1=1;/*定时器中断T1*/timer1() interrupt 3 using 3 TH1=0xfc; TL1=0x18;P0=0xff;led_wei=1;led_wei=0
17、;P0=segdisi;led_duan=1;led_duan=0;P0=wei;led_wei=1;led_wei=0;if(+i=8)i=0;wei=_cror_(wei,1); /*外中断0*/int_0() interrupt 0 clarm_switch=!clarm_switch;/ 闹钟开关if(clarm_switch)dis7=12;/ 开启显示 开启第一位显示C else dis7=11;/ 关闭 不显示 for(k=0;k40;k+)speaker=!speaker;led1=!led1;delay_ms(5);led1=1;/*外中断1*/int_1() interrupt 2/闹钟时间设置/运行 转换开关run=!run;if(run)led2=0;else led2=1;for(k=0;k90;k+)speaker=!speaker;/ 蜂鸣器响led1=!led1; / 指示灯闪烁delay_10us(100);led1=1;13 / 13