微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 《手把手教你学51单片机-C语言》之六 中断与数码管动态显示

《手把手教你学51单片机-C语言》之六 中断与数码管动态显示

时间:11-19 来源:互联网 点击:

我们用switch语句完成的情况。

#include

sbitADDR0=P1^0;

sbitADDR1=P1^1;

sbitADDR2=P1^2;

sbitADDR3=P1^3;

sbitENLED=P1^4;

unsignedcharcodeLedChar[]={//数码管显示字符转换表

0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,

0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E

};

unsignedcharLedBuff[6]={//数码管显示缓冲区,初值0xFF确保启动时都不亮

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF

};

voidmain()

{

unsignedchari=0;//动态扫描的索引

unsignedintcnt=0;//记录T0中断次数

unsignedlongsec=0;//记录经过的秒数

ENLED=0;//使能U3,选择控制数码管

ADDR3=1;//因为需要动态改变ADDR0-2的值,所以不需要再初始化了

TMOD=0x01;//设置T0为模式1

TH0=0xFC;//为T0赋初值0xFC67,定时1ms

TL0=0x67;

TR0=1;//启动T0

while(1)

{

if(TF0==1)//判断T0是否溢出

{

TF0=0;//T0溢出后,清零中断标志

TH0=0xFC;//并重新赋初值

TL0=0x67;

cnt++;//计数值自加1

if(cnt>=1000)//判断T0溢出是否达到1000次

{

cnt=0;//达到1000次后计数值清零

sec++;//秒计数自加1

//以下代码将sec按十进制位从低到高依次提取并转为数码管显示字符

LedBuff[0]=LedChar[sec%10];

LedBuff[1]=LedChar[sec/10%10];

LedBuff[2]=LedChar[sec/100%10];

LedBuff[3]=LedChar[sec/1000%10];

LedBuff[4]=LedChar[sec/10000%10];

LedBuff[5]=LedChar[sec/100000%10];

}

//以下代码完成数码管动态扫描刷新

switch(i)

{

case0:ADDR2=0;ADDR1=0;ADDR0=0;i++;P0=LedBuff[0];break;

case1:ADDR2=0;ADDR1=0;ADDR0=1;i++;P0=LedBuff[1];break;

case2:ADDR2=0;ADDR1=1;ADDR0=0;i++;P0=LedBuff[2];break;

case3:ADDR2=0;ADDR1=1;ADDR0=1;i++;P0=LedBuff[3];break;

case4:ADDR2=1;ADDR1=0;ADDR0=0;i++;P0=LedBuff[4];break;

case5:ADDR2=1;ADDR1=0;ADDR0=1;i=0;P0=LedBuff[5];break;

default:break;

}

}

}

}

程序完成的功能是一模一样的,但大家看一下,switch语句是不是比if...else语句显得要整齐清爽呢。

1.4.2数码管显示消隐

不知道同学们是否发现了,我们的这两个数码管动态显示程序的运行效果似乎并不是那么完美,第一个小问题,大家仔细看,数码管的不应该亮的段,似乎有微微的发亮,这种现象叫做“鬼影”,这个“鬼影”严重影响了我们的视觉效果,我们该如何解决呢?

同学们在今后可能会遇到各种各样的实际问题,可能很多都是我们没有讲过的,遇到问题怎么办呢?大家要相信,你作为初学者,遇到的问题肯定不是第一个遇到的,肯定有前辈已经遇到过相同的或类似的问题,他们一般都会在网上发表各种帖子,各种讨论,所以大家遇到问题,首先就应该形成一个到网上搜索的条件反射,这个问题大家可以到网上搜:“数码管消隐”或者“数码管鬼影解决”,多找相关关键词搜索试试,会搜索也是一种能力。

大家在网上搜了一下会发现,解决这类问题的方法有两个,其中之一是延时,延时之后我们肉眼就可能看不到这个“鬼影”了。但是延时是一个非常拙劣的手段,且不说延时多久能让我们看不到“鬼影”,延时后,我们的数码管亮度会普遍降低。我们解决问题呢,不能只知其然,还要知其所以然,那么我们首先就来弄明白为什么会出现“鬼影”。

“鬼影”的出现,主要是在数码管位选和段选产生的瞬态造成的。举个简单例子,我们在数码管动态显示的那部分程序中,实际上每一个数码管点亮的持续时间是1ms的时间,1ms后进行下个数码管的切换。在进行数码管切换的时候,比如我们从case5要切换到case0的时候,case5的位选用的是ADDR0=1;ADDR1=0;ADDR2=1;假如此刻case5也就是最高位数码管对应的值是0,我们要切换成的case0的数码管位选是ADDR0=0;ADDR1=0;ADDR2=0;而对应的数码管的值假如是1。又因为C语言程序是一句一句顺序往下执行的,每一条语句的执行都会占用一定的时间,即使这个时间非常非常短暂。但是当我们把“ADDR0=1”改变成“ADDR0=0”的时候,这个瞬间存在了一个中间状态ADDR0=0;ADDR1=0;ADDR2=1;在这个瞬间上,我们就给case4对应的数码管DS5瞬间赋值了0。当我们全部写完了ADDR0=0;ADDR1=0;ADDR2=0;后,这个时候,我们的P0还没有正式赋值,而P0此刻却保持了前一次的值,也就是在这个瞬间,我们又给case0对应的数码管DS1赋值了一个0。直到我们把case0后边的语句全部完成后,我们的刷新才正式完成。而在这个刷新过程中,有2个瞬间我们给错误的数码管赋了值,虽然很弱(因为亮的时间很短),但是我们还是能够发现。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top