找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机实现2位一体数码管的99-1显示的代码和仿真 显示很闪?

[复制链接]
跳转到指定楼层
楼主
51单片机实现2位一体数码管的99-1显示的代码和仿真,按键可以暂停和继续开始
可以重复实现99到1的倒计时
按键按一下为暂停,再按一次继续倒计

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include "reg52.h"
  2. #include <stdio.h>
  3. typedef unsigned int u16;
  4. typedef unsigned char u8;
  5. sbit key = P3^4;
  6. sbit LS0 = P3^0;
  7. sbit LS1= P3^1;   
  8. unsigned char led_mod[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  9. void display(u8 num);
  10. void delay_ms(u16 num);
  11. void main()
  12. {
  13. u8 c;
  14. u8 m,n,a;        
  15. c=99;        
  16. while(1)
  17. {
  18.         display(c);
  19.         delay_ms(300);
  20.         c=c-1;
  21.         if(key==0)
  22.         {
  23.                 a=1;
  24.                 while(a)
  25.                 {
  26.                         display(c);
  27.                         delay_ms(300);
  28.                         if(key==0)
  29.                         {
  30.                                 a=0;
  31.                         }
  32.                 }
  33.         }
  34.         if(c<=0)
  35.         {
  36.                 c=99;
  37.         }
  38. }
  39. }        

  40. void display(u8 num)
  41. {
  42. u8 m, n,j;
  43. m = num/10;
  44. n = num%10;
  45. for(j=0;j<2;j++)  
  46.             {
  47.                          switch(j)         
  48.                          {
  49.                                  case(0):
  50.                                          LS0=0;LS1=1;
  51.                                          P2=led_mod[m];                                 
  52.                                          break;
  53.                                  case(1):
  54.                                          LS0=1;LS1=0;
  55.                                          P2=led_mod[n];                                 
  56.                                         break;                                 
  57.                          }                        
  58.                          delay_ms(25);
  59.                          P2=0x00;
  60.                  }
  61. }




  62. void delay_ms(u16 num)
  63. {
  64.         u16 x, y;
  65.         for(x = num; x > 0; x--)
  66.         for(y = 110; y > 0; y--);
  67. }
复制代码

Keil代码与Proteus仿真下载:
电子设计.7z (61.44 KB, 下载次数: 9)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:966423 发表于 2022-3-7 21:34 | 只看该作者
建议你程序规范一些,u8 c最好初始化的时候直接定于0或者其他数据要不然编译器有时会给你随便搞一个数值。
回复

使用道具 举报

板凳
ID:514254 发表于 2022-3-8 00:20 | 只看该作者
闪烁是“视觉暂留”没有控制好啊,delay_ms(300);delay_ms(25);都是问题
回复

使用道具 举报

地板
ID:123289 发表于 2022-3-8 15:39 | 只看该作者
何时不用DELAY了,就好了。
初学者,只会用最低级的DELAY延时,不知道教课书上有没有教过DELAY的危害是什么。谁害了初学者。
你想想看,当你DELAY 0.3秒时,在这0.3秒里,两个LED是显示的是什么?一个有字一个无字?
回复

使用道具 举报

5#
ID:1008839 发表于 2022-3-8 16:19 | 只看该作者
延迟弄长一点看看
回复

使用道具 举报

6#
ID:213173 发表于 2022-3-8 16:45 | 只看该作者
楼主仔细对比一下,会有收获。
  1. #include "reg52.h"
  2. #include <stdio.h>
  3. typedef unsigned int u16;
  4. typedef unsigned char u8;
  5. sbit key = P3^4;
  6. sbit LS0 = P3^0;
  7. sbit LS1 = P3^1;   
  8. unsigned char led_mod[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  9. void display(u8 num);
  10. void delay_ms(u16 num);

  11. void main()
  12. {
  13.         u16 count;
  14.         u8  c=0,a=0;
  15.         bit n=0,m=0;
  16.         while(1)
  17.         {
  18.                 if(key==0)
  19.                 {
  20.                         if(++a>=10 && n==0)
  21.                         {
  22.                                 n=1;
  23.                                 if(c!=0)m=~m;
  24.                                 else        
  25.                                 {
  26.                                         c=99;
  27.                                         m=1;
  28.                                 }
  29.                         }
  30.                 }
  31.                 else
  32.                 {
  33.                         a=0;
  34.                         n=0;
  35.                 }
  36.                 if(m==1)
  37.                 {               
  38.                         if(++count>=1000)
  39.                         {
  40.                                 count=0;
  41.                                 if(c>0)c--;
  42.                                 else m=0;
  43.                         }
  44.                 }
  45.                 display(c);
  46.                 delay_ms(1);       
  47.         }
  48. }        

  49. void display(u8 num)
  50. {
  51.         static bit i=0;
  52.         P2=0x00;
  53.         if(i==0)
  54.         {
  55.                 LS0=0;LS1=1;       
  56.                 P2=led_mod[num/10];
  57.                 i=1;
  58.         }
  59.         else
  60.         {
  61.                 LS0=1;LS1=0;       
  62.                 P2=led_mod[num%10];
  63.                 i=0;
  64.         }
  65. }

  66. void delay_ms(u16 num)
  67. {
  68.         u16 x, y;
  69.         for(x=num;x>0;x--)
  70.                 for(y=110;y>0;y--);
  71. }
复制代码
回复

使用道具 举报

7#
ID:824490 发表于 2022-3-8 16:45 | 只看该作者
本帖最后由 名字不是重点 于 2022-3-8 17:00 编辑

动态扫描显示,就是利用人眼的“视觉暂留”效果,来实现整幅画面的“稳定”显示。
人眼的“视觉暂留”一般在100ms-400ms,如要8个数码管动态扫显,必需保证至少每100ms(扫描间隔Ts)要输出一帧的显示数据。假如传输一帧数据花费的时间为2ms(Tf),一帧包含8个数码管,所以每个数码管的维持时间(Th)约为0.25ms,这时数码管显示看上去很暗,就要把Th加大。而且每个数码管的Th必需相同,这样才不会显得亮度不均(硬件参数正确的情况下)。而Ts太大了,就会出现数码管闪烁的现象,也不能太小,否则会影响其它任务的时效性。这就牵涉到任务时间片的调度,
在祼奔系统中,常规的做法是把扫显任务做成一个函数,在其它任务片中按需调用。比如按键扫描,插入扫显,替代“去抖动延时”,等等。而RTOS之类的系统另说。
回复

使用道具 举报

8#
ID:1008839 发表于 2022-3-8 21:33 | 只看该作者
应该是延时中断的问题
回复

使用道具 举报

9#
ID:824490 发表于 2022-3-8 22:09 | 只看该作者
void display(u8 num)这个函数有点废。。
总共就2个数码管,又是if ,又是switchr ...
  • void display(u8 num)
  • {
  • u8 m, n;
  • m = num/10;
  • n = num%10;
  • LS0=0;LS1=1;
  • P2=led_mod[m];
  • delay_ms(25);
  • LS0=1;LS1=0;
  •   P2=led_mod[n];
  •   delay_ms(25);
  •   P2=0x00;
  • }

这样不更快吗?


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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