设计要求:
基本任务:
用单片机和数码管设计可调式电子钟,采用24小时制计时方式,要求能够稳定准确计时,并能调整时间。发光二极管每秒亮灭一次。电子钟显示格式为:时、分、秒各两位,中间有分隔符,格式为xx-xx-xx,共8位。采用三个按键调整时间,具体任务如下:
- 发光二极管每秒钟亮灭一次(亮500ms,灭500ms)。
- 上电自动显示初始时间 12-00-00。
- 实现时钟走时和显示时、分、秒。
- 当第一次按下第一个按键时进入时间调节状态,实现对显示时间的分钟调节,按下第二个按键时实现分钟的加1调节,按下第三个按键时实现分钟的减1调节。
- 当第二次按下第一个按键时进入显示时间的小时调节状态,按下第二个按键时实现小时的加1调节,按下第三个按键时实现小时的减1调节。
当第三次按下第一个按键时数字时钟恢复正常时间显示。
内容及步骤:
一、电路原理图
二、源代码(包括注释)
#include<reg51.h>
#define uChar unsigned char
#define uInt unsigned int
uChar a[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //单个数码管字模
uChar b[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //选通数码管位数
uChar second=00,minute=00,hour=12,count; //赋初始值
sbit one = P3^0; // 调节位
sbit two = P3^1; //加一位
sbit three = P3^2; //减一位
sbit four= P3^3; //暂停位
sbit five= P1^0; //LED状态位
void Delay(unsigned int t) //时间延时函数
{
int i,x;
for(i=1;i<=x;x++);
while(t)
{
t--;
}
}
void Dispaly1(uChar second,uChar minute,uChar hour) //数码管显示函数
{
P2=b[0]; //小时的显示
P0=a[hour/10]; //小时的十位显示
Delay(10);
P2=b[1];
P0=a[hour%10]; //小时的个位显示
Delay(10);
P2=b[2]; //--显示
P0=0x40;
Delay(10);
P2=b[3]; //分钟显示
P0=a[minute/10];
Delay(10);
P2=b[4];
P0=a[minute%10];
Delay(10);
P2=b[5];
P0=0x40;
Delay(10);
P2=b[6]; //秒钟显示
P0=a[second/10];
Delay(10);
P2=b[7];;
P0=a[second%10];
Delay(10);
}
void Keyscan1() //调节函数
{
static uChar i=0,j=0; //定义初始值,以I,J分别实现暂停和调节功能 i是暂停位次数,j是调节标志位
if(four==0) //暂停键按下
{
while(!four);
i++;
}
if(i%2==1)
{
TR0=0; //关中断 停止计时
}
if(i%2==0)
{
TR0=1; //开中断
}
if(one==0){ //当按下第一个键位
while(!one);
j++;
}
if(j%3==1) //j+1使进入到分钟的调节
{
if(two==0)
{
while(!two);
minute++;
if(minute==60) //判断进位
minute=0;
}
if(three==0)
{
while(!three);
if(minute==0) //判断退位标志
minute=60;
minute--;
}
}
if(j%3==2) //进入到小时的调节
{
if(two==0)
{
while(!two);
hour++;
if(hour==24)
hour=0;
}
if(three==0)
{
while(!three);
hour--;
if(hour==0)
hour=24;
}
}
}
void main() //主函数
{ void delay(int);
int time = 50;
TMOD=0x01; //TO定时方式一
TH0=(65536-10000)/256; //高位值 定义10ms
TL0=(65536-10000)%256; //低位值
EA=1; //开总中断
ET0=1; //开TO中断
TR0=1; //启动TO
while(1)
{
static uChar h=0;
five=!five;
delay(time);
Dispaly1(second,minute,hour); //函数初始化
Keyscan1(); //函数初始化
}
}
void time0_int(void) interrupt 1 //中断函数 循环进位
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
count++;
if(count==100) // 一秒
{
count=0;
second++;
if(second==60) //一分钟
{
second=0;
minute++;
if(minute==60) //一小时
{
minute=0;
hour++;
if(hour==24) //24小时
{
hour=0;
}
}
}
}
}
三、流程图
四、仿真运行结果及分析
初始值状态:
第一次按下K1并按下一次K2(分加)
第一次按下K1并按下两次K3(分减)
第二次按下K1并按下一次K2(时加)
第二次按下K1并按下两次K3(时减)
第三次按下K1(恢复正常计时)