找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2981|回复: 26
收起左侧

51单片机定时器刷新数码管显示鬼影,求解决

  [复制链接]
ID:389488 发表于 2020-9-22 11:51 | 显示全部楼层 |阅读模式
基于郭天祥开发板
#include <STC89C5xRC.H>
#include <intrins.h>

#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long

//sbit ir=P3^2;

sbit ledw=P2^6;
sbit ledd=P2^7;

#define ledduan P0

u8 code ledma []={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
0x7c,0x58,0x5e,0x79,0x71,0x80,0xff,0x00};//共阴 0-f . 全显全灭

u8 code ledwma []={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//共阴

u8 i,j;
u32 a;

void delay(u16 z)
{
         u16 x;
         u8 y;
        for(x=z;x>0;x--)
        for(y=120;y>0;y--);
}

void timerInit ()
{
        TMOD|=0x01;
        TH0=(65536-3000)/256;  //50MS
        TL0=(65536-3000)%256;
        //TH1=(65536-46080)/256;  //3MS
        //TL1=(65536-46080)%256;
        ET0=1;
        //ET1=1;
        EA=1;
        TR0=1;
//        TR1=1;
}
/*
void timer0init ()
{
        TMOD|=0x01;
        TH0=(65536-46080)/256;
        TL0=(65536-46080)%256;
        ET0=1;
        EA=1;
        TR0=1;
}

void display(u32 a)
{
        u8 aa,bb,cc,dd,ee,ff;
        aa=a/100000;
  bb=a%100000/10000;
  cc=a%10000/1000;
        dd=a%1000/100;
        ee=a%100/10;
        ff=a%10;
        
                ledd=1;
          ledduan=ledwma [0];
          ledd=0;
        
                 ledw=1;
                ledduan=ledma[aa];
                ledw=0;
        
                delay(5);
        
          ledd=1;
          ledduan=ledwma [1];
          ledd=0;
        
                 ledw=1;
                ledduan=ledma[bb];
                ledw=0;
        
                delay(5);
               
                ledd=1;
          ledduan=ledwma [2];
          ledd=0;
        
                 ledw=1;
                ledduan=ledma[cc];
                ledw=0;
        
                delay(5);
               
                ledd=1;
          ledduan=ledwma [3];
          ledd=0;
        
                 ledw=1;
                ledduan=ledma[dd];
                ledw=0;
        
                delay(5);
               
                ledd=1;
          ledduan=ledwma [4];
          ledd=0;
        
                 ledw=1;
                ledduan=ledma[ee];
                ledw=0;
        
                delay(5);
               
                ledd=1;
          ledduan=ledwma [5];
          ledd=0;
        
                 ledw=1;
                ledduan=ledma[ff];
                ledw=0;
        
                delay(5);
}
*/

void main()
{
        u8 aa,bb,cc,dd,ee,ff;
        a=333333;
        
        aa=a/100000;
  bb=a%100000/10000;
  cc=a%10000/1000;
        dd=a%1000/100;
        ee=a%100/10;
        ff=a%10;
        
        timerInit ();
        
        while(1)
  {
                ledduan=0x00;
        switch(j)
        {
                case 0:
                //        ledduan=0x00;
                        ledd=1;
                        ledduan=ledwma [j];
                        ledd=0;
        //ledduan=0x00;
                        ledw=1;
                        ledduan=ledma[aa];
                        ledw=0;
                //ledduan=0x00;
                        break;
                case 1:
        //ledduan=0x00;
                        ledd=1;
                        ledduan=ledwma [j];
                        ledd=0;
        //ledduan=0x00;
                        ledw=1;
                        ledduan=ledma[bb];
                        ledw=0;
        //ledduan=0x00;
                break;
               
                case 2:
                //        ledduan=0x00;
                ledd=1;
          ledduan=ledwma [j];
          ledd=0;
        //ledduan=0x00;
                 ledw=1;
                ledduan=ledma[cc];
                ledw=0;
        //ledduan=0x00;
                break;
                case 3:
                //        ledduan=0x00;
                ledd=1;
          ledduan=ledwma [3];
          ledd=0;
        //ledduan=0x00;
                 ledw=1;
                ledduan=ledma[dd];
                ledw=0;
        //ledduan=0x00;
                break;
                case 4:
                //        ledduan=0x00;
                ledd=1;
          ledduan=ledwma [4];
          ledd=0;
        //ledduan=0x00;
                 ledw=1;
                ledduan=ledma[ee];
                ledw=0;
        //ledduan=0x00;
                break;
                case 5:
                        //ledduan=0x00;
                ledd=1;
          ledduan=ledwma [5];
          ledd=0;
        //ledduan=0x00;
                 ledw=1;
                ledduan=ledma[ff];
                ledw=0;
        //ledduan=0x00;
                break;
          /*if(i>=20)
                {
                        i=0;
                        cnt++;
    }*/
                //display(123456);
                //delay(3000);*
   }
}
}
void timer0isr() interrupt 1
{
        TH0=(65536-3000)/256;
        TL0=(65536-3000)%256;
        j++;
        if(j>=6)
        {
                j=0;
  }
}
/*
void timer1isr() interrupt 3
{
        TH1=(65536-46080)/256;
        TL1=(65536-46080)%256;
        i++;
}*/

回复

使用道具 举报

ID:821845 发表于 2020-9-22 13:04 | 显示全部楼层
你这个是什么的代码
回复

使用道具 举报

ID:332444 发表于 2020-9-22 13:44 | 显示全部楼层
通常数码管都使用2块锁存器,我买的板子数码管就是,只要使用了锁存器这种电路通常需要写消隐才能很好解决问题,一般的做法是先打开位,再打开段显示一点时间就消隐。
回复

使用道具 举报

ID:332444 发表于 2020-9-22 13:50 | 显示全部楼层
回复

使用道具 举报

ID:821872 发表于 2020-9-22 14:47 | 显示全部楼层
延迟部分写太复杂了,鬼影就是延迟部分没做好,人眼看的时候出现视觉效果,改下延迟时间试一试。
回复

使用道具 举报

ID:389488 发表于 2020-9-22 15:29 | 显示全部楼层
13424291824 发表于 2020-9-22 14:47
延迟部分写太复杂了,鬼影就是延迟部分没做好,人眼看的时候出现视觉效果,改下延迟时间试一试。

用延时没问题 我已经注释掉了 用定时器动态显示就不行了鬼影也去不掉
回复

使用道具 举报

ID:389488 发表于 2020-9-22 15:32 | 显示全部楼层
xianfajushi 发表于 2020-9-22 13:44
通常数码管都使用2块锁存器,我买的板子数码管就是,只要使用了锁存器这种电路通常需要写消隐才能很好解决 ...

是这样的,你说的非常对。但是我用延时动态显示的问题已经解决 现在已经把延时注释掉了,不用延时用定时器动态显示就是不行,鬼影严重。位选前面后面加了0x00也不行。
回复

使用道具 举报

ID:332444 发表于 2020-9-22 15:40 | 显示全部楼层
段需要消隐,位无需消隐。数码管显示不要放在定时器里面,我的做法是不用定时器延时,也不用嵌套循环的延时,直接使用char n=0;while(!++n);这样,不知道明白了?若还不能解决我写个参考给你。
回复

使用道具 举报

ID:807182 发表于 2020-9-22 16:17 | 显示全部楼层
共阳极共阴极也需要注意,】
回复

使用道具 举报

ID:89515 发表于 2020-9-22 17:03 来自手机 | 显示全部楼层
定时器18ms扫描一位?6位九帧没问题吗?思考一下为何要消影。明白了就很简单了。
回复

使用道具 举报

ID:750420 发表于 2020-9-22 20:36 | 显示全部楼层
仿真还是实物,反正的话注意看下是否报告菜谱、
回复

使用道具 举报

ID:750420 发表于 2020-9-22 20:38 | 显示全部楼层
仿真还是实物,仿真注意下cpu的负载,是否给你报告不能实时的进行显示了,实物的话多半是延时函数设置的问题
回复

使用道具 举报

ID:213173 发表于 2020-9-22 21:27 | 显示全部楼层
适合郭天祥TX-1C开发板,楼主消隐没有处理好。
  1. #include <STC89C5xRC.H>
  2. #include <intrins.h>

  3. #define u8 unsigned char
  4. #define u16 unsigned int
  5. #define u32 unsigned long

  6. sbit ledw=P2^6;
  7. sbit ledd=P2^7;

  8. #define ledduan P0

  9. u8 code ledma[]={
  10.                 0x3f,0x06,0x5b,0x4f,
  11.                 0x66,0x6d,0x7d,0x07,
  12.                 0x7f,0x6f,0x77,0x7c,
  13.                 0x39,0x5e,0x79,0x71,
  14.                 0x40,0x80,0xff,0x00};//共阴 0-f . 全显全灭

  15. u8 code ledwma[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//共阴

  16. u8 i;
  17. u32 a;

  18. void delay(u16 z)
  19. {
  20.         u16 x,y;
  21.         for(x=z;x>0;x--)
  22.                 for(y=120;y>0;y--);
  23. }

  24. void main()
  25. {
  26.         u8 aa[6];
  27.         a=333333;       
  28.         aa[0]=a/100000;
  29.         aa[1]=a%100000/10000;
  30.         aa[2]=a%10000/1000;
  31.         aa[3]=a%1000/100;
  32.         aa[4]=a%100/10;
  33.         aa[5]=a%10;

  34.         while(1)
  35.         {
  36.                 ledduan=0x00;         ledw=1;ledw=0;//消隐
  37.                 ledduan=ledwma[i];    ledd=1;ledd=0;//送位码
  38.                 ledduan=ledma[aa[i]]; ledw=1;ledw=0;//送段码
  39.                 delay(1);
  40.                 i++;i%=6;
  41.         }
  42. }
复制代码
回复

使用道具 举报

ID:389488 发表于 2020-9-23 08:20 | 显示全部楼层
xianfajushi 发表于 2020-9-22 15:40
段需要消隐,位无需消隐。数码管显示不要放在定时器里面,我的做法是不用定时器延时,也不用嵌套循环的延时 ...

感谢回复,理解你的写法。但是我现在需要解决的问题是用定时器时间切换位选
回复

使用道具 举报

ID:89515 发表于 2020-9-23 09:19 来自手机 | 显示全部楼层
j>=6对吗?
回复

使用道具 举报

ID:332444 发表于 2020-9-23 11:01 | 显示全部楼层
看注释目前定时器设定50毫秒,也就是说每50毫秒换一位数码管显示,似乎时间有点长了,通常是每位数码管20毫秒刷新,如果位数多了还要减少刷新时间,这暂且不论,使用锁存器电路通常处理的办法就是打开位送段延时段消隐就是消除幻影的办法,至少理论是这样,一般位是不用消隐的因为无论打开哪位段都是消隐的因此就没影响,不知道我说清楚了没,不知道试过没?
回复

使用道具 举报

ID:285863 发表于 2020-9-23 11:14 | 显示全部楼层
加快刷新速率 每位数码管10毫秒刷新 就没有鬼影
回复

使用道具 举报

ID:89515 发表于 2020-9-23 13:03 来自手机 | 显示全部楼层
j>=6?
回复

使用道具 举报

ID:389488 发表于 2020-9-23 13:17 | 显示全部楼层
谢谢各位热心的朋友,已解决 不用延时,用定时器计数时间切换。主要问题出来数字切换的时间上
#include <STC89C5xRC.H>
#include <intrins.h>

#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long


sbit ledd=P2^6;
sbit ledw=P2^7;

#define ledsmg P0


u8 code ledma []={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
0x7c,0x58,0x5e,0x79,0x71,0x80,0xff,0x00};//共阴 0-f . 全显全灭

u8 code ledwma []={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//共阴

u8 i;
u32 a=456123;

u8 aa,bb,cc,dd,ee,ff;

  

void timer0init()
{
        TMOD|=0x01;
        TH0=(65536-2765)/256;//3ms
        TL0=(65536-2765)%256;
        ET0=1;
        EA=1;
        TR0=1;
}




void main()
{
        aa=a/100000;
  bb=a%100000/10000;
  cc=a%10000/1000;
        dd=a%1000/100;
        ee=a%100/10;
        ff=a%10;
         
                  timer0init();
         
         while(1)
          {
                 
                }       
                 
}


void timerIsr() interrupt 1
{
         TH0=(65536-2765)/256;
         TL0=(65536-2765)%256;

          i++;
         if(i>=6)
                 {
                         i=0;
     }
                 switch(i)
                                {
                                        case 0:
                                                     ledw=1;
                                                     ledsmg=ledwma [0];
                       ledw=0;
       
                             ledd=1;
                             ledsmg=ledma[aa];
                                               ledd=0;
                             break;
                                        case 1:
                                                     ledw=1;
                                                     ledsmg=ledwma [1];
                       ledw=0;
       
                             ledd=1;
                             ledsmg=ledma[bb];
                                               ledd=0;
                                               break;
                                        case 2:
                                                     ledw=1;
                                                     ledsmg=ledwma [2];
                       ledw=0;
       
                             ledd=1;
                             ledsmg=ledma[cc];
                                                ledd=0;
                                                break;
                                        case 3:
                                                     ledw=1;
                                                     ledsmg=ledwma [3];
                       ledw=0;
       
                             ledd=1;
                             ledsmg=ledma[dd];
                                               ledd=0;
                                               break;
                                        case 4:
                                                     ledw=1;
                                                     ledsmg=ledwma [4];
                       ledw=0;
       
                             ledd=1;
                             ledsmg=ledma[ee];
                                               ledd=0;
                                               break;
                                        case 5:
                                                     ledw=1;
                                                     ledsmg=ledwma [5];
                       ledw=0;
       
                             ledd=1;
                             ledsmg=ledma[ff];
                                               ledd=0;
                                               break;
         }
}
回复

使用道具 举报

ID:389488 发表于 2020-9-23 13:18 | 显示全部楼层
xianfajushi 发表于 2020-9-23 11:01
看注释目前定时器设定50毫秒,也就是说每50毫秒换一位数码管显示,似乎时间有点长了,通常是每位数码管20毫 ...

实际是3ms  50ms备注没修改。
回复

使用道具 举报

ID:389488 发表于 2020-9-23 13:25 | 显示全部楼层
2894989833 发表于 2020-9-22 13:04
你这个是什么的代码

定时器切换数码管显示
回复

使用道具 举报

ID:389488 发表于 2020-9-24 08:15 | 显示全部楼层
wulin 发表于 2020-9-22 21:27
适合郭天祥TX-1C开发板,楼主消隐没有处理好。

赞一个
回复

使用道具 举报

ID:389488 发表于 2020-9-24 08:45 | 显示全部楼层
更新后的简化程序如下,正常显示
#include <STC89C5xRC.H>
#include <intrins.h>

#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long


sbit ledd=P2^6;
sbit ledw=P2^7;

#define ledsmg P0


u8 code ledma []={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
0x7c,0x58,0x5e,0x79,0x71,0x80,0xff,0x00};//共阴 0-f . 全显全灭

u8 code ledwma []={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//共阴

u8 i,j;
u32 a=654321;

u8 aa[6];

  

void timerinit()
{
        TMOD|=0x01;
        TH0=(65536-2765)/256;//3ms
        TL0=(65536-2765)%256;
        ET0=1;
        EA=1;
       
        TR0=1;
       
}




void main()
{
  aa[0]=a/100000;
  aa[1]=a%100000/10000;
  aa[2]=a%10000/1000;
  aa[3]=a%1000/100;
  aa[4]=a%100/10;
  aa[5]=a%10;
                  timerinit();
         
         while(1)
          {
                       
                 ledw=1;
                 ledsmg=ledwma [i];
                 ledw=0;
                       
                 }       
                 
}


void timer0Isr() interrupt 1
{
         TH0=(65536-2765)/256;
         TL0=(65536-2765)%256;

          i++;            
         if(i>=6)
          i=0;
                             ledd=1;
                             ledsmg=ledma[aa[i]];
                             ledd=0;
}

回复

使用道具 举报

ID:389488 发表于 2020-9-24 08:45 | 显示全部楼层

这样是没有问题的
回复

使用道具 举报

ID:822669 发表于 2020-9-24 09:33 | 显示全部楼层
所谓鬼影就是多次显示的重叠,每次显示完都清除一次就可以了
回复

使用道具 举报

ID:822755 发表于 2020-9-24 12:00 | 显示全部楼层
更新数据前,先关闭所有数码管
回复

使用道具 举报

ID:825447 发表于 2020-10-4 12:37 | 显示全部楼层
你在每次段选结束后下次位选前加上P0=0xff;  //消影
这样应该就可以解决了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表