用51单片机设计了一个简单的倒计时器,但数码管有点小问题,请教高手

#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};
uchar data1[]={5,9}; //保存倒计时初始值
sbit a=P1^0; //设置键
sbit b=P1^1; //增一键
sbit c=P1^2; // 减一键
sbit d=P1^3; // 确定键
sbit e=P3^0; //控制LED发光
sbit f=P3^2;
void keyscan();
void display();
void delayms(uint t)
{
uint a,b;
for(a=t;a>0;a--)
for(b=125;b>0;b--);
}
void display() //数码管显示函数
{
uchar i;
P2=0X01;
for(i=0;i<2;i++)
{

P0=table[data1[i]];
P2=~(P2<<i);
delayms(2);
P2=~P2;
}

while(!(data1[1]||data1[0])) //当倒计时到0时点亮LED,停止计时
{

TR0=0;
e=0;
f=0;
P2=0XFC;
P0=0X3F;
}

}

void main()
{
// delayms(1);
TMOD=0x01;
ET0=1;
EA=1;
TH0=0X3C;
TL0=0XB0;
TR0=1;

while(1)
{
keyscan();
display();

}
}

void timer0() interrupt 1 using 0
{
uchar count;
count++;
if(count==20)
{
count=0;
data1[1]--;
if(data1[1]==-1)
{
data1[1]=9;
data1[0]--;

}
}
else
TH0=0X3C;
TL0=0XB0;
}

void keyscan()
{
uchar num;
if(a==0)
{
delayms(10);
if(a==0)
{
TR0=0;
num++;

}
}
while(a==0);//松手检测
if(num==1)
{
if(b==0)
{
delayms(5);
if(b==0)
{
while(!b)
{
display();
}
data1[1]++;
if(data1[1]==10)
{

data1[1]=0;
data1[0]++;
if(data1[0]==6)
data1[0]=1;
}
}
}
if(c==0)
{
delayms(10);
if(c==0)
{
while(!c);
data1[1]--;
if(data1[1]==255)
{
data1[1]=9;
data1[0]--;
}
}

}
}

if(d==0)
{
TR0=1;
num=0;
}

}
当每次按下按键时,左侧数码管都会抖动一次,如何改程序能克服抖动,电路图如下,如果必要的话可以改电路图

试试看:
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[] = {
0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F};
uchar data1[]={5, 9}; //保存倒计时初始值
uchar num; //设为全局变量
uchar count;

sbit a = P1^0; //设置键
sbit b = P1^1; //增一键
sbit c = P1^2; //减一键
sbit d = P1^3; //确定键

sbit e = P3^0; //控制LED发光
sbit f = P3^2;

void delayms(uint t)
{
uint a, b;
for(a = t; a > 0; a--) for(b = 125; b > 0; b--);
}
void display() //数码管显示函数.
{
uchar i;
for(i = 0; i < 2; i++) {
P0 = table[data1[i]];
P2 = ~(i + 1);
delayms(2);
P2 = 255;
}
while(!(data1[1] || data1[0])) { //当倒计时到0时点亮LED,停止计时.
TR0 = 0;
e = 0;
f = 0;
P2 = 0xFC;
P0 = 0x3F;
}
}

void keyscan()
{
if(a == 0) {
display();
if(a == 0) {
TR0 = 0;
num++;
}
}
while(!a) display();//松手检测.

if(num >= 1) {
if(b == 0) {
display();
if(b == 0) {
while(!b) display();
data1[1]++;
if(data1[1] == 10) {
data1[1] = 0;
data1[0]++;
if(data1[0] == 6) data1[0] = 1;
}
}
}

if(c == 0) {
display();
if(c == 0) {
while(!c) display();
data1[1]--;
if(data1[1] == 255) {
data1[1] = 9;
data1[0]--;
}
}
}
}
if(d == 0) {TR0 = 1; num = 0;}
}

void main()
{
TMOD = 0x01;
TH0 = 0x3C;
TL0 = 0xB0;
TR0 = 1;
ET0 = 1;
EA = 1;
while(1) {
keyscan();
display();
}
}

