源码 3 -- 电子时钟(独立按键、8 位数码管、定时器)
注:由于使用了中断以及各种延时程序,此程序并不是真正准确的“电子时钟”,想要真正准确,需要特别的外部模块,如时钟芯片 DS1302。
附上源码:(初出茅庐,难免有写的不好的地方,仅作备份之用,欢迎指点,喷子退散……)
/**********************************************************************************
电子时钟
1、初始从 00-00-00 时刻开始显示
2、按 Pause 键暂停,此时可以通过三个按键调节时间
3、再按 Pause 键恢复工作
缺陷:
1、按键过程中,有瞬间闪烁
2、再次按 Pause 开始时,会等待一会儿,电子时钟才会工作
***********************************************************************************/
#include
#defineDATA P1// 数码管数据传输口
sbitSEG = P0^0;// 段码输入
sbitBIT = P0^2;// 位码输入
sbitKEY_PAUSE = P2^0;// 暂停 / 开始 按键
sbitKEY_H_UP = P2^2;// 小时调节 按键
sbitKEY_M_UP = P2^4;// 分钟调节 按键
sbitKEY_S_UP = P2^6;// 秒调节 按键
unsigned char codeSEG_CODE[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40};
unsigned char codeBIT_CODE[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
// 上面是段码表,0-9,还有一个 “-” 符号
// 下面是位码表,指示哪一位显示字符
unsigned chartimer0_count;// 定时器 50ms 一个中断,计 20 次为 1s
unsigned charH1, H0, M1, M0, S1, S0;// 电子时钟显示数字 HH-MM-SS
voidDelay(unsigned intt);// 普通延迟函数
voidDelay_ms(unsigned intt);// ms 延迟函数
voidInit_Key(void);// 初始化按键
voidInit_Clock(void);// 初始化电子时钟显示
voidInit_Timer0(void);// 初始化定时器
voidDisplay(unsigned charx,unsigned charnum);// 在 x 位置,显示数字 num
voidDisplay_Clock(void);// 显示电子时钟
voidmain (void)
{
Init_Key();
Init_Clock();
Init_Timer0();
while(1) {
Display_Clock();// 在大循环中显示时钟,形成动态扫描
if(timer0_count == 20) {// 定时器中断了 20 次,即 1s,开始对显示进行处理
timer0_count = 0;
S0 += 1;
if(S0 == 10) {// 以下保证了秒:0-59,分钟:0-59,小时:0-23
S0 = 0;
S1 += 1;
}
if(S1 == 6) {
S1 = 0;
M0 +=1;
}
if(M0 == 10) {
M0 = 0;
M1 += 1;
}
if(M1 == 6) {
M1 = 0;
H0 += 1;
}
if(H0 == 10 && (H1 == 0 || H1 == 1)) {
H0 = 0;
H1 += 1;
}
else if(H0 == 4 && H1 == 2) {
H0 = 0;
H1 = 0;
}
}
if(!KEY_PAUSE) { // 检测 暂停键 是否按下
Delay_ms(10);// 延迟 10ms,消除按键抖动,后边同理
if(!KEY_PAUSE) {// 在延迟之后,还能检测到按键,说明真的是按键
while(!KEY_PAUSE) Display_Clock();// 如果按住按键不放,就保持时钟显示状态
while(KEY_PAUSE) {// 按键终于放开了,处理按键的行为
Display_Clock();// 在此期间,要保持时钟一直动态显示
if(!KEY_H_UP) { // 在暂停期间,检测到了 小时调节 操作,处理显示
Delay_ms(10);
if(!KEY_H_UP) {
while(!KEY_H_UP) Display_Clock();
H0 += 1;
if(H0 == 10 && (H1 == 0 || H1 == 1)) {
H0 = 0;
H1 += 1;
}
else if(H0 == 4 && H1 == 2) {
H0 = 0;
H1 = 0;
}
}
}
if(!KEY_M_UP) {// 在暂停期间,检测到了 分钟调节 操作,处理显示
Delay_ms(10);
if(!KEY_M_UP) {
while(!KEY_M_UP) Display_Clock();
M0 += 1;
if(M0 == 10) {
M0 = 0;
M1 += 1;
}
if(M1 == 6) M1 = 0;
}
}
if(!KEY_S_UP) {// 在暂停期间,检测到了 秒调节 操作,处理显示
Delay_ms(10);
if(!KEY_S_UP) {
while(!KEY_S_UP) Display_Clock();
S0 += 1;
if(S0 == 10) {
S0 = 0;
S1 += 1;
}
if(S1 == 6) S1 = 0;
}
}
}
if(!KEY_PAUSE) {// 再次按下 暂停 按键,恢复工作
Delay_ms(10);
if(!KEY_PAUSE) {
while(!KEY_PAUSE) Display_Clock();
}
}
}
}
}
}
voidDelay(unsigned intt)
{
while(t--);
}
voidDelay_ms(unsigned intt)// 根据测试,可以相当近似的表示 1ms
{
while(t--) {
Delay(245);
Delay(245);
}
}
voidInit_Key(void)
{
KEY_PAUSE = 1;// 赋值高电平为 按键断开 状态
KEY_H_UP = 1;
KEY_M_UP = 1;
KEY_S_UP = 1;
}
voidInit_Clock(void)// 初始时钟显示为 00-00-00
{
H1 = 0;
H0 = 0;
M1 = 0;
M0 = 0;
S1 = 0;
S0 = 0;
}
voidInit_Timer0(void)
{
TMOD = 0x01;// 使用定时器 0,模式 1
EA = 1;// 开总中断
ET0 = 1;// 开定时器 0 中断
TH0 = (65536-50000)/256;// 定时器 0 赋值,定时 50ms
TL0 = (65536-50000)%256;
TR0 = 1;// 定时器 0 开始工作
C51电子时钟独立按键数码管定时 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)