找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4|回复: 0
收起左侧

解决了初学者常遇到的糟心问题,51单片机proteus仿真数码管点阵的动态显示乱码故障

[复制链接]
ID:1175293 发表于 2026-9-2 21:43 | 显示全部楼层 |阅读模式
对于初学者最糟心的事就是程序编写的很好,却在仿真时出毛病。程序能在开发板上顺利执行,数码管与点阵屏proteus显示仿真却总是出问题。你的本意是想用仿真发现问题,从而减少在现实中出错的机率,结果到仿真那一步让你抓狂了,薅掉半斤头发,最后发现与你的程序与原理图毛事没有,毛病出在proteus软件上,毕竟人编写的软件,还达不到真正模拟实物的水平,只能努力无限接近。
我用了一整天,和这个问题较劲,期间无数次反对AI提出的问题答案与解决方案。也不能说AI一点帮助没有,在某些问题与思路上还是能给些提示的,但更多的时间是在胡说八道,引你入歧途,所以我浪费了这么长时间。
因为我是直接用P0,和P2端口控制的8个数码管,所以我会用逻辑探针去检查P0端口及与P0相连的线,发现P0口在程序proteus仿真过程中,出现了我不需要的数据,即出现了干扰。
这促使我放弃直接用P0与P2端口,我决定用两个74HC595串转并芯片级联来控制8个数码管。我要看看没有了P0的数据干扰,会有效吗?结果是解决了95%的故障。剩下的故障是因为我有些变量设置成pdata模式,而这个模式也容易造成proteus仿真51芯片工作时,出现对芯片P0与P2寄存器的干扰,从而神秘地间接影响你的变量。总结下来都是一回事,P0与P2寄存器易受干扰,从而在proteus仿真中故障,使你的程序能在开发板运行(实物容错能力比虚拟仿真强),但在仿真时出现乱码,乱跳,甚至不显示,重点体现在有很多个LED灯一起工作的情况,比如更多的数码管与8*8点阵。
实话实说,pdata设置造成P0寄存器的干扰,最后还是AI提出的假设,我验证成功了。单独靠我自己,绝对发现不了这种玄幻。

