找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

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

查看数: 620 | 评论数: 5 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2026-9-2 13:51

正文摘要:

我用89C51芯片编写了一个简易时钟,功能是用89C51中断计时,然后在8位数码管上显示出来。使用4个按键来对小时与分钟调整,并整合了长短按键功能。程序可以在普中A4开发板顺利运行,所以我贴出来分享给新进者。 但同 ...

回复

ID:1175293 发表于 2026-9-7 15:02
WL0123 发表于 2026-9-4 15:00
你这程序写的实在不敢恭维,给你写一段数码管动态显示驱动代码,仿真没有问题。其他功能你自己添加。

谢谢大神指点。我这程序确实有些乱了。你说的对,我还要继续改进。你的代码看起来很清爽,尤其是代码缩进很有层次感,学习了。我仔细看了一下你的原理图,其实与我的原理图原理相同。不同的是,你是直接连接各个管脚,我是通过标志符来连接的。为了确保是我自己的问题,我又照你的图重新在我电脑上画了一遍,然后又改为标志符连接,均可成功执行程序。在我自己原先的原理图上,怎么修改都不行,只能推倒重画,才去除毛病。
后来,我又参考你与上一位老师的建议,把我的程序修改了一下,把ledscan()函数移到了主循环中,以减少主循环修改时间时,恰好中断发生再执行ledscan()函数撞车的事件,这样一改,果然就解决了我原来数码管乱显示的又一部分问题。
这个经验教训就是1、先搞定显示系统,如果有问题,必要时就需要重新画图,从而减少绘制原理图时就出现的故障。2、逐渐上功能模块,好排查现象毛病。不要一次就求大求全。3、多思考程序有无冲突的地方,减少数据相互干扰。
ID:1175293 发表于 2026-9-7 12:22
zhuls 发表于 2026-9-4 14:20
从仿真图中可以看出,位选没有起作用,重点去查一下位选相关代码。
位选明明是8位,你凭啥只用“(weixuan& ...

谢谢大神指点。本来我以为能看到有人回复,需要好久,没想到这么快就看到了。简单解释下,位选8位,却“weixue&0xe3",  是因为普中A4开发板是用P2.2,P2.3, P2.4通过74HC138来控制数码管的位选信号的。所以我把那weixuan中的三个相应位清0,再把i 值或上去,以达到简化程序的目的。
我提到的这个数码管与点阵显示仿真问题,确实困扰我很久。我觉得应该不是我一个人遇到过。
通过我的排查,代码逻辑应没问题。我认为这仿真图位选没起作用,一是数码管选错了,用成共阴极的,而程序用的是共阳极的逻辑(没有把开发板的程序针对原理图修改完善)。二、估计与程序中有些变量使用pdata设置有关。可能仿真芯片在模拟访问片外内存时干扰到了P0,P2寄存器。不过我在做点阵显示实验时,发现没用pdata设置,也会出现P0口数据被扰乱的情况。三、绘原理图时,就出了了毛病,基础不牢,地动山摇。
感谢你花费宝贵时间来指点。
ID:1133081 发表于 2026-9-4 15:00
你这程序写的实在不敢恭维,给你写一段数码管动态显示驱动代码,仿真没有问题。其他功能你自己添加。


  1. #include<reg51.h>

  2. typedef unsigned char u8;
  3. typedef unsigned int u16;

  4. char hour=12;
  5. char min=30;
  6. char sec=0;
  7. u16 ms;
  8. bit flag;//中断标志
  9. u8 code gsmg_code[] = {
  10. 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  11. 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E,0xbf,0x7f};

  12. u8 smgbuff[8]={0xc0,0xc0,0xbf,0xc0,0xc0,0xbf,0xc0,0xc0};

  13. void InitTimer0(void)//1ms
  14. {
  15.     TMOD= 0x01;
  16.     TH0 = 0xFC;
  17.     TL0 = 0x66;
  18.     EA  = 1;
  19.     ET0 = 1;
  20.     TR0 = 1;
  21. }

  22. void ledscan()
  23. {
  24.         static u8 i=0;
  25.         P0=0xff;
  26.         P2=0x01<<i;
  27.         P0=smgbuff[i];
  28.         i=++i%8;
  29. }

  30. void main()
  31. {
  32.         InitTimer0();               
  33.         while(1)
  34.         {
  35.                 if(flag)
  36.                 {
  37.                         flag=0;
  38.                         ledscan();
  39.                         if(++ms==1000)
  40.                         {
  41.                                 ms=0;
  42.                                 if(++sec>=60)
  43.                                 {
  44.                                         sec=0;
  45.                                         if(++min>=60)
  46.                                         {
  47.                                                 min=0;
  48.                                                 if(++hour>=24)
  49.                                                 {
  50.                                                         hour=0;
  51.                                                 }
  52.                                         }
  53.                                 }
  54.                         }
  55.                         smgbuff[0]=gsmg_code[hour/10];
  56.                         smgbuff[1]=gsmg_code[hour%10];
  57.                         smgbuff[3]=gsmg_code[min/10];
  58.                         smgbuff[4]=gsmg_code[min%10];
  59.                         smgbuff[6]=gsmg_code[sec/10];
  60.                         smgbuff[7]=gsmg_code[sec%10];
  61.                 }
  62.         }       
  63. }

  64. void interruptmr() interrupt 1
  65. {
  66.         TH0 = 0xFC;
  67.         TL0 = 0x66;
  68.         flag= 1;
  69. }
复制代码



ID:69038 发表于 2026-9-4 14:20
从仿真图中可以看出,位选没有起作用,重点去查一下位选相关代码。
位选明明是8位,你凭啥只用“(weixuan&0xe3)”?
常听说仿真能用实物不能用挺愁人的,第一回听说实物能用仿真不能用的。。
或许开发板用的是串转并驱动8位8段,比如595、164、138之类的。
而仿真却是直接用并行驱动8位8段,仿真图中的74HC245可忽略之。
还有,你的中断是个好同志,中断发生时顺便把主循环的事都干完了:
        ledscan();
        keyscan();
        timer1++;
        timer2++;
        if(timer1==1000)。。。。。

总之,Proteus被这锅坑了。。
ID:1175293 发表于 2026-9-4 10:47
我后来弃用P0与P2寄存器,用两个74HC595级联来控制8个数码的段选 与位选,解决了95%的数码管显示乱跳,甚至不显示的故障。文章详见http://www.51hei.com/bbs/dpj-243531-1.html。不过我还是希望有人能够在现有电路原理图基础上帮我解决下问题。

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

Powered by 单片机教程网

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