找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3512|回复: 6
收起左侧

单片机+74HC595控制数码管位码问题

[复制链接]
ID:709561 发表于 2020-8-9 18:37 | 显示全部楼层 |阅读模式
20黑币
74HC595控制数码管位码,单片机P2控制断码,P10(11脚)P11(12脚)P12(14脚)595功能脚连接,数码管2个4位公阳,单片机 STC89C52。
想过很多程序都无法实现,不是重影就是在单个数码管上显示或乱码,,就是想操作595让它工作,想要实现的功能是【时钟】不带实时时钟芯片,单片机定时器完成。无奈自己刚接触一段时间技艺不精。希望各位大神帮助 给予学习 不胜感激!!!
51hei图片_20200809181603.jpg

最佳答案

回复

使用道具 举报

ID:213173 发表于 2020-8-9 18:37 | 显示全部楼层
无标题.jpg
  1. #include<reg52.h>
  2. #define key_S 15                                        //宏定义短按/消抖(约15ms)
  3. #define key_L key_S*35                        //宏定义长按(约500ms)
  4. #define key_I key_S*27                        //宏定义长按连续+/-间隔(约120ms)
  5. #define uint unsigned int
  6. #define uchar unsigned char

  7. sbit SER  = P1^0;    //数据输入
  8. sbit SCK  = P1^1;    //串行移位时钟
  9. sbit RCK  = P1^2;    //锁存器时钟
  10. sbit key0 = P3^5;
  11. sbit key1 = P3^6;
  12. sbit key2 = P3^7;

  13. uchar code table[]={//共阳数码管段码"0~f-."
  14.                 0xc0,0xf9,0xa4,0xb0,
  15.                 0x99,0x92,0x82,0xf8,
  16.                 0x80,0x90,0x88,0x83,
  17.                 0xc6,0xa1,0x86,0x8e,0xbf,0x7f};
  18. uchar data dis_buf[]={0,0,0xbf,0,0,0xbf,0,0};//显示缓存

  19. char sec=0,fen=0,shi=12;
  20. uchar num=0,KeySec;

  21. void delay_ms(uint z)
  22. {
  23.         uint x,y;
  24.         for(x = z;x>0;x--)
  25.                 for(y=115;y>0;y--);
  26. }
  27. void hc595(uchar Data)//74HC595的数据串入并出子程序
  28. {
  29.         uchar i;            
  30.         for(i=0;i<8;i++)        //由高位到低位发送一个字节
  31.         {
  32.                 Data<<=1;                //左移一位,最高位溢出到位寄存器CY
  33.                 SER=CY;                        //从位寄存器的进位标志位CY读取
  34.                 SCK = 0;                        //串行移位
  35.                 SCK = 1;
  36.         }
  37.    RCK = 0;                         //锁存
  38.    RCK = 1;
  39. }
  40. void key()
  41. {
  42.         static unsigned int time=0;//计数变量
  43.         if(!key0||!key1||!key2)
  44.         {
  45.                 time++;
  46.                 if(time>key_L)//长按有效
  47.                         time=key_I;//连续+/-间隔
  48.                 if(time==key_S)//短按消抖
  49.                 {
  50.                         if(!key0)//调整时、分、秒
  51.                         {
  52.                                 KeySec++;
  53.                                 if(KeySec>3)
  54.                                 {
  55.                                         KeySec=0;
  56.                                         num=0;
  57.                                 }
  58.                         }
  59.                 }
  60.                 if(time==key_S||time==key_L)//短按消抖或长按连+/-
  61.                 {
  62.                         if(!key1 && KeySec!=0)//++
  63.                         {
  64.                                 switch(KeySec)
  65.                                 {
  66.                                         case 1: shi++;if(shi>23)shi=0; break;
  67.                                         case 2: fen++;if(fen>59)fen=0; break;
  68.                                         case 3: sec++;if(sec>59)fen=0; break;
  69.                                 }
  70.                         }
  71.                         if(!key2 && KeySec!=0)//--
  72.                         {
  73.                                 switch(KeySec)
  74.                                 {
  75.                                         case 1: shi--;if(shi<0)shi=23; break;
  76.                                         case 2: fen--;if(fen<0)fen=59; break;
  77.                                         case 3: sec--;if(sec<0)sec=59; break;
  78.                                 }
  79.                         }
  80.                 }
  81.         }
  82.         else time=0;
  83. }

  84. void display(void)
  85. {
  86.         static uchar i=0;
  87.         dis_buf[0]=table[shi/10];
  88.         dis_buf[1]=table[shi%10];
  89.         dis_buf[3]=table[fen/10];
  90.         dis_buf[4]=table[fen%10];
  91.         dis_buf[6]=table[sec/10];
  92.         dis_buf[7]=table[sec%10];

  93.         P2=0xff;                                                //段码消隐
  94.         hc595(0x01<<i);                        //送位码
  95.         if((KeySec==1 && i==1)||(KeySec==2 && i==4)||(KeySec==3 && i==7))
  96.                 P2=dis_buf[i]&0x7f;        //送段码加点
  97.         else P2=dis_buf[i];           //送段码不加点
  98.         i++;
  99.         i%=8;
  100. }
  101. void Timer0Init() //20毫秒@12.000MHz
  102. {
  103.         TMOD= 0x01;                //设置定时器模式
  104.         TL0 = 0xE0;                //设置定时初值
  105.         TH0 = 0xB1;                //设置定时初值
  106.         TF0 = 0;                //清除TF0标志
  107.         TR0 = 1;                //定时器0开始计时
  108.         EA  = 1;                //开总中断
  109.         ET0 = 1;                //开T0中断
  110. }

  111. void main()
  112. {
  113.         Timer0Init();
  114.         while(1)
  115.         {
  116.                 key();
  117.                 display();
  118.                 delay_ms(1);//控制主循环周期约1ms
  119.         }
  120. }

  121. void timer0() interrupt 1
  122. {
  123.         TL0 = 0xE0;
  124.         TH0 = 0xB1;
  125.         num++;
  126.         if(num>=50)
  127.         {
  128.                 num=0;
  129.                 sec++;
  130.                 if(sec>=60)
  131.                 {
  132.                         sec=0;
  133.                         fen++;
  134.                         if(fen>=60)
  135.                         {
  136.                                 fen=0;
  137.                                 shi++;
  138.                                 if(shi>=24)
  139.                                 {
  140.                                         shi=0;
  141.                                 }
  142.                         }
  143.                 }
  144.         }
  145. }
