找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5272|回复: 9
打印 上一主题 下一主题
收起左侧

单片机数码管动态扫描程序,有一个没搞懂,求解惑!

[复制链接]
跳转到指定楼层
楼主
ID:404479 发表于 2018-11-7 14:57 来自手机 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以下这段是数码管动态扫描的单片机程序,这段程序实现的是8个数码管同时循环显示11111111,22222222,一直到99999999,以下几个地方我不明白,大家帮我指导以下:
①数码管用共阴极,用的是138译码器控制8和数码管的负级,大家知道,138译码器一次性只能输出一位低电平,不能同时全输出低电平,也就是只能通过switch选择语句来一位一位的点亮,不能实现同时一起点亮同一个数,并且循环扫描显示,于是,我就请教了很多论坛朋友,他们修改了一段代码,我就不理解是什么意思,也就是从我编写的原基础上,增加了:
void main()
{        
unsigned char i;
        while(1)
        {        
          for  (i=0;i<200;i++)     
                                        {
                                                DigDisplay();  
                                        }
                                        k++;
                                        if (k>9)
                                        {
                                                k=0;
                                        }
        }               
}
我看不懂的是,它在main主函数里增加要循环200次这个子函数的意义是什么,这样会不会是为了快速刷新子函数里面的这个switch反复执行来达到138译码器全部无间隔的提供负级,让数码管显示00000000,11111111,这样循环显示到99999999然后又从0开始?是这样吗?
以下是网友们修改的代码,可以实现同时一起动态扫描显示,我就不理解为何要让子函数执行200次的循环!
修改后我不能理解的程序:
  1. #include "reg52.h"                     
  2. typedef unsigned int u16;         
  3. typedef unsigned char u8;

  4. sbit LSA=P2^2;
  5. sbit LSB=P2^3;
  6. sbit LSC=P2^4;

  7. unsigned char k=0;

  8. u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  9.                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};


  10. void delay(u16 i)
  11. {
  12.         while(i--);        
  13. }


  14. void DigDisplay()
  15. {
  16.         u8 i;
  17.         for(i=0;i<8;i++)
  18.         {
  19.                 switch(i)         
  20.                 {
  21.                         case(0):
  22.                                 LSA=0;LSB=0;LSC=0; break;
  23.                         case(1):
  24.                                 LSA=1;LSB=0;LSC=0; break;
  25.                         case(2):
  26.                                 LSA=0;LSB=1;LSC=0; break;
  27.                         case(3):
  28.                                 LSA=1;LSB=1;LSC=0; break;
  29.                         case(4):
  30.                                 LSA=0;LSB=0;LSC=1; break;
  31.                         case(5):
  32.                                 LSA=1;LSB=0;LSC=1; break;
  33.                         case(6):
  34.                                 LSA=0;LSB=1;LSC=1; break;
  35.                         case(7):
  36.                                 LSA=1;LSB=1;LSC=1; break;        
  37.                 }
  38.                 P0=smgduan[k];
  39.                 delay(100);      
  40.                 P0=0x00;
  41.         }
  42. }


  43. void main()
  44. {        
  45. unsigned char i;
  46.         while(1)
  47.         {        
  48.           for  (i=0;i<200;i++)     
  49.                                         {
  50.                                                 DigDisplay();  
  51.                                         }
  52.                                         k++;
  53.                                         if (k>9)
  54.                                         {
  55.                                                 k=0;
  56.                                         }
  57.         }               
  58. }
复制代码


