51单片机实践之数码管电子时钟/时间显示及其设置
以下源码在keil内可直接使用,注意板子的型号(AT89C52)即可。
代码如下:
/*
需求:两个独立按键分别控制加减(KEY2和KEY3),一个独立按键控制移位(KEY1),且在移动到该位置时该位置闪烁。
开发板:普中-A2
*/
#include <REGX52.H>
#define leds P0
typedef unsigned int uint;
typedef unsigned char uchar;//独立按键模块
sbit KEY1 = P3^1;
sbit KEY2 = P3^0;
sbit KEY3 = P3^2;
sbit KEY4 = P3^3;//0-F再加一个 - .数码管显示数字的数组
uchar leds_body [] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};uchar time[] = {6,3,16,0,4,16,1,2};//时间数组,每个数字和符号都占一个数码管uchar h = 0,m = 0,s = 0;//时分秒初始化
uint count = 0;//计数量
uchar set_pos = -1;//控制显示位置的变化
void caculate()//计算时分秒,将其每一位放到相应位置
{time[0] = s%10;time[1] = s/10;time[3] = m%10;time[4] = m/10;time[6] = h%10;time[7] = h/10;
}
void delay(uint xms) //@11.0592MHz,1ms 延迟:以1ms为单位
{unsigned char k, j;while(xms){k = 2;j = 199;do{while (--j);} while (--k);xms--;}
}
void dynamic_hms()//动态显示时分秒
{if(count==1000)//for循环决定这里得是8的倍数{count = 0;if(set_pos == -1)//只有位置不变化时,才进行时间流动{s++;if(s == 60){s = 0;m++;if(m == 60){m = 0;h++;if(h == 24){h = 0;}}}}}
}
void showtime()//控制时间显示在数码管上
{uchar i = 0;caculate();for(i=0;i<8;i++){P2 = i<<2;//控制数码管的显示位置if(count<500 && set_pos==i){leds = 0;//使得该位置的数码管闪烁,半秒内的每一轮都会处理该位置,使得该位置半秒不显示。}else{leds = leds_body [time[i]];//没有选中的位置内容每一次循环都会显示,半秒后,位置全部正常显示。}delay(1);//显示1mscount++;//动态显示时分秒的关键,在1ms后每次加上1,等差不多到1000ms后即为1秒}leds = 0;//消影
}void button_control()//控制移位
{if(KEY1 == 0){delay(50);//使频率稳定while(KEY1 == 0);//判断是否松开delay(50);//使得频率稳定set_pos++;//数码管进入闪烁阶段if(set_pos == 2)set_pos++;else if(set_pos == 5)set_pos++;else if(set_pos == 8)set_pos = -1;}if(KEY2 == 0)//控制数字加{delay(50);while(KEY2 == 0);delay(50);if(set_pos==0){s++;s = s % 60;caculate();}else if(set_pos==1){s = s + 10;s = s % 60;caculate();}else if(set_pos==3){m++;m = m % 60;caculate();}else if(set_pos==4){m = m + 10;m = m % 60;caculate();}else if(set_pos==6){h++;h = h % 24;caculate();}else if(set_pos==7){h = h + 10;h = h % 24;caculate();}}if(KEY3 == 0)//控制数字减{delay(50);while(KEY3 == 0);delay(50);if(set_pos==0){if(s>0){s--;}else{s = 0;}s = s % 60;//使s在[0,59]这个区间内,后面类似caculate();}else if(set_pos==1){if(s>10){s = s - 10;}else{s = 0;}s = s % 60;caculate();}else if(set_pos==3){if(m>0){m--;}else{m = 0;}m = m % 60;caculate();}else if(set_pos==4){if(m>10){m = m - 10;}else{m = 0;}m = m % 60;caculate();}else if(set_pos==6){if(h>0){h--;}else{h = 0;}h = h % 24;caculate();}else if(set_pos==7){if(h>10){h = h - 10;}else{h = 0;}h = h % 24;caculate();}}
}
void main()
{while(1){showtime();//展示时间dynamic_hms();//时间流动button_control();//按键控制}
}