仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg51.h>
- //---------------------端口定义-----------------
- sbit K1 = P1^0; //指定P1.0为K1,在C51中Px.y写为Px^y,因“.”在C语言中是一种运算符
- sbit K2 = P1^1;
- sbit K3 = P1^2;
- sbit K4 = P1^3;
- //---------------------变量定义-----------------
- unsigned char hou,min,sec,yea,mon,day;
- unsigned char disp_buf[6]; //定义显示缓冲单元
- bit update_time; //时间更新标志,1:当前时间已更新 0:当前时间未更新
- unsigned char cnt=0; //时间累加变量
- unsigned int fli=0; //闪烁时间累加变量
-
- bit c = 0; //时间 与日期切换标志变量,c=0显示时间,c=1显示日期
- bit leap; //判断是否为闰年标志变量
- bit f = 0; //判断闪烁与不闪烁切换标志变量
- bit s = 1; //停留在某一状态变量
- //---------------------函数声明-----------------
- void sysinit(void); //调用初始化函数
- //void time_inc(void); //调用时间加1函数
- void key_proc(void); //调用按键模块
- void disp_proc(void); //调用显示模块
- void delayms(unsigned char x);//延时xms函数
- void main(void)
- {
- sysinit(); //调用初始化函数
- while(1)
- {
- //time_inc(); //调用时间加1函数
- key_proc(); //调用按键模块
- //showcut(); //调用切换函数
- disp_proc(); //调用显示模块
- }
- }
- void sysinit(void)
- {
- hou = 12;
- min = 0;
- sec = 0;
- yea = 16;
- mon = 10;
- day = 1;
- TMOD=0X11; //设置定时器0和定时器1为工作方式1
- TH0=(65536-50000)/256; //装初值
- TL0=(65536-50000)%256;
- TH1=(65536-50000)/256; //装初值
- TL1=(65536-50000)%256;
- EA=1; //开总中断
- ET0=1; //开定时器0中断
- TR0=1; //启动定时器0
- ET1=1; //开定时器1中断
- TR1=0; //启动定时器1
-
- }
- void key_proc(void)
- {
- static key_ask=0;
- if((K1 == 0)&&(c == 0))
- {
- delayms(10); //去抖动
- if(key_ask == 0)
- {
- hou++;
- hou=hou%24;
- key_ask =1;
- }
- }
- else if((K2 == 0)&&(c == 0))
- {
- delayms(10);
- if(key_ask == 0)
- {
- min++;
- min = min % 60;
- key_ask = 1;
- }
- }
- else if((K1 == 0)&&(c == 1))
- {
- delayms(10);
- if(key_ask == 0)
- {
- day++;
- if((leap ==1)&&(mon == 2)&&(day >29 ))
- day = 1;
- else if((leap == 0)&&(mon == 2)&&(day > 28))
- day=1;
- else if(((mon == 1)||(mon == 3)||(mon == 5)||(mon == 7)||(mon == 8)||(mon == 10)||(mon == 12))&&(day > 31))
- day = 1;
- else if(((mon == 2)||(mon == 4)||(mon == 6)||(mon == 9)||(mon == 11))&&(day > 30))
- day = 1;
- key_ask = 1;
- }
- }
- else if((K2 == 0)&&(c == 1))
- {
- delayms(10);
- if(key_ask == 0)
- {
- mon++;
- if(mon > 12)
- mon = 1;
- key_ask = 1;
- }
- }
- else if(K3 == 0)
- {
- delayms(10);
- if(key_ask == 0)
- {
- c=~c;
- key_ask = 1;
- }
- }
- if((K4 == 0)&&(f == 0))
- {
- delayms(10);
- if(key_ask == 0)
- {
- TR1=1;
- f = 1;
- key_ask = 1;
- }
- }
- else if((K4 == 0)&&(f == 1))
- {
- delayms(10);
- if(key_ask == 0)
- {
- TR1 = 0;
- f = 0;
- key_ask = 1;
- s = 1;
- }
- }
-
- else if(key_ask == 1)
- {
- if(K1 == 1 && K2 == 1 && K3 ==1)
- {
- key_ask = 0;
- }
- }
- }
- void gengxin(void)
- {
-
- }
- void disp_proc(void)
- {
- unsigned char i,j;
- unsigned char code dis_tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- unsigned char code bit_tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
- if((update_time == 1)&&(s == 1)) //若时值(hou,min,sec)已更新则要更新显缓disp_buf。使显示与时值保持一致
- {
- if((c == 0))
- {
- update_time = 0;
- disp_buf[0] = hou / 10; //更新时值
- disp_buf[1] = hou % 10;
- disp_buf[2] = min / 10; //更新分值
- disp_buf[3] = min % 10;
- disp_buf[4] = sec / 10; //更新秒值
- disp_buf[5] = sec % 10;
- }
- if((c == 1))
- {
- update_time = 0;
- disp_buf[0] = yea / 10; //年
- disp_buf[1] = yea % 10;
- disp_buf[2] = mon / 10; //月
- disp_buf[3] = mon % 10;
- disp_buf[4] = day/ 10; //日
- disp_buf[5] = day% 10;
- }
- }
-
- for(i = 0; i < 6; i++)
- {
- P3 = 0xff; //熄灭显示器(避免数码管出现乱码,不熄
- //灭就会下次字型码输出的时候,下个数码
- //管没有亮得时候,在之前的数码管上就瞬间亮了)
- if((i==1)||(i==3))
- {
- P2 = dis_tab[disp_buf[i]]+0x80; //输现定形码
- P3 = bit_tab[i];
- for(j = 0; j < 100; j++);
- }
- else
- {
- P2 = dis_tab[disp_buf[i]]; //输现定形码
- P3 = bit_tab[i];
- for(j = 0; j < 100; j++);
-
-
- }
-
- }
- }
- void T0_time()interrupt 1
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- ++cnt;
- if((yea%4 == 0)&&(yea%100 != 0)||(yea%400 == 0))
- leap = 1; //判断为闰年
- else
- leap = 0; //不是闰年
- if(cnt >= 20)
- {
- update_time = 1; //置时间更新标志
- cnt = 0;
- ++sec;
- if(sec >= 60)
- {
- sec = 0;
- ++min;
- if(min >= 60)
- {
- min = 0;
- ++hou;
- if(hou >= 24)
- {
- hou = 0;
- day++;
- if((leap ==1)&&(mon == 2)&&(day >29 ))
- {
- mon++;
- day = 0;
- }
- else if((leap == 0)&&(mon == 2)&&(day > 28))
- {
- mon++;
- day = 0;
- }
- else if((mon == 1)||(mon == 3)||(mon == 5)||(mon == 7)||(mon == 8)||(mon == 10)||(mon == 12)&&(day > 31))
- {
- mon++;
- day = 0;
- }
- else if((mon == 2)||(mon == 4)||(mon == 6)||(mon == 9)||(mon == 11)&&(day > 30))
- {
- mon++;
- day = 0;
- }
- if(mon > 12)
- mon = 1;
- }
- }
- }
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
-数字钟24.rar
(78.96 KB, 下载次数: 29)
|