找回密码
 立即注册

QQ登录

只需一步,快速开始

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

简易芯片中断供时时钟,并希望大神解决一个普遍性proteus显示问题

[复制链接]
跳转到指定楼层
楼主
我用89C51芯片编写了一个简易时钟,功能是用89C51中断计时,然后在8位数码管上显示出来。使用4个按键来对小时与分钟调整,并整合了长短按键功能。程序可以在普中A4开发板顺利运行,所以我贴出来分享给新进者。
但同时也向路过的大神问一个问题?为什么程序在proteus上不能正确仿真,总是出现乱码?在网上搜过各种答案,也照着答案修改过原理图,还是不能解决。问过AI,它总是一本正经的胡说八道,害我浪费很多时间。本来我直接用P2口控制位选,用P0接个74HC138跟随器控制段选,没成功。按AI说的,P2也接上74HC138,还与数码管之间连上限流电阻,依然无效。单步运行仿真,还能看到数码管时不时显示乱码,整体仿真连显示都没有。换成8个单个的数码管,结局一样。proteus自己的提示是CPU过载,我按网上提示所说,换了台性能好的游戏本,还是一样结果。
所以我没招了,有用proteus非常多的大神没有?希望你们能帮我解决一下这个大众问题。这个问题应该是很普便性的,但一直没见到好的解决方案。它是proteus的51单片机之坑。我在使用点阵时,也会碰到类似问题。

我把时钟设计的proteus9.0原理图与针对原理图调整的程序放在了附件的zip文件里

