找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机数码管动态显示有误 前两位是不亮只能隐约看到微亮

[复制链接]
ID:966442 发表于 2022-1-22 19:18 | 显示全部楼层 |阅读模式
20黑币
问题描述:单片机为清翔单片机,其两个四位共阴极数码管由两片74HC573控制,我做的项目是利用矩阵按键做一个简易加法计算器。我认为大致问题是出在数码管显示ShowNumber这个函数。数码管虽然能够正确显示结果,但是在放着单片机不碰它的时候,数码管只有第三位是常亮的,前两位是不亮的,只能不停地按按键才能让前两位数码管一闪一闪从而隐约地能够看到结果。不知道怎么解决请大家帮个忙?

单片机源程序如下:
  1. #include <REGX52.H>
  2. sbit KeyOut1 = P3^0;
  3. sbit KeyOut2 = P3^1;
  4. sbit KeyOut3 = P3^2;
  5. sbit KeyOut4 = P3^3;
  6. sbit KeyIn1 = P3^4;
  7. sbit KeyIn2 = P3^5;
  8. sbit KeyIn3 = P3^6;
  9. sbit KeyIn4 = P3^7;
  10. sbit duan = P2^6;
  11. sbit wei = P2^7;
  12. #define uchar unsigned char
  13. #define uint  unsigned int
  14. #define ulong unsigned long
  15. uchar T0RH,T0RL;
  16. uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
  17. 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  18. uchar KeySta[4][4]={
  19. {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1},
  20. };
  21. uchar code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表
  22. { 0x31, 0x32, 0x33, 0x26 }, //数字键 1、数字键 2、数字键 3、向上键
  23. { 0x34, 0x35, 0x36, 0x25 }, //数字键 4、数字键 5、数字键 6、向左键
  24. { 0x37, 0x38, 0x39, 0x28 }, //数字键 7、数字键 8、数字键 9、向下键
  25. { 0x30, 0x1B, 0x0D, 0x27 } //数字键 0、ESC 键、 回车键、 向右键
  26. };
  27. uchar we[]={0xFE,0xFD,0xFB,0xF7,0xef,0xdf,0xbf,0x7f};
  28. unsigned char LedBuff[6] = { //数码管显示缓冲区
  29. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  30. };
  31. void ConfigTimer0(uint ms)
  32. {
  33.         ulong tmp;
  34.         tmp = 11059200/12;
  35.         tmp = (tmp*ms)/1000;
  36.         tmp = 65536-tmp;
  37.         T0RH = (uchar)(tmp>>8);
  38.         T0RL = (uchar)tmp;
  39.         TMOD &= 0xF0;
  40.         TMOD |= 0x01;
  41.         TH0 = T0RH;
  42.         TL0 = T0RL;
  43.         ET0 = 1;
  44.         TR0 = 1;
  45.         EA = 1;
  46. }
  47. void delay(uchar i)
  48. {
  49.         uchar j,k;
  50.         for(j=i;j>0;j--)
  51.         for(k=125;k>0;k--);
  52. }
  53. void ShowNumber(ulong num)
  54. {
  55.         uchar bai,shi,ge;
  56.         bai = num/100%10;
  57.         shi = num/10%10;
  58.         ge = num/1%10;
  59.         duan = 0;
  60.         P0 = table[bai];
  61.         duan = 1;
  62.         duan = 0;
  63.         wei = 0;
  64.         P0 = we[0];
  65.         wei = 1;
  66.         wei = 0;
  67.         delay(5);
  68.         
  69.         duan = 0;
  70.         P0 = table[shi];
  71.         duan = 1;
  72.         duan = 0;
  73.         wei = 0;
  74.         P0 = we[1];
  75.         wei = 1;
  76.         wei = 0;
  77.         delay(5);
  78.         
  79.         duan = 0;
  80.         P0 = table[ge];
  81.         duan = 1;
  82.         duan = 0;
  83.         wei = 0;
  84.         P0 = we[2];
  85.         wei = 1;
  86.         wei = 0;
  87.         delay(5);
  88. }
  89. void KeyAction(uchar keycode)
  90. {
  91.         static ulong result,addend;
  92.         if((keycode>=0x30)&&(keycode<=0x39))
  93.         {
  94.                 addend = (addend*10)+keycode-0x30;
  95.                 ShowNumber(addend);
  96.         }
  97.         else if(keycode == 0x26)
  98.         {
  99.                 result += addend;
  100.                 addend = 0;
  101.                 ShowNumber(result);
  102.         }
  103.         else if(keycode == 0x0D)
  104.         {
  105.                 result += addend;
  106.                 addend = 0;
  107.                 ShowNumber(result);
  108.         }
  109.         else if(keycode == 0x1B)
  110.         {
  111.                 addend = 0;
  112.                 result = 0;
  113.                 ShowNumber(addend);
  114.         }
  115. }
  116. void KeyDriver()
  117. {
  118.         uchar i,j;
  119.         static uchar backup[4][4]={
  120.         {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1},
  121.         };
  122.         for(i=0;i<4;i++)
  123.         {
  124.   for(j=0;j<4;j++)
  125.   {
  126.     if(backup[i][j]!=KeySta[i][j])
  127.     {
  128.       if(backup[i][j]!=0)
  129.      {
  130.         KeyAction(KeyCodeMap[i][j]);
  131.      }
  132.      backup[i][j] = KeySta[i][j];
  133.    }
  134.   }
  135. }
  136. }
  137. void main()
  138. {
  139.   ConfigTimer0(2);
  140.   while(1)
  141.   {
  142.     KeyDriver();
  143.   }
  144. }
  145. void KeyScan()
  146. {
  147.   uchar i;
  148.   static uchar KeyOut = 0;
  149.   static uchar KeyBuf[4][4]={
  150.   {0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},
  151.   {0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}
  152.   };
  153.   KeyBuf[KeyOut][0] = (KeyBuf[KeyOut][0]<<1)|KeyIn1;
  154.   KeyBuf[KeyOut][1] = (KeyBuf[KeyOut][1]<<1)|KeyIn2;
  155.   KeyBuf[KeyOut][2] = (KeyBuf[KeyOut][2]<<1)|KeyIn3;
  156.   KeyBuf[KeyOut][3] = (KeyBuf[KeyOut][3]<<1)|KeyIn4;
  157.   for(i=0;i<4;i++)
  158.   {
  159.     if((KeyBuf[KeyOut][i]&0x0F)==0x00)
  160.     KeySta[KeyOut][i] = 0;
  161.     else if((KeyBuf[KeyOut][i]&0x0F)==0x0F)
  162.     KeySta[KeyOut][i] = 1;
  163.   }
  164.   KeyOut++;
  165.   KeyOut = KeyOut&0x03;
  166.   switch(KeyOut)
  167.   {
  168.     case 0:KeyOut4=1;KeyOut3=1;KeyOut2=1;KeyOut1=0;break;
  169.     case 1:KeyOut4=1;KeyOut3=1;KeyOut2=0;KeyOut1=1;break;
  170.     case 2:KeyOut4=1;KeyOut3=0;KeyOut2=1;KeyOut1=1;break;
  171.     case 3:KeyOut4=0;KeyOut3=1;KeyOut2=1;KeyOut1=1;break;
  172.     default:break;
  173.   }
复制代码
计算器.rar (33.89 KB, 下载次数: 3)

最佳答案

查看完整内容

你这个思路是正确的。显示函数示例: 需要实时显示的内容存放在缓存中 LedBuff[0]=table[number/100%10]; LedBuff[1]=table[number/10%10]; LedBuff[2]=table[number%10]; 显示函数放在主循环中调用,对于3位数码管动态显示,主循环周期不大于7ms(8位不大于2.5ms),肉眼观察不到闪烁
回复

使用道具 举报

ID:213173 发表于 2022-1-22 19:18 | 显示全部楼层
本帖最后由 wulin 于 2022-1-23 20:52 编辑
电子浪人 发表于 2022-1-23 18:07
我想到了一个方法,就是设一个变量number去储存KeyAction里每个if语句里面的result和addend的值也就是num ...

你这个思路是正确的。显示函数示例:
需要实时显示的内容存放在缓存中
        LedBuff[0]=table[number/100%10];
        LedBuff[1]=table[number/10%10];
        LedBuff[2]=table[number%10];

显示函数放在主循环中调用,对于3位数码管动态显示,主循环周期不大于7ms(8位不大于2.5ms),肉眼观察不到闪烁
  1. void ShowNumber()
  2. {
  3.         static unsigned char i;
  4.         P0=0x00;//段消隐
  5.         duan=1;//锁存
  6.         duan=0;
  7.         P0=we[i];//送位码
  8.         wei=1;//锁存
  9.         wei=0;
  10.         P0=LedBuff[i];//送段码
  11.         duan=1;//锁存
  12.         duan=0;
  13.         i=++i%3;//循环计数
  14. }
复制代码



回复

使用道具 举报

ID:262 发表于 2022-1-22 21:25 | 显示全部楼层
这个是消隐的问题
回复

使用道具 举报

ID:213173 发表于 2022-1-23 08:15 | 显示全部楼层
你这明显是程序结构问题。数码管要不停的循环逐位显示,你把数码管驱动函数放在与按键操作相关函数中调用,每按一下数码管驱动函数只运行一次,当然就停留在最后一位上。
回复

使用道具 举报

ID:966442 发表于 2022-1-23 18:07 | 显示全部楼层
wulin 发表于 2022-1-23 08:15
你这明显是程序结构问题。数码管要不停的循环逐位显示,你把数码管驱动函数放在与按键操作相关函数中调用, ...

我想到了一个方法,就是设一个变量number去储存KeyAction里每个if语句里面的result和addend的值也就是number=addend,或者number=result,然后把ShowNumber这个函数放在mian函数的while里面,其形参就是number,这样就解决了问题
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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