下面是我个人写的不能同时显示得程序,这个程序就只能利用动态扫描来显示出1234567,就不动了!


  1. #include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

  2. typedef unsigned int u16;          //对数据类型进行声明定义
  3. typedef unsigned char u8;

  4. sbit LSA=P2^2;
  5. sbit LSB=P2^3;
  6. sbit LSC=P2^4;

  7. u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  8.                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值


  9. void delay(u16 i)
  10. {
  11.         while(i--);        
  12. }


  13. void DigDisplay()
  14. {
  15.         u8 i;
  16.         for(i=0;i<8;i++)
  17.         {
  18.                 switch(i)         //位选,选择点亮的数码管,
  19.                 {
  20.                         case(0):
  21.                                 LSA=0;LSB=0;LSC=0; break;//显示第0位
  22.                         case(1):
  23.                                 LSA=1;LSB=0;LSC=0; break;//显示第1位
  24.                         case(2):
  25.                                 LSA=0;LSB=1;LSC=0; break;//显示第2位
  26.                         case(3):
  27.                                 LSA=1;LSB=1;LSC=0; break;//显示第3位
  28.                         case(4):
  29.                                 LSA=0;LSB=0;LSC=1; break;//显示第4位
  30.                         case(5):
  31.                                 LSA=1;LSB=0;LSC=1; break;//显示第5位
  32.                         case(6):
  33.                                 LSA=0;LSB=1;LSC=1; break;//显示第6位
  34.                         case(7):
  35.                                 LSA=1;LSB=1;LSC=1; break;//显示第7位        
  36.                 }
  37.                 P0=smgduan[i];//发送段码
  38.                 delay(100); //间隔一段时间扫描        
  39.                 P0=0x00;//消隐
  40.         }
  41. }


  42. void main()
  43. {        
  44.         while(1)
  45.         {        
  46.                 DigDisplay();  //数码管显示函数        
  47.         }               
  48. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:419294 发表于 2018-11-7 16:43 | 只看该作者
动态扫描就是几个数码显示的数字式一直显示的,实际上是一个一个在显示,这就是动态显示
回复

使用道具 举报

板凳
ID:89515 发表于 2018-11-7 17:15 | 只看该作者
显示同一个数的次数,相当于延时
回复

使用道具 举报

地板
ID:394504 发表于 2018-11-7 17:54 | 只看该作者
你的 i 先复制为零 在循环八次 之后 i就为八了 所以就不会继续显示了 所以你的i要去判断
if (i == 8)
{
    i = 0;
}
回复

使用道具 举报

5#
ID:272089 发表于 2018-11-7 18:13 | 只看该作者
  1. uchar code ledcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
  2. uchar buf1[8];

  3. void dis()
  4. {
  5.     uchar i,j=0x7f;
  6.         for(i=0;i<8;i++)
  7.         {
  8.            cs1=0;cs2=1;
  9.            P0=ledcode[buf1[i]];wr=1;wr=0;
  10.            cs1=1;cs2=0;
  11.            P0=j;wr=1;wr=0;
  12.            delay(100);
  13.            cs1=cs2=1;
  14.            j=_cror_(j,1);
  15.            P0=0xff;wr=1;wr=0;
  16.         }
  17. }
  18. void main()
  19. {
  20.      buf[0]=1;                          //想用第几个数码管就写buf[几]
  21.      buf[1]=2;                          //等于后面的是用来显示上面的数组的,
  22.                                             //等于1就是显示ledcode的第一个数组也就是1
  23.      buf[2]=3;                         //不过我这个是共阴极的数码管
  24.      while(1){dis();}
  25. }
复制代码
回复

使用道具 举报

6#
ID:213173 发表于 2018-11-7 22:03 | 只看该作者
他在main主函数里增加要循环200次是为了延时,使0~9变化不至于太快而无法辨识。也就是数码管动态扫描显示200次,显示内容才变化1次。由于单片机运行速度非常快,你要处理的任务又很少,主循环周期很短。0~9变化太快你看到的是笔画亮度不均的8字。坛友是在你的程序基础上优化的,在实际应用中不可能是这样处理的。
回复

使用道具 举报

7#
ID:111634 发表于 2018-11-8 09:06 | 只看该作者
还是要打基础,学理论,否则,问题多多,事倍功半。
回复

使用道具 举报

8#
ID:381277 发表于 2018-11-8 10:30 | 只看该作者
第一段程序的变量k是两段程序运行结果不一样的关键
回复

使用道具 举报

9#
ID:123289 发表于 2018-11-8 13:38 | 只看该作者
是你未理解如何扫描:
准备好一行的显示码 → 关所有显示(防止因切换引起错码闪动)→ 输出显示码 → 打开显示
→ 间隔一段时间(这段时间才能让人眼感觉到显示的信息!间隔小了人眼看分不清,间隔大了有闪烁感,需要仔细选择)
下一行开始,如发泡制。
回复

使用道具 举报

10#
ID:404479 发表于 2018-11-16 19:27 来自手机 | 只看该作者
wulin 发表于 2018-11-7 22:03
他在main主函数里增加要循环200次是为了延时,使0~9变化不至于太快而无法辨识。也就是数码管动态扫描显示20 ...

谢谢,我明白了!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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