下面是我用51单片机中断计时,在数码管上显示时间的程序,整合了长短按键功能,按键设置时间功能。AI说pdata设置变量,使得51仿真时,调用了P0去寻址,从而神秘使得51误判我某个按键启动,显示小时部分在00与23之间互跳,分钟部分在00与01间互跳。
初学者在写程序时,还是尽量不要用片外内存,即不用pdata与xdata,除非256个字节片内RAM用完,尤其是在用数码管与点阵显示数字时。硬件设置上弃用芯片寄存器直接控制数码管与点阵,用类似74HC595芯片来传输数据,控制点阵与数码管。
程序中注释掉的是我程序修改前的痕迹,我没有删除,有兴趣的人可以对比一下仿真现象与效果。

  1. #include<reg51.h>
  2. #include<intrins.h>
  3. // #define weixuan P2
  4. // #define duanxuan P0
  5. sbit key1=P3^0;
  6. sbit key2=P3^1;
  7. sbit key3=P3^2;
  8. sbit key4=P3^3;
  9. sbit SH_CP=P1^0;
  10. sbit ST_CP=P1^1;
  11. sbit DS1=P1^2;



  12. unsigned char code KeyCodeMap[4] ={0x26,0x25,0x28,0x27};//up left down right
  13. typedef unsigned char u8;
  14. typedef unsigned int u16;
  15. u8 T0RH,T0RL;
  16. u8 secflag=0;
  17. bit sethour=0,setmin=0;
  18. u8 keysta[4]={1,1,1,1};
  19. signed char hour=0;
  20. signed char min=0;
  21. signed char sec=0;
  22. bit hourblink=0;
  23. bit minblink=0;
  24. /*  共阴极管的数字索引
  25. u8 code gsmg_code[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  26.                                           0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  27. */
  28. unsigned char code gsmg_code[] = {   //共阳极管的数字索引
  29. 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  30. 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  31. };
  32. // u8 smgbuff[8]={0x3f,0x3f,0x40,0x3f,0x3f,0x40,0x3f,0x3f};//s,min,h
  33. u8 smgbuff[8]={0xC0,0xC0,0xBF,0xC0,0xC0,0xBF,0xC0,0xC0};//s,min,h

  34. u8  wselect[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

  35. unsigned long  keydowntime[4]={0,0,0,0};



  36. void tranfer_data(u8 dat1,u8 dat2)   //595串转并芯片的数据传输函数,dat1交给第一级,控制位选,dat2交给第二级,段选
  37. {
  38.         u8 i=0;
  39.         for(i=0;i<8;i++)
  40.         {
  41.                 DS1=dat2>>7;
  42.                 dat2<<=1;
  43.                 SH_CP=0;
  44.                 _nop_ ();

  45.                 SH_CP=1;
  46.                 _nop_();

  47.                
  48.         }
  49.                         
  50.         
  51.         for(i=0;i<8;i++)
  52.         {
  53.                 DS1=dat1>>7;
  54.                 dat1<<=1;
  55.                 SH_CP=0;
  56.                 _nop_ ();

  57.                 SH_CP=1;
  58.                 _nop_();

  59.                
  60.         }
  61.                 ST_CP=0;
  62.                 _nop_();
  63.                 ST_CP=1;
  64.         _nop_ ();

  65. }        



  66. void ledscan()
  67. {
  68.                  static u8 i=0;
  69. //          duanxuan=0x00;                                                                // hide shade
  70. //    duanxuan=0xFF;
  71. //            weixuan=0x00;
  72. //           weixuan  =(0x01<<i);
  73. //                duanxuan=smgbuff[i];
  74.         
  75.         //                tranfer_data(0x00,0xFF);  //hide shade
  76.                         tranfer_data(wselect[i], smgbuff[i]);//transer wx and dx data        
  77.         
  78.         
  79.                
  80.                 i++;
  81.                 if(i>=8)
  82.                 {
  83.                         i=0;
  84.                 }
  85.                 //i=i&0x07;
  86. }

  87. void configtime(u8 ms)
  88. {
  89.         unsigned long tmp;
  90.         tmp=ms*11059200/12/1000;
  91.         tmp=65536-tmp+15;//delay compensationn
  92.         T0RH=(u8)(tmp>>8);
  93.         T0RL=(u8)tmp;
  94.         EA=1;
  95.         TMOD=0X01;
  96.         TH0=T0RH;
  97.         TL0=T0RL;
  98.         ET0=1;
  99.         TR0=1;
  100. }


  101. void keyscan()
  102. {
  103.         static u8 keybuff[4]={0xff,0xff,0xff,0xff};
  104.         
  105.         u8 j=0;
  106.         keybuff[0]=(keybuff[0]<<1) | key1;
  107.         keybuff[1]=(keybuff[1]<<1) | key2;
  108.         keybuff[2]=(keybuff[2]<<1) | key3;
  109.         keybuff[3]=(keybuff[3]<<1) | key4;
  110.         
  111.         
  112.         for(j=0;j<4;j++)
  113.         {
  114.                 if(keybuff[j]==0x00)
  115.                 {
  116.                         keysta[j]=0;
  117.                         keydowntime[j]+=4;
  118.                 }
  119.                 else if(keybuff[j]==0xff)
  120.                 {
  121.                         keysta[j]=1;
  122.                         keydowntime[j]=0;
  123.                 }
  124.         }
  125.         
  126.         
  127.         
  128.         
  129. }

  130. void keyaction(u8 kode)
  131. {
  132.         //0x26,0x25,0x28,0x27
  133.         switch(kode)
  134.         {
  135.                 case 0x26:
  136.                                                         {
  137.                                                                 if(sethour==1)
  138.                                                                 {
  139.                                                                         
  140.                                                                         hour++;
  141.                                                                
  142.                                                                         if(hour>=24)
  143.                                                                         {
  144.                                                                                 hour=0;
  145.                                                                         }
  146.                                                                         smgbuff[1]=gsmg_code[hour%10];
  147.                                                                         smgbuff[0]=gsmg_code[hour/10];
  148.                                                                 }
  149.                                                                 if(setmin==1)
  150.                                                                 {
  151.                                                                         min++;
  152.                                                                         if(min>=60)
  153.                                                                         {
  154.                                                                                 min=0;
  155.                                                                         }
  156.                                                                         smgbuff[4]=gsmg_code[min%10];
  157.                                                                         smgbuff[3]=gsmg_code[min/10];
  158.                                                                 }
  159.                                                                 break;
  160.                                                         }
  161.                 case 0x25:sethour=~sethour;break;
  162.                 case 0x28:
  163.                                                         {
  164.                                                                 if(sethour==1)
  165.                                                                 {
  166.                                                                         hour--;
  167.                                                                         if(hour<0)
  168.                                                                         {
  169.                                                                                 hour=23;
  170.                                                                         }
  171.                                                                         smgbuff[1]=gsmg_code[hour%10];
  172.                                                                         smgbuff[0]=gsmg_code[hour/10];
  173.                                                                 }
  174.                                                                 if(setmin==1)
  175.                                                                 {
  176.                                                                         min--;
  177.                                                                         if(min<0)
  178.                                                                         {
  179.                                                                                 min=59;
  180.                                                                         }
  181.                                                                         smgbuff[4]=gsmg_code[min%10];
  182.                                                                         smgbuff[3]=gsmg_code[min/10];
  183.                                                                 }
  184.                                                                 break;
  185.                                                         }
  186.                 case 0x27:setmin=~setmin;break;
  187.                 default :break;
  188.         }
  189.         
  190.         
  191. }


  192. void keydrive()
  193. {
  194.         static u8 backup[4]={1,1,1,1};
  195.         u8 k=0;
  196.         static unsigned long  timemax[4]={1000,1000,1000,1000};
  197.         for(k=0;k<4;k++)
  198.         {
  199.                 if(backup[k]!=keysta[k])
  200.                 {
  201.                         backup[k]=keysta[k];
  202.                         if(backup[k]!=0)
  203.                         {
  204.                                 keyaction(KeyCodeMap[k]);
  205.                                 
  206.                         }
  207.                 }
  208.                 if(keydowntime[k]>0)
  209.                 {
  210.                         if(keydowntime[k]>=timemax[k])
  211.                                         {
  212.                                                 keyaction(KeyCodeMap[k]);
  213.                                                 timemax[k]+=200;
  214.                                         }
  215.                
  216.                 }
  217.                 else
  218.                 {
  219.                         timemax[k]=1000;
  220.                 }
  221.         }
  222. }

  223. void time()
  224. {
  225.         if(secflag==1)
  226.         {
  227.                 secflag=0;
  228.                
  229.                 sec++;
  230.                 if(sec==60)
  231.                 {
  232.                         sec=0;
  233.                         
  234.                         min++;
  235.                         if(min==60)
  236.                         {
  237.                                 min=0;
  238.                                 
  239.                                 hour++;
  240.                                 if(hour==24)
  241.                                 {
  242.                                         hour=0;
  243.                                 }
  244.                                 smgbuff[1]=gsmg_code[hour%10];
  245.                                 smgbuff[0]=gsmg_code[hour/10];
  246.                                 
  247.                         }
  248.                         smgbuff[4]=gsmg_code[min%10];
  249.                         smgbuff[3]=gsmg_code[min/10];
  250.                 }
  251.                 smgbuff[7]=gsmg_code[sec%10];
  252.                 smgbuff[6]=gsmg_code[sec/10];
  253.         }
  254.                
  255. }



  256. void main()
  257. {
  258.         configtime(5);  //中断函数中内容较多,1ms可能不够用,故设置成5ms
  259.         
  260.         
  261.         while(1)
  262.         {
  263.                 time();
  264.                 keydrive();
  265.         
  266.                
  267.         }
  268.         
  269. }

  270. void interruptmr() interrupt 1
  271. {
  272.         static u16 timer1=0;
  273.         static u16 timer2=0;
  274.         TH0=T0RH;
  275.         TL0=T0RL;
  276.         ledscan();
  277.         keyscan();
  278.         timer1++;
  279.         timer2++;
  280.         if(timer1==200)
  281.         {
  282.                 timer1=0;
  283.                 secflag=1;
  284.         }
  285.         if(timer2==100)
  286.         {
  287.                 timer2=0;
  288.         
  289.                         if(sethour==1 )
  290.                 {
  291.                                 if(hourblink==0)
  292.                         {
  293.                                 smgbuff[1]=0xFF;
  294.                                 smgbuff[0]=0xFF;
  295.                                 
  296.                         }
  297.                         else
  298.                         {
  299.                                 smgbuff[1]=gsmg_code[hour%10];
  300.                                 smgbuff[0]=gsmg_code[hour/10];
  301.                         }
  302.                         hourblink=~hourblink;
  303.                 }
  304.                 else
  305.                 {
  306.                         smgbuff[1]=gsmg_code[hour%10];
  307.                         smgbuff[0]=gsmg_code[hour/10];
  308.                 }

  309.                 if(setmin==1)
  310.                 {
  311.                                 if(minblink==0)
  312.                         {
  313.                                 smgbuff[4]=0xFF;
  314.                                 smgbuff[3]=0xFF;
  315.                                 
  316.                         }
  317.                         else
  318.                         {
  319.                                 smgbuff[4]=gsmg_code[min%10];
  320.                                 smgbuff[3]=gsmg_code[min/10];
  321.                         }
  322.                         minblink=~minblink;
  323.                 }
  324.                 else
  325.                 {
  326.                         smgbuff[4]=gsmg_code[min%10];
  327.                         smgbuff[3]=gsmg_code[min/10];
  328.                 }
  329.         
  330.         }
  331. }
复制代码

proteus9

proteus9

smgclock.zip

26.64 KB, 下载次数: 0, 下载积分: 黑币 -5

原理图与程序

评分

参与人数 1黑币 +80 收起 理由
admin + 80 共享资料的奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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