//用定时器0的方式1实现第一个发光管以200ms间隔闪烁;
//用定时器1的方式1实现数码管前两位59s循环计时。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6; //申明U1锁存器锁存端
sbit wela=P2^7; //申明U2锁存器锁存端
sbit led1=P1^0;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delayms(uint);
void display(uchar,uchar);
uchar num, num1, num2,shi,ge;
//主函数,设置定时器工作方式,装初值,打开哪些中断的开关,让它一直在while那里等着就好了!调用一个display函数,其实就是给2个数码管赋值的过程。
void main()
{
TMOD=0x11; //设置定时器0和1为工作方式1(0001 0001)
TH0=(65536-45872)/256; //装初值
TL0=(65536-45872)%256;
TH1=(65536-45872)/256;
TL1=(65536-45872)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
ET1=1; //开定时器1中断
TR0=1; //启动定时器0
TR1=1; //启动定时器1
while(1) //程序在这里不停地对数码管动态扫描,等待中断发生
{
display(shi,ge);
}
}
void display(uchar shi, uchar ge)
//显示函数:所谓的显示函数,其实就是给前两位一个数值让数码管显示,极快间隔让人看着以为给他们分别赋值。流程是打开第一个位选,赋值shi,打开第二个位选,赋值ge。这样的一个流程定义为显示函数。
{
dula=1;
P0=table[shi];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delayms(5);
dula=1;
P0=table[ge];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delayms(5);
}
void delayms(unit xms) //延迟函数
{
uint i,j;
for (i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void T0_time() interrupt 1
//中断函数1:用定时器0的方式1实现第一个发光管以200ms间隔闪烁; num1以50ms递增,当num1 4次也就是200ms后,亮灯方式取反,num1置零。
{
TH0=(65536-45872)/256; //装初值
TL0=(65536-45872)%256;
num1++;
if(num1 == 4)
{
num1=0;
led1=~led1;
}
}
void T1_time() interrupt 3
//中断函数2: 用定时器1的方式1实现数码管前两位59s循环计时。num2是50ms为单位的计时器,num2累计20次为1s。 num2够1s后num2清0,num按照1s每次加一,当num够60了清零,num不够60的话进行shi ge的取模赋值。
{
TH1=(65536-45872)/256;
TL1=(65536-45872)%256;
num2++;
if (num2 == 20)
{
num2=0;
num++;
if(num == 60)
num=0;
shi = num/10;
ge = num%10;
}
}