分享一个基于51单片机的可调时钟小设计
模式键:按一次,进入倒计时设置模式(设置倒计时的时间,比如2min30s,5min40s等)
按两次,进入倒计时模式(开始倒计时)
按三次,进入钟表时间调节模式
按四次,回到正常显示模式(进入计时器/倒计时模式时不影响钟表正常走时)
配置键:按一次调整分
按两次调整时
按三次,回到调整分,依次循环
(配置键选择需要调整的单位,由加/减键进行加减调整)
加法键:数值加
减法键:数值减
红色数码管显示0时,为正常显示模式
红色数码管显示1时,为倒计时设置模式
红色数码管显示3时,为倒计时模式
在正常显示模式下,除模式键外其他按键都不可用
在钟表时间调节模式下,钟表不走时,其他任何模式都不影响钟表的正常走时
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- /*晶振12MHZ*/
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar code wela[6] = {0x20,0x10,0x08,0x04,0x02,0x01}; //位选码
- uchar code dula[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //段选码
- uchar buff[6] = {0,0,0,0,0,0};
- sbit P33 = P3^3;
- sbit P32 = P3^2;
- sbit P34 = P3^4;
- sbit P35 = P3^5;
- uchar hour,second,minute,hour_1,second_1,minute_1,hour_2,second_2,minute_2,t0,mode,reset,i;
- //无下划线的为时分秒辅助变量,下划线1的为时钟时分秒,下划线2的为倒计时时分秒
- void init(); //初始化函数
- void mode_0(void); //动态扫描函数
- void mode_1(void); //闪烁函数
- void time_1(void); //时钟函数(正计时)
- void time_2(void); //倒计时函数
- void oper_add(void); //加法键函数
- void oper_minus(void); //减法键函数
- void delay(uint z); //延时函数
- void main()
- {
- init();
- while(1)
- {
- if(mode==1)
- {
- second = second_2;
- minute = minute_2;
- hour = hour_2;
- oper_add(); //加法键函数
- oper_minus(); //减法键函数
- second_2 = second;
- minute_2 = minute;
- hour_2 = hour;
- }
- else if(mode==3)
- {
- second = second_1;
- minute = minute_1;
- hour = hour_1;
- oper_add();
- oper_minus();
- second_1 = second;
- minute_1 = minute;
- hour_1 = hour;
- }
- }
- }
- /*初始化函数*/
- void init()
- {
- TMOD = 0x01; //设置T0为方式一
- TH0 = 0x3c;
- TL0 = 0xb0;
- IE = 0x87;
- IT0 = IT1 = 0;
- IP = 0X02; //设置T0为高优先级
- TR0 = 1;
- t0 = 0;
- mode = 0;
- P1 = 0xc0;
- }
- /*模式键函数,外部中断0*/
- void X0_mode() interrupt 0
- {
- delay(10);
- if(P32 == 0)
- {
- mode++; //mode为模式标志位
- reset = 0; //reset为时分秒调节标志位
- switch(mode)
- {
- case 0 : P1 = 0xc0 ; break;
- case 1 : { P1 = 0xf9 ; hour_2 = second_2 = minute_2 = 0;} break;
- case 2 : P1 = 0xa4 ; break;
- case 3 : P1 = 0xb0 ; break;
- case 4 : { P1 = 0xc0 ; mode = 0;} break;
- default : break;
- }
- }
- while(P32 == 0);
-
- }
- /*配置键函数,外部中断1*/
- void X1_reset() interrupt 2
- {
- delay(10);
- if(P33 == 0)
- {
- if((mode==1) || (mode==3))
- {
- reset++; //时分秒调节标志位
- if(reset == 3)
- reset = 0;
- }
- }
- while(P33 == 0);
-
- }
- /*计时/动态扫描函数,内部中断0*/
- void T0_disp() interrupt 1
- {
- TH0 = 0xb1;
- TL0 = 0xe0; //b1e0(20ms)
- t0++;
- if(t0==50) //秒计数部分(正倒计时共用)
- {
- t0=0;
- if(mode != 3)
- time_1(); //除了调节钟表时间调节模式外,其他模式下执行正计时函数
- if(mode==2)
- time_2(); //进入倒计时模式时,执行倒计时函数(正计时不受干扰)
- }
- if((mode==1) || (mode==2)) //装载部分,将时分秒装载到数组buff,便于动态扫描。
- {
- buff[0]=second_2%10;
- buff[1]=second_2/10;
- buff[2]=minute_2%10;
- buff[3]=minute_2/10;
- buff[4]=hour_2%10;
- buff[5]=hour_2/10;
-
- }
- else
- {
- buff[0]=second_1%10;
- buff[1]=second_1/10;
- buff[2]=minute_1%10;
- buff[3]=minute_1/10;
- buff[4]=hour_1%10;
- buff[5]=hour_1/10;
- }
- switch(mode) //显示部分,包括动态扫描和闪烁函数
- {
- case 0 : mode_0() ; break;
- case 1 : mode_1() ; break;
- case 2 : mode_0() ; break;
- case 3 : mode_1() ; break;
- default : break;
- }
-
- }
- /*动态扫描函数*/
- void mode_0(void)
- {
- for(i=0;i<6;i++)
- {
- P2=wela[i];
- P0=dula[buff[i]];
- delay(1);
- }
- P2 = 0xe0;
- P0 = 0xbf;
- delay(1);
- }
- /*闪烁函数*/
- void mode_1(void) //实现0.5s亮灭闪烁
- {
- P2 = 0xc0;
- P0 = 0xbf;
- delay(1);
-
- if((reset==0) && (t0>24)) P2 = 0;
- else P2 = wela[0];
- P0 = dula[buff[0]];
- delay(1);
- if((reset==0) && (t0>24)) P2 = 0;
- else P2 = wela[1];
- P0 = dula[buff[1]];
- delay(1);
- if((reset==1) && (t0>24)) P2 = 0;
- else P2 = wela[2];
- P0 = dula[buff[2]];
- delay(1);
- if((reset==1) && (t0>24)) P2 = 0;
- else P2 = wela[3];
- P0 = dula[buff[3]];
- delay(1);
- if((reset==2) && (t0>24)) P2 = 0;
- else P2 = wela[4];
- P0 = dula[buff[4]];
- delay(1);
- if((reset==2) && (t0>24)) P2 = 0;
- else P2 = wela[5];
- P0 = dula[buff[5]];
- delay(1);
- }
- /*正计时函数*/
- void time_1(void)
- {
- second_1++;
- if(second_1==60)
- {
- second_1=0;
- minute_1++;
- if(minute_1==60)
- {
- minute_1=0;
- hour_1++;
- if(hour_1==24)
- hour_1=0;
- }
- }
- }
- /*倒计时函数*/
- void time_2(void)
- {
- second_2--;
- if(second_2==255)
- {
- second_2=59;
- minute_2--;
- if(minute_2==255)
- {
- minute_2=59;
- hour_2--;
- if(hour_2==255)
- hour_2=23;
- }
- }
- }
- /*加法键函数*/
- void oper_add(void)
- {
- if(P35 == 0)
- {
- delay(10);
- if(P35 == 0)
- {
- switch(reset)
- {
- case 0 :
- {
- second++;
- if(second > 59)
- second = 0;
- } break;
- case 1 :
- {
- minute++;
- if(minute > 59)
- minute = 0;
- } break;
- case 2 :
- {
- hour++;
- if(hour > 24)
- hour = 0;
- }
- default : break;
- }
- }
- while(P35 == 0);
- }
- }
- /*减法键函数*/
- void oper_minus(void)
- {
- if(P34 == 0)
- {
- delay(10);
- if(P34 == 0)
- {
- switch(reset)
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
clock.zip
(65.56 KB, 下载次数: 67)
|