微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 多位数加减数码管显示,用定时器消除闪烁问题

多位数加减数码管显示,用定时器消除闪烁问题

时间: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;
}
求大侠解决,我都在这里卡了几个小时了

你是需要 按键调整显示值 数码管不闪烁对吧  用定时器可以做到啊 你把按键扫描放在定时器里面  

处理按键的时候,关闭定时器
把定时器时间修改的小一些

可以用状态机的思想写数码管,按键处理时互不影响

我之前做过数码管的动态扫描显示,调节显示速度,同时在下次变化显示前消隐,可以去掉闪烁问题的

路过学习一下

看小编的程序,小编的思路不对,还停留在延时的思想中。定时器中断里面还有延时函数。
我们知道数码管是不断扫描现实动态显示。每隔一段时间亮一个数码管。不断扫描实现多个数码管同时显示的效果。如果我们要用定时器中断。那么每次进中断就是点亮下一个数码管。下面这个就是我改的中断程序。每次进入中断就是点亮一个数码管。下次进入中断就点亮下一个数码管。例外提示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个数码管。

  1. void display(uchar i)
  2. {
  3.   P0=0;//清空数据,防止交替重影
  4.   dula=1;
  5.   dula=0;
  6.   
  7.   P0=wema[i+fisbit];
  8.   wela=1;
  9.   wela=0;

  10.   P0=tempdata[i];
  11.   dula=1;
  12.   dula=0;
  13. }

复制代码


定时器中断的时间不能设置太大或太小,太大出现闪烁,太小中断占用CPU的时间比例太高。

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

网站地图

Top