在郭天祥的那本书中,有一个通过按键控制数码管的例子,在运行这个例子的时候,我发现当按键按下的时候,第一位数码管会熄掉,这是为什么呢?
后来在网上找到了原因,当我按下按键不松开的时候,接下来要运行的代码会阻塞,因为多位数码管是动态扫描显示的,所以就会发生上述问题。
修改后的代码如下(未验证)
#include "mylib.h"
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
/**
* Global Value
*/
sbit key1 = P3 ^ 4; //increase the number
sbit key2 = P3 ^ 5; //decrease the number
sbit key3 = P3 ^ 6; //start
sbit key4 = P3 ^ 7; //clear
uchar key1Flag = 0;
uchar key2Flag = 0;
uchar key3Flag = 0;
uchar key4Flag = 0;
sbit dula = P2 ^ 6;
sbit wula = P2 ^ 7;
uchar numt0, num;
uchar pressed = 0;
void Init();
void ScanKey();
void Display(uchar numdis);
void main()
{
Init();
while (1)
{
ScanKey();
Display(num);
}
}
void Init()
{
TMOD = 0x01; //set the counter mode
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256;
EA = 1;
ET0 = 1;
}
void ScanKey()
{
if (key1 == 0)
{
Delay(10);
if ((key1 == 0))
{
key1Flag = 1;
}
}
else if (key1 == 1)
{
if (key1Flag == 1)
{
key1Flag = 0;
num++;
if (num == 60)
{
num = 0;
}
}
}
if (key2 == 0)
{
Delay(10);
if ((key2 == 0))
{
key2Flag = 1;
}
}
else if (key2 == 1)
{
if (key2Flag == 1)
{
key2Flag = 0;
if (num == 0)
{
num = 60;
}
num--;
}
}
if (key3 == 0)
{
Delay(10);
if ((key3 == 0) && (pressed == 0))
{
pressed = 1;
num = 0;
}
}
else
{
if (pressed == 1)
{
pressed = 0;
}
}
if (key4 == 0)
{
Delay(10);
if ((key4 == 0) && (pressed == 0))
{
pressed = 1;
TR0 = ~TR0;
}
}
else
{
if (pressed == 1)
{
pressed = 0;
}
}
}
void Display(uchar numdis)
{
uchar tens, ones;
tens = numdis / 10;
ones = numdis % 10;
dula = 1;
P0 = digCode[tens];
dula = 0;
P0 = 0xff;
wula = 1;
P0 = 0xef;
wula = 0;
Delay(4);
dula = 1;
P0 = digCode[ones];
dula = 0;
P0 = 0xff;
wula = 1;
P0 = 0xdf;
wula = 0;
Delay(4);
}
void T0_time() interrupt 1
{
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256;
numt0++;
if (numt0 == 20)
{
numt0 = 0;
num++;
if (num == 60)
{
num = 0;
}
}
}
原谅我没加上注释,毕竟这段代码还是不够完美。
解决方案详解
当第一次扫描到按键按下的信号,延时10ms(去抖),再次判断信号是否存在,如果存在,设置该按键的被按下的旗帜为1。在没有检测到按键按下的信号的时候,判断该按键的被按下的旗帜是否为1,如果是的话,执行按键的功能,否则,继续检测下一个按键
仍然存在的问题
第一位的数码管在按键按下的时候会变暗
推测的原因
扫描函数又臭又长,可能导致第一位数码管的扫描显示间隔比较大