void timer0() interrupt 1
{
TH0 = 0x3C;
TL0 = 0xB0;
count++;
if(count == 20) {
count = 0;
data1[1]--;
if(data1[1] == -1) {
data1[1] = 9;
data1[0]--;
}
}
}
温馨提示:内容为网友见解,仅供参考
第1个回答  2011-10-28
把数码管显示的刷新程序放在中断中,不就OK了。
这就相当于多任务系统,又开了个线程。

51单片机数码管倒计时!自己写的程序但输入后怎么都亮!#include<reg52...
首先指出程序中明显的问题:1.数字只能显示1~8,下面修改后显示0~9;当然这个不是问题;2.主要问题:混淆了两位数码管动态显示的时间逻辑;显示的数字变化没有单独设置时间,以至于数字变化和数码管的短时间动态显示混淆了。也就是数码管动态显示是根据人眼视觉效应原理,快速改变点亮第一个和点亮第二个数...

如何用单片机做一个简单的倒计时器
delay(300); \/\/动态扫描数码管延时 P0=gewei;P2=1;delay(300);} } void tim(void) interrupt 1 using 1 \/\/定时器0中断 { static uchar second=99,count; \/\/99只是一个数,可以任意改,因为这里只学习怎样实现倒计时 TH0=0xd8; \/\/定时10毫秒 TL0=0xf0;count++;if(count==1...

求大神。。51单片机的【倒计时+密码锁】没办法解锁。。
这你就钻牛角尖了!解锁何必中断,在倒计时过程中放一句按键检测,有键按下则调用你的解锁子程序,解锁成功关闭定时器不就行了。

我想用51单片机做一个篮球计时器24秒倒计时,用数码管显示,求各位高手帮 ...
define uchar unsigned char uchar display_code[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};uchar display_data[8]={0,0,0,0,0,0,0,0};uchar time[]={0,0,0};void delay(void){ uchar i;for(i=250;i>0;i--);} void...

51单片机 数码管实现九秒倒计时的程序
主程序可以这样写:a=9;while(a>0){ P0=table[a];delayms(1000);a--;}

51单片机两个阳极数码管显示24倒计时怎么显示00
1、基于51单片机共阴两位数码管显示倒计时#includeunsigned char s=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f;unsigned char count,d1,d2,g,y;signed int time=10; void delay(unsigned char i);void sm()d1=time\/10;d2=time%10;P1=sd1;P3=0x00;delay(2);P3=0x01;P1...

想用51单片机编个倒计时的c程序,要求用两位数码管显示分钟的,并用一...
你这数码管的1、2口就这么悬着或者接dp一起了真的没问题吗……全局变量2个用于表示个位和十位,显示的时候可以省点力不用每次计算个位十位。然后一个全局变量代表秒 编程的话,首先是按键响应中断,控制某个全局变量flag的值,三种状态:正常、暂停、到时间。按键可以在前两种之间切换,如果已经是第...

51单片机数码管的问题
每个器件有12个脚,数码管的七段ABCDEFG+DP,也叫8段,DP是小数点,这是8个脚,4位数码管有4个共公端,所以,8+4=12个脚。图中一共是8位数码管了,有电阻的引脚就是8段,两块的相同的引脚即都是A的相连,都是B的相连,以此类推。在左边的导线上加有网络标号ABCDEFGH,H就是小数点DP。...

51单片机数码管倒计时程序,从999999开始倒计时,用定时器T1的中断...
这个和代码顺序有关系:while (1) { if (flag1s == 1) \/\/判断1秒定时标志 { flag1s = 0; \/\/1秒定时标志清零 sec--; \/\/秒计数自减1【这里是先减一,后面再送显示】 \/\/将sec按十进制位从低到高依次提取到buf数组中 buf[0] = sec%10; buf[1] = ...

51单片机试题,写一个用单个数码管显示10秒倒计时的程序,急!!!
void Timer0Init(void)\/\/1毫秒@12.000MHz { TMOD &= 0xF0;\/\/设置定时器模式 TMOD |= 0x01;\/\/设置定时器模式 TL0 = 0x18;\/\/设置定时初值 TH0 = 0xFC;\/\/设置定时初值 TF0 = 0;\/\/清除TF0标志 TR0 = 1;\/\/定时器0开始计时 } void main(){ Timer0Init()ET0=1; \/\/开启定时器0...

相似回答