当前位置:文档之家› 模拟时钟电路的程序

模拟时钟电路的程序

//单片机实验模板文件。

具有三个基本功能:
// 1、数码管、发光二极管扫描显示
// 2、键盘扫描,返回0---15
// 3、T0中断,产生基本延时2.5ms,并且调用显示函数
// 根据以上功能,该文件为进一步编写实验程序、实际应用程序,提供了基础
#include <reg52.h>
#define delay5ms(x) {delay_xms=x*2; while(delay_xms<255);} //用于延时的宏,x的1个数值对应延时5ms。

x<=127。

void display(void);
unsigned char code
ledcode[]={0x3f,6,0x5b,0x4f,0x66,0x6d,0x7d,7,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0};
//共阴极7段数码管显示段码
//unsigned char xdata dis_seg _at_ 0xfeff; //输出数码管段显示码地址
//unsigned char xdata dis_bit _at_ 0xfdff; //输出数码管位控制码地址unsigned char min,sec,hour;
unsigned char bdata dis_buf[7]; //dis_buf[0]为最高位数据(显示在左边),dis_buf[5]为最低位数据;dis_buf[6]为8个发光二极管的数据。

unsigned char data delay_xms; //用于延时
sfr IPH = 0xb7; //定义中断优先级(高2级)寄存器
//******************************************************************
void int_t0(void) interrupt 1 //T0中断函数,fosc按11.0592M计算,定时时间为2.5ms {
TH0=0xf7;
delay_xms--;
display(); //调用显示函数
}
//******************************************************************
void display(void) //数码管显示函数。

左边是最高位,从左边开始扫描,函数每执行1次仅扫描1位,每2.5ms扫描一位
{
static unsigned char data i=0, scan=0xfe;
P0=0;
if(i<6)
P0=ledcode[dis_buf[i]];
else
P0=dis_buf[i];
P2=scan;
scan=scan*2+1;
i++;
if(i>6)
scan=0xfe, i=0;
}
//******************************************************************
unsigned char key(void) //有键按下返回0---15,无键按下返回0xff {
unsigned char data i, j, dd, scan, kk=0xff;
P1=0xf0; //查询是否有键按下
dd=P1;
if(dd==0xf0)
return kk;
delay5ms(3); //延时15ms去抖动
P1=0xf0;
dd=P1;
if(dd==0xf0)
return kk;
scan=0xfe; //行扫描码
for(i=0;i<4;i++) //循环做行扫描
{ P1=scan; //使某一行为低扫描
dd=P1; //读P1口的值
dd/=16; //取P1口值的高4位
if(dd!=0xf) //dd!=0xf表明该行有键按下
{ for(j=0;j<4;j++)
{ if(dd%2==0) //dd%2==0表明查询的第j列有键按下{ kk=i*4+j; //计算被按下键的键值
break;
}
dd=dd/2;
}
break;
}
scan=scan*2+1;
}
while(1) //等待按键释放
{ P1=0xf0;
dd=P1;
if(dd==0xf0)
break; //无键按下跳出循环}
delay5ms(3); //延时15ms去抖动
return kk;
}
//******************************************************************
void timer1() interrupt 3
{
static unsigned char count=0;
TL1=0x12;
TH1=0x2c;
count++; //正常计时
if(count>19) // 定时1S 到,以下为时钟的正常走钟逻辑
{
count=0;
sec++;
if(sec>= 60)
{ sec=0;
min++;
if(min>59)
{ min=0; hour++;
if(hour>23)
hour=0;
dis_buf[0]=hour/10; //可以随便修改
dis_buf[1]=hour%10;
}
dis_buf[2]=min/10;
dis_buf[3]= min%10;
}
dis_buf[4]=sec/10;
dis_buf[5]=sec%10;
}
}
void main() //主函数
{
unsigned char i;
TMOD=0x11; //根据情况可以修改
TL0=0; //T0定时2.5ms的初值. 不要修改TH0=0xf7; //T0定时2.5ms的初值. 不要修改TL1=0X12;
TH1=0x2c;
IE=0x82; //根据情况可以修改
IPH=0x02; //T2的优先级,为2级. 不要修改TR0=1;
TR1=1;
ET1=1;
while(1)
{ i=key();
switch (i)
{
case 0:if(hour<23)
hour++;
else hour=0;
dis_buf[0]=hour/10; //可以随便修改
dis_buf[1]=hour%10;
break ;
case 1:if(min<59)
min++;
else min=0;
dis_buf[2]= min/10;
dis_buf[3]= min%10;
break;
case 2:if(sec<59)
sec++;
else sec=0;
dis_buf[4]=sec/10;
dis_buf[5]=sec%10;
break;
default:break;
} } }。

相关主题