如果直接在主函数中写按键控制数码管0-99显示,不管怎么延时数码管十位上的数都会闪,原因就是单片机的机器周器太快,人的按键速度是ms级的,所以等你人操作完了,单片机早就执行了不知道多少遍。
解决方法就是用中断,这里采用定时器T0溢出中断,工作方式1, 2ms中断显示一次,这样的话既不影响按键操作,又不影响显示,一举两得。
以下程序是适用于德飞莱51单片机开发板
#include <reg52.h>
#define uchar unsigned char
#define DataPort P0
sbit Seg_Latch = P2^2; //段锁存
sbit Bit_Latch = P2^3; //位锁存
sbit key_up = P1^0; //数字增加按键
sbit key_down = P1^1; //数字减少按键
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //数码管显示0-9
uchar code tab[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f}; //数码管位选
uchar temp[2]; //存放num十位和个位
void Display(unsigned char FirstBit,unsigned char Num); //显示函数
void delay(uchar t) //延时
{
while(--t);
}
void DelayMs(uchar z) //ms级延时
{
while(z--)
{
delay(245);
delay(245);
}
}
void Time0_init() //定时器T0溢出中断初始化
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
EA = 1;
ET0 = 1;
TR0 = 1;
}
char num = 0; //0-99数字
uchar key_num = 0; //按键计数
void main()
{
Time0_init(); //T0中断初始化
key_up = 1; //使用前先拉高
key_down = 1;
while(1)
{
if(!key_up)
{
DelayMs(10);
if(!key_up)
{
while(!key_up)
{
key_num++;
DelayMs(10); //10x100 = 1s 按了1s
if(key_num == 100)
{
key_num = 0; //清零
while(!key_up)
{
if(num < 99)
{
num++;
}
temp[0] = table[num / 10];//及时赋值
temp[1] = table[num % 10];
DelayMs(50); //数字跳动快慢
}
}
}
key_num = 0; //防止累加造成错误识别
if(num < 99)
{
num++;
}
}
}
if(!key_down) //减操作
{
DelayMs(10);
if(!key_down)
{
while(!key_down)
{
key_num++;
DelayMs(10);
if(key_num == 100)
{
key_num = 0;
while(!key_down)
{
if(num > 0)
{
num--;
}
temp[0] = table[num / 10];
temp[1] = table[num % 10];
DelayMs(50);
}
}
}
key_num = 0;
if(num > 0 )
{
num--;
}
}
}
temp[0] = table[num / 10]; //用完赋值
temp[1] = table[num % 10];
}
}
void Display(unsigned char FirstBit,unsigned char Num) //显示
{
static unsigned char i = 0; //静态局部变量,用完后不释放
DataPort = 0;
Seg_Latch = 1;
Seg_Latch = 0;
DataPort = tab[i+FirstBit];
Bit_Latch=1;
Bit_Latch=0;
DataPort = temp[i];
Seg_Latch=1;
Seg_Latch=0;
i++;
if(i == Num)
{
i = 0;
}
}
void Time0_isr() interrupt 1
{
TH0 = (65536 - 2000) / 256; //取高八位 2ms
TL0 = (65536 - 2000) % 256; //取低八位
Display(0,2);
}