①开机为走时模式,正常显示时间。
②共设置3个按键,分别为模式键、功能键1、功能键2。按动模式键,模式将在“走时/调时/日期显示及调整/闹钟显示及调整”4个模式下切换。
③走时模式下按动功能键1/功能键2停止闹钟。
④调时模式下,功能键1上调时间,功能键2下调时间。
仿真原理图如下
单片机源程序如下:
#include #define uchar unsigned char uchar code tab[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; //共阳极数码管显示"0~9","灭"和"-"的字段码 //uchar code tab[]={0x3f,0x06,05b,0x4f,0x66,0x6d,07d,0x07,0x7f,0x6f,0x00,0x40};//共阴数码管 uchar code wetab[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位选 uchar data dis[8]={0x00,0x00,0x0b,0x00,0x00,0x0b,0x00,0x00}; //显示数据缓冲区,时十、个位、分十、个位、秒十、个位初始为0,0x0b为"-"编码 uchar data timedat[3]={0x00,0x00,0x00}; //分别为秒、分和小时的计数值(记录K1和K2次数) uchar data ms50=0x00, num=0x00, n1=0x00, n2=0x00; //定义定时次数变量,调整模式变量,按加1键次数变量,按减1键次数变量 sbit key0=P1^0 ; //调整键--模式 sbit key1=P1^1 ; //加1键 sbit key2=P1^2 ; //减1键 //--------------------------------------- void delay1ms( unsigned int z ) //定义延时1ms函数 { unsigned int x, y ; for ( x=z; x>0; x-- ) for ( y=120; y>0 ; y-- ) ; } //--------------------------------------- //按键处理函数。如果没有按键则时钟正常走时。当按K0键1次→暂停走时进入调小时状态;再按K0键1次→进入调分钟状态;再按K0键1次→回到正常走时状态。对于K1和K2键,如果正常走时下→按K1K2键不起作用;如果进入调时或者调分状态→按K1键可对时或分加1操作,小时加到24则回0,分钟加到60则回0。按K2键可对时或分减1操作,小时减到负则回23,分钟减到负则回59。 void keyscan( void ) { EA=0; //关中断 if(timedat[0]==0&timedat[1]==0&timedat[2]==7) {P1=0xff;} if (key0==0) { delay1ms(10); while (key0==0); num++; TR0=0; ET0=0; // 调整键K0每按1次--模式变量num加1 if (num>=3) {num=0; ET0=1; TR0=1; } // 启动T0校时 } if (num!=0) //模式变量不等于0 { if (key1==0) // K1键确实按下 { delay1ms(10); while (key1==0); timedat[num]++; //记录按键K1按下次数 if (num==2) n1=24; else n1=60; //模式变量等于小时2--则回迟到一天或60分钟 if (timedat[num]>=n1) { timedat[num]=0; } } } if (num!=0) { if (key2==0) { delay1ms(10); while (key2==0); timedat[num]--; //记录按键K2按下次数 if (num==2) n2=23;else n2=59; if (timedat[num]<=0) {timedat[num]=n2; } } } EA=1; } //--------------------------------------- //数码管显示函数。时间显示先秒个位计算显示→秒十位计算显示→再分个位计算显示→分十位显示→再时个位计算显示→时十位显示。 void display( void ) { uchar k; if(timedat[0]==0&timedat[1]==0&timedat[2]==7) {P1=0xff;} dis[0]=timedat[0]%10; dis[1]=timedat[0]/10; //秒 dis[3]=timedat[1]%10; dis[4]=timedat[1]/10; //分 dis[6]=timedat[2]%10; dis[7]=timedat[2]/10; //时 for ( k=0; k<8; k++ ) { P0=tab[ dis[k] ]; P2=wetab[k]; delay1ms(1); P2=0x00; } } //--------------------------------------- //主函数,时间显示先秒个位计算显示,然后是秒十位计算显示;再就是分个位计算显示,然后是分十位显示;再就是时个位计算显示,然后是时十位显示。定时器中断先检测1秒是否到→1秒如果到则秒单元加1;1秒如果没到就检测1分钟是否到→1分钟如果到则分单元加1;如果没到就检测1小时是否到→1小时如果到则时单元加1;如果没到→则显示时间。 void main( void ) { TMOD=0x01; //T0定时50ms,方式1 EA=1; ET0=1; TR0=1; //开中断,允许T0中断,启动T0 TH0=0x3c; TL0=0xb0; while (1) { display( ) ; keyscan( ) ; } } //定时器/计数器T0中断服务函数。定时器中断先检测1秒是否到→1秒如果到则秒单元加1;1秒如果没到就检测1分钟是否到→1分钟如果到则分单元加1;如果没到就检测1小时是否到→1小时如果到则时单元加1;如果没到→则显示时间。 void timer0(void) interrupt 1 { ET0=0; TR0=0; //不许T0中断也不启动 TH0=0x3c; TL0=0xb0; TR0=1; //启动T0 ms50++; P1=0xf7; if(timedat[0]==0&timedat[1]==0&timedat[2]==7) {P1=0xff;} if (ms50==20) { ms50=0x00; timedat[0]++; //变量m回0,且秒加1 if (timedat[0]==60) { timedat[0]=0;timedat[1]++; //秒到60后回0,且分加1 if (timedat[1]==60) { timedat[1]=0;timedat[2]++; //分到60后回0,且时加1 if (timedat[2]==24) { timedat[2]=0; } } } //时到24后回0 } ET0=1; //允许T0中断 }
上一篇:单片机DS18B20温度测控系统
下一篇:51单片机蜂鸣器播放小星星两只老虎欢乐颂
推荐阅读最新更新时间:2024-11-12 21:16
设计资源 培训 开发板 精华推荐
- ADA4610-1ARZ-RL 正峰值检波器运算放大器的典型应用电路
- 阿梓喵效果器
- 使用 Inphi Corporation 的 LXT914 的参考设计
- LTC1655LCS8、16 位轨至轨微功率 DAC 的典型应用,用于隔离式 4mA 至 20mA 过程控制器
- 当 LTC2380IDE-16 中启用数字增益压缩时,使用 LT6350 的典型应用被配置为接受 ±10V 输入信号,同时运行一个 5.5V 单电源
- 2串锂电池充放电保护板
- ADP8863DBCP-EVALZ,用于 7 通道趣味照明 LED 驱动器的评估板
- LTC3646HDE 5V、1A 同步降压转换器的典型应用电路
- 使用 ON Semiconductor 的 KA7809E 的参考设计
- LTC3805 隔离式演示板,电信 DC/DC 转换器 Vin= 18V 至 72V,Vout= 3.3V/3A