今天做了一道动态数码管显示与定时器控制的综合编程题,目的在于复习之前所学的动态数码显示和定时器中断控制原理。
题目:利用动态扫描和定时器1在数码管上显示出从765432开始以1/10秒的速度往下递减直至765398并保持显示此数,与此同时利用定时器0以500MS速度进行流水灯从上至下移动,当数码管上数减到停止时,实验板上流水灯也停止然后全部开始闪烁,3秒后(用T0定时)流水灯全部关闭、数码管上显示出“HELLO”。到此保持住。
思路:1.在定时器0中断里设置好流水灯程序;
2.在定时器1中设计好算数递减(765432递减到765398)程序;
3.根据定时器1条件终止定时器0、1;
4.根据题干设标记flag、flag1,分别标记流水灯流动开始到结束,流水灯全部闪烁到结束。
程序如下:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned long
void init();
void delay(uint a);
void display(uint num);
void display1();
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x89,0x86,0xc7,0xc7,0xc0};//共阳
uchar code table_w[]={0x01,0x02,0x04,0x08,0x10,0x20};
uint num=765432;
uchar j=0;
uchar flag=0;
uchar flag1=0;
uchar temp=0xfe;
sbit LE=P3^5;
uchar tt=0;
uchar t0=0;
void main()
{
init();
j=0;
while(1)
{
if(flag1!=1)
{
display(num);
}
else
{
display1();
}
}
}
void delay(uint a)
{
uint i,j;
for(i=a;i>0;i--)
for(j=20;j>0;j--);
}
void display(uint num)
{
uchar i=0;
//uchar bai,shi,ge;
P2=table_w[j]; //段选开关,负责给当前led灯加高电平(共阳极)
//i=(i+1)%8;765432
switch(j)
{
case 0:i=num/100000;break;
case 1:i=num%100000/10000;break;
case 2:i=num%10000/1000;break;
case 3:i=num%1000/100;break;
case 4:i=num%100/10;break;
case 5:i=num%10;break;
default:break;
}
LE=1; //段选加锁存器
P0=table[i];//位选开关,负责给led灯显示数字
LE=0;
j=j+1;
if(6==j)
{
j=0;
}
delay(1);//5ms
}
void display1()
{
uchar i=0;
//uchar bai,shi,ge;
P2=table_w[j]; //段选开关,负责给当前led灯加高电平(共阳极)
//i=(i+1)%8;765432
switch(j)
{
case 0:i=10;break;
case 1:i=11;break;
case 2:i=12;break;
case 3:i=13;break;
case 4:i=14;break;
default:break;
}
LE=1; //段选加锁存器
P0=table[i];//位选开关,负责给led灯显示数字
LE=0;
j=j+1;
if(5==j)
{
j=0;
}
delay(1);
}
void init()
{
//设置定时器50ms中断一次,中断后,需将TH0、TL0置0
TH0=(65536-50000)/256; //高8位50ms产生溢出
TL0=(65536-50000)%256; //低8位50ms产生溢出
//设置定时器50ms中断一次,中断后,需将TH0、TL0置0
TH1=(65536-50000)/256; //高8位50ms产生溢出
TL1=(65536-50000)%256; //低8位50ms产生溢出
//设置中断工作方式为模式1(16位自加器)
TMOD=0x11; //time0、time1
EA=1; //开总中断控制开关
ET0=1; //开定时器控制中断开关
ET1=1; //开定时器控制中断开关
//TR1=1; //设置定时器1开启
TR0=1;
TR1=1;
}
void timer0()interrupt 1
{
if(flag!=1)
{
if(10==t0)
{
t0=0;
P1=temp;
temp=_crol_(temp,1);
}
}
else
{
if(t0%4==0)
P1=~P1;
if(t0==60)
{
TR0=0;
P1=0xff;
flag1=1;
}
}
t0++;
//将TH0、TH1置0
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}
void timer1()interrupt 3
{
if(2==tt)
{
tt=0;
if(765398==num)
{
//将TH0、TH1置0
tt=0;
flag=1;
P1=0xff;
TR0=0;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR1=0;
TR0=1;
}
else
{
num--;
}
}
tt++;
//将TH0、TH1置0
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
}
//备注:实际应用时段选位选都需加锁存器,否则容易跳乱码
/*
duan=1;
P0=table_d[i];
duan=0;
wei=1;
P1=table_w[j];
wei=0;
*/