问题
利用动态扫描和定时器1在数码管上显示出从765432开始以1/10秒的速度往下递减直至765398并保持显示此数,与此同时利用定时器0以500MS速度进行流水灯从上至下移动,当数码管上数减到停止时,实验板上流水灯也停止然后全部开始闪烁,3秒后(用T0定时)流水灯全部关闭、数码管上显示出“HELLO”
到此保持住。
什么是动态扫描
动态显示是多个数码管,交替显示,利用人的视觉暂停作用使人看到多个数码管同时显示的效果。就像我们看的电影是有一帧一帧的画面显示的,当速度够快的时候我们看到它就是动态的。当我们显示数码管的速度够快的时候,也就可以看到它们是同时显示了
动态数码管的程序
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
u8 code smgduan[16]= {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; //0~F数码
void delay(u16 i) //延时函数
{
while(i--);
}
void DigDisplay() //数码管显示函数
{
u8 i; for(i=0;i<8;i++)
{
switch(i)
{
case 0: LSC = 0;LSB = 0;LSA = 0;break; //显示第1个数码管
case 1: LSC = 0;LSB = 0;LSA = 1;
break; //显示第2个数码管
case 2: LSC = 0;LSB = 1;LSA = 0;break; //显示第3个数码管
case 3: LSC = 0;LSB = 1;LSA = 1;break; //显示第4个数码管
case 4: LSC = 1;LSB = 0;LSA = 0;break; //显示第5个数码管
case 5: LSC = 1;LSB = 0;LSA = 1;break; //显示第6个数码管
case 6: LSC = 1;LSB = 1;LSA = 0;break; //显示第7个数码管
case 7: LSC = 1;LSB = 1;LSA = 1;
break; //显示第8个数码管
}
P0 = smgduan[i+1];//显示1~8的数值 delay(100); //延时,造成视觉暂留现象
P0 = 0x00; //数码管消隐
}
}
void main()
{
while(1)
{ DigDisplay();
}
}
什么是定时器
工作原理
定时/计数器实质上是一个加1计数器。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值定时器
初值计算
1、计算出机器周期——每次定时计算器加1所用的时间。根据你要定时的时间去算初值:2、假设你要定时Xms,计时次数C:Xms/机器周期。用65536-C=初值。
{方式一}
TH0=初值/256;
TL0=初值%256。
定时器的设置
1、设置TMOD
2、计算出初值
3、启动定时计数器
4、设置中断程序 (在进入中断要重新设置定时器初值)
关于问题的程序
#include <reg52.h>
#include <intrains.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x76,0x79,0x38,0x3f,0};
void display(uchar aa,uchar bb,ucharcc,uchar bai,uchar shi,uchar ge);
uchar temp,t0,t1,bai,shi,ge,flag,flag1;
uint shu;
void init();
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void main()
{
init();
while(1)
{
if(flag1!=1)
display(7,6,5,bai,shi,ge);
else
display(16,17,18,18,19,20);
}
}
void init() //初始化函数
{
shu=432;
temp=0xfe;
P1=temp; //第一个发光二极管点亮
TMOD=0x11; //定时器的工作方式
TH0=(65536-50000)/256; //初值 高8位
TL0=(65536-50000)%256; // 低8位
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
ET1=1; //开定时器1中断 TR0=1; //启动定时器0
TR1=1; //启动定时器1
}
void timer0() interrupt 1 //定时器中断函数 定时器0的中断
{
TH0=(65536-50000)/256; TL0=(65536-50000)%256;
t0++;
if(flag!=1)
{
if(t0==10)
{
t0=1; temp=_cror_(temp,1);
P1=temp;
}
}
else
{ if(t0%4==0)
P1=^P1; if(t0==60)
{ TR0=0;
P1=0xff; }
}
}
void timer1() interrupt 3 //定时器中断函数 { TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
t1++;
if(t1==2)
{ t1=0; shu--;
bai=shu/100;
shi=shu%100/10;
ge=shu%10;
if(shu==398)
{
TR0=0; //控制流水灯的定时器0关闭 TH0=(65536-50000)/256; TL0=(65536-50000)%256;
TR0=1; flag=1; t0=0; P1=0xff;
//关闭所有流水灯
TR1=0; //控制减数的定时器1关闭 }
}
}
void display(uchar aa,uchar bb,uchar cc,uchar bai,uchar shi,uchar ge)
{
dula=1; P0=table[aa]; dula=0; P0=0xff; wela=1; P0=0xfe; wela=0; delay(1); dula=1; P0=table[bb]; dula=0; P0=0xff; wela=1; P0=0xfd; wela=0; delay(1); dula=1; P0=table[cc]; dula=0; P0=0xff; wela=1; P0=0xfb; wela=0; delay(1); dula=1; P0=table[bai]; dula=0; P0=0xff; wela=1; P0=0xf7; wela=0; delay(1); dula=1; P0=table[shi]; dula=0; P0=0xff; wela=1; P0=0xef; wela=0; delay(1); dula=1; P0=table[ge]; dula=0; P0=0xff; wela=1; P0=0xdf; wela=0; delay(1);
```mermaid
](https://img-blog.csdnimg
```mermaid
```mermaid

.cn/20210425225938780.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzU3