单片机/MCU论坛
直播中

84151341

10年用户 7经验值
擅长:控制/MCU
私信 关注

新手求助:数码管显示时候闪烁,找不到是什么原因,求高手们解析

写了一个4位数码管记数的小程序,每过1秒数码管记数1,一直累加下去。烧录之后发现,记数是对了,前面三位一直在闪,最后一位显示正常。在百度上也搜了相关的情况,但就是找不到问题所在。希望高手们不吝赐教。谢了,跪谢
下面是代码:


/*********************************************************************************
*实验名称:四位数码管计数器
*控制思路:使用定时器0不带中断控制数码管每秒加1
*实验效果:每过一秒,数码管累加1
*
*********************************************************************************/
#include
#define uint unsigned int
#define uchar unsigned char
***it DU = P2 ^ 6;
***it WE = P2 ^ 7;
uchar code smgd[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                  0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

uchar buff[]={0xff,0xff,0xff,0xff};


void delay(uint xms)
{
   uint i,j;
   for(i=xms;i>0;i--)
   for(j=112;j>0;j--);
}

void main()
{
   uint cnt = 0;
   uchar a = 0;
   uchar x = 1;
   uint sec = 0;
   TMOD = 0x01;
   TH0 = (65536-50000)/256;
   TL0 = (65536-50000)%256;
   TR0 = 1;

   while(1)
{
    if(TF0 == 1)
    {
       TF0 = 0;
       cnt++;
       TH0 = (65536-50000)/256;
       TL0 = (65536-50000)%256;
       if(cnt == 20)
       {
          cnt = 0;
          sec++;
          buff[0]=smgd[sec%10];
          buff[1]=smgd[sec/10%10];
          buff[2]=smgd[sec/100%10];
          buff[3]=smgd[sec/10000%10];
      }
      if(a==0)
      {
         a++;
         P0 = 0xff;
         WE = 1;
         WE = 0;
         P0 = buff[3];
         DU = 1;
         DU = 0;
         P0 = 0xef;
         WE = 1;
         WE = 0;
         delay(x);
       }

       if(a==1)
       {
          a++;
          P0 = 0xff;
          WE = 1;
          WE = 0;
          P0 = buff[2];
          DU = 1;
          DU = 0;
          P0 = 0xcf;
          WE = 1;
          WE = 0;
          delay(x);
       }

       if(a==2)
       {
           a++;
           P0 = 0xff;
           WE = 1;
           WE = 0;
           P0 = buff[1];
           DU = 1;
           DU = 0;
           P0 = 0xbf;
           WE = 1;
           WE = 0;
           delay(x);
      }

      if(a==3)
      {
         a = 0;
         P0 = 0xff;
         WE = 1;
         WE = 0;
         P0 = buff[0];
         DU = 1;
         DU = 0;
         P0 = 0x7f;
         WE = 1;
         WE = 0;
         delay(x);
       }

  }
}
}

回帖(10)

84151341

2017-7-3 18:19:23
对了,我是希望用定时器0来定时1s,但是不开中断。不知道是不是没有中断后,main函数与定时器0同时运行才产生的问题?
举报

84151341

2017-7-3 18:19:25
对了,我是希望用定时器0来定时1s,但是不开中断。不知道是不是没有中断后,main函数与定时器0同时运行才产生的问题?
举报

人中狼

2017-7-3 19:05:19
按你现在的定时数据算是50毫秒刷新一个数码管显示,时间太长了,缩短这个时间试试
举报

84151341

2017-7-3 19:18:37
首先,感谢你对我的问题做了回答,谢谢!

你说的50ms是说               
TH0 = (65536-50000)/256;
TL0 = (65536-50000)%256;
这两句里面定时时间50ms其实是刷新数码管的时间吗?
我写时候,那个delay()是刷新数码管的,参数是2ms。
我按照你说的,把 TH0 = (65536-50000)/256改成了 TH0 = (65536-5000)/256(5万改成了5千,就是每次计时5ms)
也还是一样的效果,数码管还在闪
举报

人中狼

2017-7-3 21:39:12
这里有几个问题:
一,你这里的delay(),不算是刷新延时,只是相邻两个数码管交替显示的间隔时间,因为你的所有程序都是在if(TF0 == 1)的条件下才执行,所以刷新时间是定时器的溢出时间。
二,定时器是执行加一操作直到溢出为0才产生中断,所以(65536-X)是计算定时起始值到溢出之间的数值,这个数值越小,代表定时时间越短。
三,最好是在定时器溢出时只显示一个数码管,等下次溢出时再显示下一个数码管,这样只有一个时间需要调整,容易做一些,象你现在的做法,实际上是有两个时间,一个是定时器,一个是delay(),两个时间的协调会比较麻烦
举报

84151341

2017-7-3 22:24:28
谢谢你耐心的教导。我理解了大概8成你说的,我自己再研究研究,这样弄懂了印象深刻一点。谢谢了!
举报

武林

2017-7-4 10:29:54
多位数码管动态显示程序要掌握几个要点:
1.显示1轮的周期不大于15ms,不小于1ms,否则大于15ms会闪烁,小于1ms会暗淡并产生鬼影。每一位的显示时间1~3ms为宜。
2.各位显示时间应相同,否则各位亮度不均匀。
3.显示过程不能被其他程序干扰,会产生闪烁。避免使用软件延时delay占用MCU时间,会影响其他程序运行。
总而言之,用中断法或时间片轮询法处理多位数码管动态显示效果较好。
举报

wuguangqi1024

2017-7-4 23:30:05
WE = 1;
         WE = 0;
         P0 = buff[3];
         DU = 1;
         DU = 0;
         P0 = 0xef;
         WE = 1;
         WE = 0;
         delay(x);
P0数显已经关闭,你又把IO口P2.7又是1又是0的,不是多此一举吗。另外,这代码也太烂了
举报

jf_20646311

2020-10-20 01:42:52
把j定义成unsigned char就好了
举报

jf_20646311

2020-10-20 01:47:28
别问我为啥知道,把j的类型定义为unsigned char就不会闪烁了,我找这个问题找了一天,最后发现问题在这里,50000那个时间要看你的振晶频率,11.0592的用46080,如果是12Mhz的就用50000
举报

更多回帖

发帖
×
20
完善资料,
赚取积分