数码管动态显示的51单片机时钟设计
- 格式:doc
- 大小:17.50 KB
- 文档页数:3
一看就会,适合初学者参考
T0,T1同时开中断,和别人的有点不一样
源程序如下
//数码管设计的可调电子钟
//K1,K2分别调整小时和分钟
#include<>
#include<>
#define uchar unsigned char
#define uint unsigned int
uchar code DSY_CODE[]={0xC0,0xF9,0xA4,0xB0,0x99, //共阳段码
0x92,0x82,0xF8,0x80,0x90,0xFF}; uchar DSY_BUFFER[]={0,0,0xBF,0,0,0xBF,0,0}; //显示缓存uchar Scan_BIT; //扫描位,选择要显示的数码管
uchar DSY_IDX; //显示缓存索引
uchar Key_State; //P1端口按键状态
uchar h,m,s,s100; //十分秒,1/100s
void DelayMS(uchar x) //延时
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
void Increase_Hour() //小时处理函数
{
if(++h>23)h=0;
DSY_BUFFER[0]=DSY_CODE[h/10];
DSY_BUFFER[1]=DSY_CODE[h%10];
}
void Increase_Minute()//分钟处理函数
{
if(++m>59)
{
m=0;Increase_Hour();
}
DSY_BUFFER[3]=DSY_CODE[m/10];
DSY_BUFFER[4]=DSY_CODE[m%10];
}
void Increase_Second() //秒处理函数
{
if((++s>59))
{
s=0;Increase_Minute();
}
DSY_BUFFER[6]=DSY_CODE[s/10];
DSY_BUFFER[7]=DSY_CODE[s%10];
}
void T0_INT() interrupt 1 //T0中断动态扫描数码管显示
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
P2=Scan_BIT; //选通相应数码管
P0=~DSY_BUFFER[DSY_IDX]; //段码送p0进行取反,共阴共阳转换 Scan_BIT=_crol_(Scan_BIT,1);//准别下次选通的数码管
DSY_IDX=(DSY_IDX+1)%8; //索引0-7内循环
}
void T1_INT() interrupt 3 //T1中断控制时钟运行
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
if(++s100==20) //50ms*20=1s延时
{
s100=0;Increase_Second();
}
}
void main() //主程序
{
P0=P3=0xFF;
TMOD=0x11; //T0,T1工作模式1
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
TH1=0xDC;
TL1=0;
TCON=0x01;
EA=1; //开中断
ET0=1;
ET1=1;
h=0;
m=s=s100=0;
//将时分秒段码放入显存
DSY_BUFFER[0]=DSY_CODE[h/10];
DSY_BUFFER[1]=DSY_CODE[h%10];
DSY_BUFFER[3]=DSY_CODE[m/10];
DSY_BUFFER[4]=DSY_CODE[m%10];
DSY_BUFFER[6]=DSY_CODE[s/10];
DSY_BUFFER[7]=DSY_CODE[s%10];
Scan_BIT=0xFE;
DSY_IDX=0;
TR0=TR1=1; //启动两个定时器
Key_State=0xFF;
while(1)
{
if(P1^Key_State)
{
DelayMS(10);
if(P1^Key_State)
{
Key_State=P1;EA=0;
if((Key_State&0x01)==0)Increase_Hour(); //K1 +小时 else if((Key_State&0x02)==0) //K2 + 分钟 {
m=(m+1)%60;
DSY_BUFFER[3]=DSY_CODE[m/10];
DSY_BUFFER[4]=DSY_CODE[m%10];
}
EA=1;
}
}
}
}