多位数加减数码管显示,用定时器消除闪烁问题
时间:10-02
整理:3721RD
点击:
while(!key_dec);
delay_ms(10);
while(!key_dec);
if(num>0)
num--;
else
num=999;
}
}
if(num>999)
tempdata[3]=duma[num/1000];
else
tempdata[3]=0;
if(num>99)
tempdata[2]=duma[num%1000/100];
else
tempdata[2]=0;
if(num>9)
tempdata[1]=duma[num%1000%100/10];
else
tempdata[1]=0;
tempdata[0]=duma[num%1000%100%10];
display(0,3);
}
}
/*------------------------------------------------
显示函数,用于动态扫描数码管
输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三
个数码管开始显示
如输入0表示从第一个显示。
Num表示需要显示的位数,如需要显示99两位数值则该值输入2
------------------------------------------------*/
void display(uchar fisbit,uchar num)
{
static uchar i;
for(i=0;i<num;i++)
{
P0=0;//清空数据,防止交替重影
dula=1;
dula=0;
P0=wema[i+fisbit];
wela=1;
wela=0;
P0=tempdata;
dula=1;
dula=0;
delay_ms(2);
}
}
void delay_us2x(uchar t)
{
while(t--);
}
void delay_ms(uchar t)
{
while(t--)
{
delay_us2x(245);
delay_us2x(245);
}
}
void init()
{
key_add=1;
key_dec=1;
}
这个按键盘可以实现数码管显示加减,不过有闪烁,下面这个程序是想通过定时器消除数码管闪烁,可是按键盘数码管不变化,一直显示0
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key_add=P3^3;
sbit key_dec=P3^4;
sbit dula=P2^6;
sbit wela=P2^7;
uchar code duma[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar code wema[]={
0x7f,0xbf,0xdf,0xef,0xf7,
0xfb,0xfd,0xfe};
uchar tempdata[8];
void display(uchar fisbit,uchar num);
void delay_us2x(uchar t);
void delay_ms(uchar t);
void init();
void init_timer0();
void main()
{
uint num=0;
init();
init_timer0();
while(1)
{
if(!key_add)
{
delay_ms(10);
if(!key_add)
{
while(!key_add);
//delay_ms(10);
//while(!key_add);
num++;
if(num==1000)
num=0;
}
}
if(!key_dec)
{
delay_ms(10);
if(!key_dec)
{
while(!key_dec);
//delay_ms(10);
//while(!key_dec);
if(num>0)
num--;
else
num=999;
}
}
if(num>999)
tempdata[3]=duma[num/1000];
else
tempdata[3]=0;
if(num>99)
tempdata[2]=duma[num%1000/100];
else
tempdata[2]=0;
if(num>9)
tempdata[1]=duma[num%1000%100/10];
else
tempdata[1]=0;
tempdata[0]=duma[num%1000%100%10];
//display(0,8);
}
}
void display(uchar fisbit,uchar num)
{
static uchar i;
for(i=0;i<num;i++)
{
P0=0;//清空数据,防止交替重影
dula=1;
dula=0;
P0=wema[i+fisbit];
wela=1;
wela=0;
P0=tempdata;
dula=1;
dula=0;
delay_ms(1);
}
}
void delay_us2x(uchar t)
{
while(t--);
}
void delay_ms(uchar t)
{
while(t--)
{
delay_us2x(245);
delay_us2x(245);
}
}
void init_timer0()
{
TMOD|=0x01;
TH0=(65536-2000)/256; // 2ms
TL0=(65536-2000)%256;
EA=1;
ET0=1;
TR0=1;
}
void timer0() interrupt 1
{
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
display(0,8);
}
void init()
{
key_add=1;
key_dec=1;
}
求大侠解决,我都在这里卡了几个小时了
定时器中断的时间不能设置太大或太小,太大出现闪烁,太小中断占用CPU的时间比例太高。
delay_ms(10);
while(!key_dec);
if(num>0)
num--;
else
num=999;
}
}
if(num>999)
tempdata[3]=duma[num/1000];
else
tempdata[3]=0;
if(num>99)
tempdata[2]=duma[num%1000/100];
else
tempdata[2]=0;
if(num>9)
tempdata[1]=duma[num%1000%100/10];
else
tempdata[1]=0;
tempdata[0]=duma[num%1000%100%10];
display(0,3);
}
}
/*------------------------------------------------
显示函数,用于动态扫描数码管
输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三
个数码管开始显示
如输入0表示从第一个显示。
Num表示需要显示的位数,如需要显示99两位数值则该值输入2
------------------------------------------------*/
void display(uchar fisbit,uchar num)
{
static uchar i;
for(i=0;i<num;i++)
{
P0=0;//清空数据,防止交替重影
dula=1;
dula=0;
P0=wema[i+fisbit];
wela=1;
wela=0;
P0=tempdata;
dula=1;
dula=0;
delay_ms(2);
}
}
void delay_us2x(uchar t)
{
while(t--);
}
void delay_ms(uchar t)
{
while(t--)
{
delay_us2x(245);
delay_us2x(245);
}
}
void init()
{
key_add=1;
key_dec=1;
}
这个按键盘可以实现数码管显示加减,不过有闪烁,下面这个程序是想通过定时器消除数码管闪烁,可是按键盘数码管不变化,一直显示0
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key_add=P3^3;
sbit key_dec=P3^4;
sbit dula=P2^6;
sbit wela=P2^7;
uchar code duma[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar code wema[]={
0x7f,0xbf,0xdf,0xef,0xf7,
0xfb,0xfd,0xfe};
uchar tempdata[8];
void display(uchar fisbit,uchar num);
void delay_us2x(uchar t);
void delay_ms(uchar t);
void init();
void init_timer0();
void main()
{
uint num=0;
init();
init_timer0();
while(1)
{
if(!key_add)
{
delay_ms(10);
if(!key_add)
{
while(!key_add);
//delay_ms(10);
//while(!key_add);
num++;
if(num==1000)
num=0;
}
}
if(!key_dec)
{
delay_ms(10);
if(!key_dec)
{
while(!key_dec);
//delay_ms(10);
//while(!key_dec);
if(num>0)
num--;
else
num=999;
}
}
if(num>999)
tempdata[3]=duma[num/1000];
else
tempdata[3]=0;
if(num>99)
tempdata[2]=duma[num%1000/100];
else
tempdata[2]=0;
if(num>9)
tempdata[1]=duma[num%1000%100/10];
else
tempdata[1]=0;
tempdata[0]=duma[num%1000%100%10];
//display(0,8);
}
}
void display(uchar fisbit,uchar num)
{
static uchar i;
for(i=0;i<num;i++)
{
P0=0;//清空数据,防止交替重影
dula=1;
dula=0;
P0=wema[i+fisbit];
wela=1;
wela=0;
P0=tempdata;
dula=1;
dula=0;
delay_ms(1);
}
}
void delay_us2x(uchar t)
{
while(t--);
}
void delay_ms(uchar t)
{
while(t--)
{
delay_us2x(245);
delay_us2x(245);
}
}
void init_timer0()
{
TMOD|=0x01;
TH0=(65536-2000)/256; // 2ms
TL0=(65536-2000)%256;
EA=1;
ET0=1;
TR0=1;
}
void timer0() interrupt 1
{
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
display(0,8);
}
void init()
{
key_add=1;
key_dec=1;
}
求大侠解决,我都在这里卡了几个小时了
你是需要 按键调整显示值 数码管不闪烁对吧 用定时器可以做到啊 你把按键扫描放在定时器里面
处理按键的时候,关闭定时器
把定时器时间修改的小一些
可以用状态机的思想写数码管,按键处理时互不影响
我之前做过数码管的动态扫描显示,调节显示速度,同时在下次变化显示前消隐,可以去掉闪烁问题的
路过学习一下
看小编的程序,小编的思路不对,还停留在延时的思想中。定时器中断里面还有延时函数。
我们知道数码管是不断扫描现实动态显示。每隔一段时间亮一个数码管。不断扫描实现多个数码管同时显示的效果。如果我们要用定时器中断。那么每次进中断就是点亮下一个数码管。下面这个就是我改的中断程序。每次进入中断就是点亮一个数码管。下次进入中断就点亮下一个数码管。例外提示Num要设置成全局变量不能在中断函数里面定义成局部变量。否则每次进入中断Num的值都是初始值。
void timer0() interrupt 1
{
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
display(Num);
Num ++;
if(Num == 8) Num =0;
}
下面这个就是数码管显示函数。display(uchar i)就是点亮第i个数码管。
- void display(uchar i)
- {
- P0=0;//清空数据,防止交替重影
- dula=1;
- dula=0;
-
- P0=wema[i+fisbit];
- wela=1;
- wela=0;
- P0=tempdata[i];
- dula=1;
- dula=0;
- }
定时器中断的时间不能设置太大或太小,太大出现闪烁,太小中断占用CPU的时间比例太高。