下面是我在普中开发板上的成功代码,根据开发板原理图编写。
  1. #include<reg51.h>
  2. #define weixuan P2
  3. #define duanxuan P0
  4. sbit key1=P3^1;
  5. sbit key2=P3^0;
  6. sbit key3=P3^2;
  7. sbit key4=P3^3;
  8. unsigned char code KeyCodeMap[4] ={0x26,0x25,0x28,0x27};//up left down right
  9. typedef unsigned char u8;
  10. typedef unsigned int u16;
  11. u8 T0RH,T0RL;
  12. u8 secflag=0;  //秒计数标记
  13. bit sethour=0,setmin=0;    //设置小时与分钟的标记
  14. u8 keysta[4]={1,1,1,1};
  15. signed char hour=0;
  16. signed char min=0;
  17. signed char sec=0;
  18. bit hourblink=0;    //小时与分钟闪烁标记
  19. bit minblink=0;

  20. u8 code gsmg_code[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  21.                                           0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};   //数字索引表
  22. u8 smgbuff[8]={0x3f,0x3f,0x40,0x3f,0x3f,0x40,0x3f,0x3f};//s,min,h

  23. unsigned long pdata keydowntime[4]={0,0,0,0};   //按键按下计时



  24. void ledscan()
  25. {
  26.                  static u8 i=0;
  27.                 duanxuan=0x00;                                                                // hide shade
  28.                 weixuan  =(weixuan&0xe3) |(i<<2);             开发板用的是P2.2 2.3 2.4引脚来位选,所以i左移2位后或到P2口上
  29.                 duanxuan=smgbuff[i];
  30.                 i++;
  31.                 if(i>=8)
  32.                 {
  33.                         i=0;
  34.                 }
  35. }

  36. void configtime(u8 ms)
  37. {
  38.         unsigned long tmp;
  39.         tmp=ms*11059200/12/1000;
  40.         tmp=65536-tmp+15;//delay compensationn
  41.         T0RH=(u8)(tmp>>8);
  42.         T0RL=(u8)tmp;
  43.         EA=1;
  44.         TMOD=0X01;
  45.         TH0=T0RH;
  46.         TL0=T0RL;
  47.         ET0=1;
  48.         TR0=1;
  49. }


  50. void keyscan()  //消抖思路学自kingst开发板教程
  51. {
  52.         static u8 keybuff[4]={0xff,0xff,0xff,0xff};
  53.         
  54.         u8 j=0;
  55.         keybuff[0]=(keybuff[0]<<1) | key1;
  56.         keybuff[1]=(keybuff[1]<<1) | key2;
  57.         keybuff[2]=(keybuff[2]<<1) | key3;
  58.         keybuff[3]=(keybuff[3]<<1) | key4;
  59.         
  60.         //i=i&0x07;
  61.         for(j=0;j<4;j++)
  62.         {
  63.                 if(keybuff[j]==0x00)
  64.                 {
  65.                         keysta[j]=0;             //keybuff左移8次后若显示都是0,说明消抖后,按键处于按下状态,同时按键时间加4,改变数字可以改灵敏度
  66.                         keydowntime[j]+=4;
  67.                 }
  68.                 else if(keybuff[j]==0xff)
  69.                 {
  70.                         keysta[j]=1;
  71.                         keydowntime[j]=0;  //按键弹起后,按下时间要归0
  72.                 }
  73.         }
  74.         
  75.         
  76.         
  77.         
  78. }

  79. void keyaction(u8 kode)
  80. {
  81.         //0x26,0x25,0x28,0x27
  82.         switch(kode)
  83.         {
  84.                 case 0x26:   //向上键,方向加
  85.                                                         {
  86.                                                                 if(sethour==1)
  87.                                                                 {
  88.                                                                         
  89.                                                                         hour++;
  90.                                                                
  91.                                                                         if(hour>=24)
  92.                                                                         {
  93.                                                                                 hour=0;
  94.                                                                         }
  95.                                                                         smgbuff[6]=gsmg_code[hour%10];
  96.                                                                         smgbuff[7]=gsmg_code[hour/10];
  97.                                                                 }
  98.                                                                 if(setmin==1)
  99.                                                                 {
  100.                                                                         min++;
  101.                                                                         if(min>=60)
  102.                                                                         {
  103.                                                                                 min=0;
  104.                                                                         }
  105.                                                                         smgbuff[3]=gsmg_code[min%10];
  106.                                                                         smgbuff[4]=gsmg_code[min/10];
  107.                                                                 }
  108.                                                                 break;
  109.                                                         }
  110.                 case 0x25:sethour=~sethour;break;   //左键调小时
  111.                 case 0x28:  //向下键,方向减
  112.                                                         {
  113.                                                                 if(sethour==1)
  114.                                                                 {
  115.                                                                         hour--;
  116.                                                                         if(hour<0)
  117.                                                                         {
  118.                                                                                 hour=23;
  119.                                                                         }
  120.                                                                         smgbuff[6]=gsmg_code[hour%10];
  121.                                                                         smgbuff[7]=gsmg_code[hour/10];
  122.                                                                 }
  123.                                                                 if(setmin==1)
  124.                                                                 {
  125.                                                                         min--;
  126.                                                                         if(min<0)
  127.                                                                         {
  128.                                                                                 min=59;
  129.                                                                         }
  130.                                                                         smgbuff[3]=gsmg_code[min%10];
  131.                                                                         smgbuff[4]=gsmg_code[min/10];
  132.                                                                 }
  133.                                                                 break;
  134.                                                         }
  135.                 case 0x27:setmin=~setmin;break;  //右键调分钟
  136.                 default :break;
  137.         }
  138.         
  139.         
  140. }


  141. void keydrive()
  142. {
  143.         static u8 backup[4]={1,1,1,1};
  144.         u8 k=0;
  145.         static unsigned long pdata timemax[4]={1000,1000,1000,1000};
  146.         for(k=0;k<4;k++)
  147.         {
  148.                 if(backup[k]!=keysta[k])  //分析是否为一个完整的由弹起到按下的过程
  149.                 {
  150.                         backup[k]=keysta[k];
  151.                         if(backup[k]!=0)
  152.                         {
  153.                                 keyaction(KeyCodeMap[k]);
  154.                                 
  155.                         }
  156.                 }
  157.                 if(keydowntime[k]>0)  //判断按键按下的时间,是否需要执行长按键功能
  158.                 {
  159.                         if(keydowntime[k]>=timemax[k])
  160.                                         {
  161.                                                 keyaction(KeyCodeMap[k]);
  162.                                                 timemax[k]+=200;
  163.                                         }
  164.                
  165.                 }
  166.                 else
  167.                 {
  168.                         timemax[k]=1000;  //注意,按键弹起后,此处要恢复timemax的初值。
  169.                 }
  170.         }
  171. }

  172. void time()
  173. {
  174.         if(secflag==1)
  175.         {
  176.                 secflag=0;
  177.                
  178.                 sec++;
  179.                 if(sec==60)
  180.                 {
  181.                         sec=0;
  182.                         
  183.                         min++;
  184.                         if(min==60)
  185.                         {
  186.                                 min=0;
  187.                                 
  188.                                 hour++;
  189.                                 if(hour==24)
  190.                                 {
  191.                                         hour=0;
  192.                                 }
  193.                                 smgbuff[6]=gsmg_code[hour%10];
  194.                                 smgbuff[7]=gsmg_code[hour/10];
  195.                                 
  196.                         }
  197.                         smgbuff[3]=gsmg_code[min%10];
  198.                         smgbuff[4]=gsmg_code[min/10];
  199.                 }
  200.                 smgbuff[0]=gsmg_code[sec%10];
  201.                 smgbuff[1]=gsmg_code[sec/10];
  202.         }
  203.                
  204. }



  205. void main()
  206. {
  207.         configtime(1);  //配置一毫秒中断计时
  208.         
  209.         
  210.         while(1)
  211.         {
  212.                 time();
  213.                 keydrive();
  214.         
  215.                
  216.         }
  217.         
  218. }

  219. void interruptmr() interrupt 1
  220. {
  221.         static u16 timer1=0;
  222.         static u16 timer2=0;
  223.         TH0=T0RH;
  224.         TL0=T0RL;
  225.         ledscan();
  226.         keyscan();
  227.         timer1++;
  228.         timer2++;
  229.         if(timer1==1000)
  230.         {
  231.                 timer1=0;
  232.                 secflag=1;
  233.         }
  234.         if(timer2==500)   //此处增加调整时间时,数字的闪烁功能,以判断当前处于调整时间状态。
  235.         {
  236.                 timer2=0;
  237.                         if(sethour==1 )
  238.                 {
  239.                                 if(hourblink==0)
  240.                         {
  241.                                 smgbuff[6]=0x00;
  242.                                 smgbuff[7]=0x00;
  243.                                 
  244.                         }
  245.                         else
  246.                         {
  247.                                 smgbuff[6]=gsmg_code[hour%10];
  248.                                 smgbuff[7]=gsmg_code[hour/10];
  249.                         }
  250.                         hourblink=~hourblink;
  251.                 }
  252.                 else
  253.                 {
  254.                         smgbuff[6]=gsmg_code[hour%10];
  255.                         smgbuff[7]=gsmg_code[hour/10];
  256.                 }
  257.                 if(setmin==1)
  258.                 {
  259.                                 if(minblink==0)
  260.                         {
  261.                                 smgbuff[4]=0x00;
  262.                                 smgbuff[3]=0x00;
  263.                                 
  264.                         }
  265.                         else
  266.                         {
  267.                                 smgbuff[3]=gsmg_code[min%10];
  268.                                 smgbuff[4]=gsmg_code[min/10];
  269.                         }
  270.                         minblink=~minblink;
  271.                 }
  272.                 else
  273.                 {
  274.                         smgbuff[3]=gsmg_code[min%10];
  275.                         smgbuff[4]=gsmg_code[min/10];
  276.                 }
  277.         }
  278. }
复制代码

51hei图片_20260902131344_115_42.jpg (738.6 KB, 下载次数: 0)

普中A4开发板显示

普中A4开发板显示

原理图.jpg (584.29 KB, 下载次数: 0)

原理图

原理图

smgclock.zip

28.47 KB, 下载次数: 0

原理图与程序

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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