单片机控制多位数码管的电子时钟程序
用单片机控制多位数码管的电子时钟,用独立按键进行控制,可显示时间,日期,有闹钟功能,独立按键进行时间日历,闹钟设置
操作方法
- 01
软件编程: keil工程C语言代码:
- 02
/*************************************** 项目名称:数码管电子时钟 实现功能:数码管显示时间、日期,时间、日 期可调,可设置闹钟,闹铃响一分钟。 ****************************************/ #include <reg52.h> #define uint unsigned int #define uchar unsigned char uint numwe,tt,t,numdu,set,aclock,rili; unsigned long int time,time1=0; unsigned long int second,minute,hour,year=2012,month=12,day=31; uchar code du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar code we[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; uchar Mth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//每月对应的天数 uchar YMth[13]={0,2,9,2,1,2,1,2,2,1,2,1,2}; sbit dula=P2^0; sbit wela=P2^1; sbit KEY0=P3^2;//选位 sbit KEY1=P3^1;//加一 sbit KEY2=P3^0;//设闹铃 sbit KEY3=P3^3; sbit beep=P2^2;//响铃 void Delay(uint del);//延时程序 void Display(uint sd,uint mm,uint hy);//显示程序 void add();//加一 void alarmclock();//闹钟 void init();//初始化 int clock();//计算时间 void Calender();//计算日期 void main() { P2=0xff; init(); while(1){ add(); if(rili==1)//分日历和时间显示 Display(day,month,year); else Display(second,minute,hour); alarmclock(); } } void Display(uint sd,uint mm,uint hy) { int y0,y1,y2; if(rili==1) { y0=hy/1000,y1=hy%1000;y2=hy%100; } for(numwe=0;numwe<8;numwe++) { P0=0xff; wela=1; P0=we[numwe]; wela=0; P0=0xff; dula=1; switch(numwe) { case 0: P0=(tt==1&set==1)?0x00:(rili==1)?du[y0]:du[hy/10];break; case 1: P0=(tt==1&set==2)?0x00:(rili==1)?du[y1/100]:du[hy%10];break; case 2: P0=(rili!=1)?0x40:(tt==1&set==3)?0x00:du[y2/10];break; case 3: P0=(tt==1&set==4)?0x00:(rili==1)?du[hy%10]+0x80:du[mm/10];break; case 4: P0=(tt==1&set==5)?0x00:(rili==1)?du[mm/10]:du[mm%10];break; case 5: P0=(rili!=1)?0x40:(tt==1&set==6)?0x00:du[mm%10]+0x80;break; case 6: P0=(tt==1&set==7)?0x00:du[sd/10];break; case 7: P0=(tt==1&set==8)?0x00:du[sd%10];break; } dula=0; Delay(5); } } void init()//初始化 { wela=0; dula=0; TMOD=0x01;//设置定时器0为工作方式1 TH0=(65536-50000)/256;//定时器高八位//定时5ms TL0=(65536-50000)%256;//定时器低八位 IE=0x8f;//开启中断 TCON=0x15;//启动定时器及工作方式 } int clock()//计算时间 { if(t==10|t==20) tt=!tt;//闪烁标志位 if(t==20) { t=0; if(!(set!=0&aclock==0)) time++; if(time>=time1&time<time1+60) beep=0; else beep=1; Calender(); if(aclock==0) { second=time%60; minute=(time%3600)/60; hour=time/3600; if(hour==24) { time=0; hour=0; } } else { second=time1%60; minute=(time1%3600)/60; hour=time1/3600; if(hour==24) { time=0; hour=0; } } } } void Delay(uint del) { uint i,j; for(i=0; i<del; i++) for(j=0; j<100; j++); } void timer0() interrupt 1//定时器0中断 { TH0=(65536-50000)/256;//定时器高八位//定时5ms TL0=(65536-50000)%256;//定时器低八位 t++; clock(); } void settime() interrupt 0//it0 { if(KEY0==0) { Delay(2); if(KEY0==0) { if(rili!=1) {if(set==2|set==5) set=set+2; else set++;} else set++; if(set==9) {set=0;t=0;} //while(!KEY0); } } } void calendar() interrupt 2//日历 { if(KEY3==0) { Delay(2); if(KEY3==0) rili=!rili; set=0;aclock=0; } } void Calender()//计算日历 { if(time==86400) { day++; if((year%4==0&year%100!=0)|(year%400==0)) Mth[2]=29; else Mth[2]=28; if(day>Mth[month]) { day=1; month++; if(month>12) {month=1; year++;} } } } void add()//自加一 { int ge,ge1,ge2,shi,shi1,shi2,bai2,qian2; if(rili==1) { ge=day%10;ge1=month%10;ge2=year%10; shi=day/10;shi1=month/10;shi2=year%100/10; bai2=year%1000/100;qian2=year/1000; }else { ge=second%10;ge1=minute%10;ge2=hour%10; shi=second/10;shi1=minute/10;shi2=hour/10; } if(KEY1==0) { Delay(2); if(KEY1==0) { if(rili==1) { if((year%4==0&year%100!=0)|(year%400==0)) YMth[2]=10; else YMth[2]=9; switch(set) { case 1:qian2=(qian2+1)%10;break; case 2:bai2=(bai2+1)%10;break; case 3:shi2=(shi2+1)%10;break; case 4:ge2=(ge2+1)%10;break; case 5:shi1=(shi1+1)%2;break; case 6:ge1=(shi1==1)?(ge1+1)%3:(ge1+1)%10;break; case 7:shi=(month==2)?(shi+1)%3:(shi+1)%4;break; case 8:ge=(shi==3)?(ge+1)%YMth[month]:(month==2)?(ge+1)%YMth[2]:(ge+1)%10;break; } year=qian2*1000+bai2*100+shi2*10+ge2; month=shi1*10+ge1; day=shi*10+ge; }else { switch(set) { case 1: shi2=(shi2+1)%3;break; case 2: ge2=(ge2+1)%4;break; case 4: shi1=(shi1+1)%6;break; case 5: ge1=(ge1+1)%10;break; case 7: shi=(shi+1)%6;break; case 8: ge=(ge+1)%10;break; } second=shi*10+ge; minute=shi1*10+ge1;hour=shi2*10+ge2; if(aclock==0) time=hour*3600+minute*60+second; else time1=hour*3600+minute*60+second; } while(!KEY1); } } } void alarmclock()//设置闹铃 { if(KEY2==0) { Delay(2); if(KEY2==0) { while(!KEY2); aclock=1; rili=0; set=0; while(1) { if(rili==1) Display(day,month,year); else Display(second,minute,hour); add(); if(KEY2==0) { while(!KEY2); aclock=0; set=0; break; } } } } }
- 03
引脚连接说明: 1、PO口接8为共阴数码管; 2、P2^0与P2^1分别为数码管的段锁存与位锁存; 3、P3^0为闹钟显示功能按键 P3^1为设置时钟时的数字调整,单向增大 P3^2为设置键,可对闹钟,日期,时间选择进行设置 P3^3为日立与时间的转换查看键 4、闹钟可选用led灯或者蜂鸣器,默认提醒时长为1分钟
- 04
软件仿真与实验效果: