51单片机实践之数码管电子时钟/时间呈现及其设置
以下源码在keil内可直接使用,注意板子的型号(AT89C52)即可。
代码如下:
/*
需求:两个独立按键分别控制加减(KEY2和KEY3),一个独立按键控制移位(KEY1),且在移动到该位置时该位置闪烁。
开发板:普中-A2
*/
#include
#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);//显示1ms
count++;//动态显示时分秒的关键,在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();//按键控制
}
}