复制代码



回复

使用道具 举报

ID:123289 发表于 2020-8-10 13:26 | 显示全部楼层
逻辑混乱!
1、一个完整的数字,需要你扫完8个全部的段,如果你才扫完3个段,这时发生了改变时间的事件(时间中断),即显示的数字改变了,而你却继续扫描作下的5个段。这时前3个段的数据是原来的,后5个段的数据是新改变的,显示明显就不对了。也就发生了乱闪。我猜每次变秒时,你的显示都会乱闪一下。
2、hc595的移位,当每间隔一个时间(如4ms)移一次,这样才能让它控制的显示每个段(字)显示一定的时间(4ms),而你一下了就全部分移完了,这样你只能将其中的一个段(字)显示一定的时间,其它的7个段一闪而过,根本来不及看。
你还没有真正地理解扫描显示的原理。其它的不合理就不说了。
回复

使用道具 举报

ID:709561 发表于 2020-8-10 19:54 | 显示全部楼层
yzwzfyz 发表于 2020-8-10 13:26
逻辑混乱!
1、一个完整的数字,需要你扫完8个全部的段,如果你才扫完3个段,这时发生了改变时间的事件( ...

是的刚开始就想你所说的一样,逻辑思维不清晰,导致无法完成自己想要的,还是自己的问题!谢谢你的提醒!!
回复

使用道具 举报

ID:709561 发表于 2020-8-10 19:56 | 显示全部楼层

多谢大神,经过你的程序自己有完成了,好多自己之前无法完成的效果,十分感谢!!!
回复

使用道具 举报

ID:849478 发表于 2021-1-4 22:29 | 显示全部楼层
1P1P 发表于 2020-8-10 19:54
是的刚开始就想你所说的一样,逻辑思维不清晰,导致无法完成自己想要的,还是自己的问题!谢谢你的提醒! ...

楼主你好我最近也在学习这个51单片机,就卡到了51单片机HC595底层驱动如何写,看了您的帖子就像看到了希望,不知可否分享一下您的代码
[em02
回复

使用道具 举报

ID:873449 发表于 2021-1-4 22:34 | 显示全部楼层
建议检查一下线路的连接,因为74HC595控制数码管位码这一系列型号都有接触不良的问题
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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