找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

用5个74hc595芯片级联,控制27位数码管,数码管显示闪烁问题

查看数: 5290 | 评论数: 52 | 收藏 1
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2024-4-12 15:49

正文摘要:

用了5个74hc595芯片级联,控制27位数码管,数码管闪烁,怀疑是写入74HC595数据的时间太长导致的,现在很怕是本来硬件设计的缺陷。   我的程序大概是这样的,先用定时器0来计时,再用定时器1来刷新数码管 ...

回复

ID:1110448 发表于 2024-7-29 14:46
27位8段是216段,开方是14.9,不用开方也知道接近256,就是16*16,所以用4片就可以了;
如果不想用4片,也要用少的行列值分频吧,,用8C * 32S 可以降低要求了,其实总数据量是差不多的,只是降低了中断次数
ID:491577 发表于 2024-7-29 12:06
595的额定电流为35ma,大部分应用都是不加限流电阻的,所以595位电流是大于35ma的,短时间不断刷595是没有问题的,如果因为程序卡住595刷新不及时造成某一位长时间超电流导通就会烧595,楼主发现数码管闪烁就是刷新不及时的表现,楼主的程序效率太低,无法及时刷新595造成的,要改程序提高效率。如果楼主在8个595段码脚加上300欧姆以上的限流电阻保证大部分595都好用了。595数据可以同步刷新所以不需要消隐。
ID:1109793 发表于 2024-7-27 15:08
cy009 发表于 2024-7-27 12:55
一、消隐与否,是数码管决定,而不是芯片决定。凡是使用动态扫描的多位数码管显示,都必须消隐。HC164因 ...

可能还是我水平太菜,尝试各种方法,不好使的就是不好使。只用一片都没有问题。级联就各种奇怪现象。用价格较高的就没问题。实际上在嘉立创买过一种,那个LOGO我以前没用过,也就那样吧。级联偶尔也会出现不该有的输出跳动一下。
ID:619259 发表于 2024-7-27 12:55
xiaobendan001 发表于 2024-4-13 07:12
595不是有控制端吗?怎么还消隐?164才需要消隐吧。我用2片595级联输出,发现市场上大部分595都不能用,只 ...

一、消隐与否,是数码管决定,而不是芯片决定。凡是使用动态扫描的多位数码管显示,都必须消隐。HC164因芯片内部无锁存功能,在联级驱动数码管时只能通过复位端清零来实现消隐,属于硬件消隐。HC595内部有锁存功能,可以采用软件消隐,即通过程序关段电平或位电平的方法,也可以采用硬件消隐,即通过复位端清零来实现消隐,但得多用一个IO口。
二、“市场上大部分595都不能用”,这样的结论过于草率,在做案例时遇到问题,应该先考虑程序的问题。我个人做了很多学生竞赛的题目,多次购买并使用了很多的595芯片,驱动流水灯、数码管、LED点阵等,未遇到595损坏不能用的情况。
ID:292903 发表于 2024-7-27 01:11
zhuls 发表于 2024-4-13 09:23
switch(i) //逐位输入数据
        {
        case 0:

哈哈,我也是这样觉得的,第一眼都看麻了
ID:298743 发表于 2024-4-16 19:06
神奇,把long拆分成4个unchar ,12MHZ现在又可以了,之前要用到33MHZ才可以的
ID:298743 发表于 2024-4-16 16:29
yqs138168 发表于 2024-4-15 15:21
24个共阴数码管+5个74HC595,仿真软件为Proteus8.11版本,,,可以正常显示。

真是奇怪了,我将你的8位一组数码管换成两个四位一组的数码管就显示不出来了
ID:332444 发表于 2024-4-16 09:17
很简单的,取消延时语句,测量时间是多少,若时间刚好则可取消延时,若还是时间过多则要考虑修改电路。
ID:57657 发表于 2024-4-16 08:48
27个数码管每个8段共有216段,使用16行16列扫描只需要4个74HC595 最多驱动256个点阵(16*16或32*8)或32位8段数码管。
如果单片机有16个IO口空闲,那么只需要2片74HC595就能驱动,32个IO口空闲一片都不需要(需要IO口支持强推挽模式)。
仿真的动态扫描闪烁可以调整 Minimum Trigger Time 的毫秒参数,具体是否闪烁需要实物验证。
ID:213173 发表于 2024-4-15 17:04
给你一个仿真示例,如果实物效果不好就按10楼建议处理,以留给主函数足够时间运行其它代码。




  1. #include <reg51.H>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. #define ulong unsigned long
  5. sbit P_HC595_SER   = P2^0;
  6. sbit P_HC595_SRCLK = P2^1;
  7. sbit P_HC595_RCLK  = P2^2;
  8. sbit A0=P2^3;
  9. sbit B0=P2^4;
  10. sbit C0=P2^5;
  11. uchar code table[]={
  12. // 0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
  13.   0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
  14. //  G   H    J    K    L    M    N    o    P     Q    r   t   
  15.   0x3d,0x76,0x1E,0x70,0x38,0x37,0x54,0x5C,0x73,0x67,0x50,0x78};
  16. ulong num=0xfffffffe;
  17. bit flag;//标志

  18. /**************** 向HC595发送一个字节函数 ******************/
  19. void Send_595(uchar dat)
  20. {               
  21.         uchar i;
  22.         for(i=0;i<8;i++)
  23.         {
  24.                 dat <<= 1;
  25.                 P_HC595_SER  = CY; //溢出位赋值数据输出端
  26.                 P_HC595_SRCLK = 1; //移位时钟
  27.                 P_HC595_SRCLK = 0;
  28.         }
  29. }
  30. /**************** 向HC595发送5个字节驱动码 ******************/
  31. void DisplayScan()
  32. {       
  33.         static uchar i;

  34.         Send_595(num>>24);//向HC595发送位码
  35.         Send_595(num>>16);//向HC595发送位码
  36.         Send_595(num>>8);//向HC595发送位码
  37.         Send_595(num);   //向HC595发送位码
  38.         Send_595(table[i]);//向HC595发送段码
  39.         P_HC595_RCLK = 1;//锁存输出数据
  40.         P_HC595_RCLK = 0;
  41.         num=num<<1|0x01;
  42.         if(++i>=27)
  43.         {
  44.                 num=0xFFFFFFFE;
  45.                 i=0;
  46.         }
  47. }

  48. void InitTimer0(void)//740us
  49. {
  50.     TMOD = 0x01;
  51.     TH0 = 0x0FD;
  52.     TL0 = 0x1C;
  53.     EA = 1;
  54.     ET0 = 1;
  55.     TR0 = 1;
  56. }

  57. void main()
  58. {
  59.         P_HC595_SRCLK = 0;//初始化移位时钟端
  60.         P_HC595_RCLK  = 0;//初始化锁存输出端
  61.         InitTimer0();
  62.         while(1)
  63.         {
  64.                 if(flag)
  65.                 {
  66.                         flag=0;
  67.                         DisplayScan();
  68.                         //其它程序
  69.                 }
  70.         }
  71. }
  72. void Timer0Interrupt(void) interrupt 1
  73. {
  74.         TH0 = 0xFD;
  75.         TL0 = 0x1C;
  76.         flag=1;
  77. }
复制代码




ID:33145 发表于 2024-4-15 15:58
数码管仿真模型参数修改

数码管仿真模型参数修改.jpg (142.7 KB, 下载次数: 238)

数码管仿真模型参数修改.jpg
ID:33145 发表于 2024-4-15 15:49
yqs138168 发表于 2024-4-15 15:26
看看我的程序,新思路,与你的写法不一样,效率高很多

还有一种方案,使用专用显示驱动芯片,例如MAX7219
ID:384109 发表于 2024-4-15 15:34
看代码,你是对595的使用有误解吧
ID:33145 发表于 2024-4-15 15:28
asdadqw2 发表于 2024-4-15 15:22
大佬能不能指点一下想法吗,我觉得我的switch虽然累赘,但是应该不影响程序执行效率,然后就到消隐和写入 ...

51单片机处理大的数值(特别是32位)或浮点数,效率都很低,尽可能使用char数据或位数据,提高效率,,,
ID:33145 发表于 2024-4-15 15:26
asdadqw2 发表于 2024-4-15 15:22
大佬能不能指点一下想法吗,我觉得我的switch虽然累赘,但是应该不影响程序执行效率,然后就到消隐和写入 ...

看看我的程序,新思路,与你的写法不一样,效率高很多
ID:298743 发表于 2024-4-15 15:22
yqs138168 发表于 2024-4-15 15:16
可以尝试提高程序的效率,我用仿真24个数码管,没问题。

大佬能不能指点一下想法吗,我觉得我的switch虽然累赘,但是应该不影响程序执行效率,然后就到消隐和写入595的程序了,写入595的程序,我在网上找资料也只找到我这种写法,实在没什么头绪了
ID:33145 发表于 2024-4-15 15:21
24个共阴数码管+5个74HC595,仿真软件为Proteus8.11版本,,,可以正常显示。

24位数码管显示_74HC595X5.rar

93.32 KB, 下载次数: 10

ID:33145 发表于 2024-4-15 15:16
可以尝试提高程序的效率,我用仿真24个数码管,没问题。
ID:1109793 发表于 2024-4-15 14:22
asdadqw2 发表于 2024-4-15 13:37
怎么用软件模拟,我也去试下,能说一下怎么模拟的吗

就是在keil里面进入调试状态,设好断点,记录时间。
ID:298743 发表于 2024-4-15 13:37
xiaobendan001 发表于 2024-4-15 09:27
刚软件模拟了一下,连续输出5片的数据时间小于250us,完全可以用的。

怎么用软件模拟,我也去试下,能说一下怎么模拟的吗
ID:298743 发表于 2024-4-15 13:27
  1. void led_hc595_drive(unsigned char dat1,unsigned char dat2,unsigned char dat3,unsigned char dat4,unsigned char datL)
  2. {
  3.         unsigned char i;
  4.         unsigned char temp;
  5.         unsigned char temp2;
  6.         temp = dat1;
  7.         for(i = 0;i<8;i++)
  8.         {
  9.                 if(temp >= 0x80)   
  10.                 {
  11.                         HC595_DS = 1;
  12.                 }
  13.                 else
  14.                 {
  15.                         HC595_DS = 0;
  16.                 }
  17.                 HC595_SH_CP = 0;
  18.                 HC595_SH_CP = 1;
  19.                 temp  <<=1;
  20.         }
  21.         temp = dat2;
  22.         for(i = 0;i<8;i++)
  23.         {
  24.       
  25.                 if(temp >= 0x80)   
  26.                 {
  27.                         HC595_DS = 1;
  28.                 }
  29.                 else
  30.                 {
  31.                         HC595_DS = 0;
  32.                 }
  33.                 HC595_SH_CP = 0;
  34.                 HC595_SH_CP = 1;
  35.                 temp  <<=1;
  36.         }
  37.         temp = dat3;
  38.         for(i = 0;i<8;i++)
  39.         {
  40.          
  41.                 if(temp >= 0x80)   
  42.                 {
  43.                         HC595_DS = 1;
  44.                 }
  45.                 else
  46.                 {
  47.                         HC595_DS = 0;
  48.                 }
  49.                 HC595_SH_CP = 0;
  50.                 HC595_SH_CP = 1;
  51.                 temp  <<=1;
  52.         }
  53.         temp = dat4;
  54.         for(i = 0;i<8;i++)
  55.         {
  56.      
  57.                 if(temp >= 0x80)   
  58.                 {
  59.                         HC595_DS = 1;
  60.                 }
  61.                 else
  62.                 {
  63.                         HC595_DS = 0;
  64.                 }
  65.                 HC595_SH_CP = 0;
  66.                 HC595_SH_CP = 1;
  67.                 temp  <<=1;
  68.         }
  69.         temp2 = datL;
  70.         for(i = 0;i<8;i++)
  71.         {
  72.   
  73.                 if(temp2 >= 0x80)
  74.                 {
  75.                         HC595_DS = 1;
  76.                 }
  77.                 else
  78.                 {
  79.                         HC595_DS = 0;
  80.                 }
  81.                 HC595_SH_CP = 0;
  82.                 HC595_SH_CP = 1;
  83.                 temp2  <<=1;
  84.         }
  85.         HC595_ST_CP = 0;
  86.         HC595_ST_CP = 1;

  87.         HC595_SH_CP = 0;
  88.         HC595_ST_CP = 0;
  89.         HC595_DS = 0;

复制代码
ID:1109793 发表于 2024-4-15 13:22
asdadqw2 发表于 2024-4-15 11:40
这个的写法,跟我的差不多一样把,我没看出什么区别,原谅我新手不太懂

应该是可以的,我这用22.1184的晶振
ID:161164 发表于 2024-4-15 13:20
asdadqw2 发表于 2024-4-15 11:27
我也是小白,刚刚试过改了一下long的数据分成四个,再把频率改为33.1776 就显示正常了

贴上来看看
ID:298743 发表于 2024-4-15 11:49
zhuls 发表于 2024-4-13 09:23
switch(i) //逐位输入数据
        {
        case 0:

我的想法 是switch的执行效率应该不低吧,只是占用的代码位置多而已,执行起来应该直接到相应的case里,效率来说应该还行吧。(纯新手,刚接触,希望大佬能解答一下)
ID:298743 发表于 2024-4-15 11:40
xiaobendan001 发表于 2024-4-15 09:32
这是另外一个用了3片,一片显示数据,2片输出驱动。但是这个显示的位选是用IO的。为了配合,还是加了消隐的 ...

这个的写法,跟我的差不多一样把,我没看出什么区别,原谅我新手不太懂
ID:298743 发表于 2024-4-15 11:31
xiaobendan001 发表于 2024-4-15 09:27
刚软件模拟了一下,连续输出5片的数据时间小于250us,完全可以用的。

难道是仿真软件的问题?我在仿真软件运行这个就有闪烁
ID:298743 发表于 2024-4-15 11:27
xiaoyao166ny 发表于 2024-4-12 22:00
小白一个 高手勿喷     增加时钟频率 可以吗

我也是小白,刚刚试过改了一下long的数据分成四个,再把频率改为33.1776 就显示正常了
ID:298743 发表于 2024-4-15 11:26

能说一下怎么补偿的思路吗,我在网上找不到相关资料
ID:1109793 发表于 2024-4-15 09:32
这是另外一个用了3片,一片显示数据,2片输出驱动。但是这个显示的位选是用IO的。为了配合,还是加了消隐的,先关了COM,更新数据后再打开。
  1. OP = 0;                                        //锁定输入输出
  2. dqd(OUT[0]);                //显示
  3. dqd(OUT[1]);                //OUT_1-8=>7-0
  4. dqd(OUT[2]);                //OUT_9-16=>7-0
  5. OP = 1;                                //更新输出,上升沿有效
复制代码
  1. void dqd(uchar da){
  2. //SBUF = da;
  3. //while(!TI){};
  4. //TI = 0;
  5. uchar i = 8;
  6. while(i){
  7.         MC = 0;
  8.         if(da&0x01 == 1){
  9.                 MD = 1;
  10.                 }else{
  11.                 MD = 0;
  12.                 }
  13.         da>>=1;
  14.         _nop_();_nop_();
  15.         _nop_();_nop_();
  16.         MC = 1;
  17.         _nop_();_nop_();
  18.         _nop_();_nop_();
  19.         i--;
  20.         }
  21. }
复制代码
ID:1109793 发表于 2024-4-15 09:27
刚软件模拟了一下,连续输出5片的数据时间小于250us,完全可以用的。
ID:1109793 发表于 2024-4-15 09:19
cy009 发表于 2024-4-15 08:47
1.595两片联级,一片传段码,一片传位码,可以不用消隐。楼主的案例是5个595,段码共用,不消隐不行呵。
...

1,两片显示8位和5片显示32位难道不一样吗?为啥2片不用消隐,5片就要?
2,你说的是那个二极管吗?当然有啊
ID:1109793 发表于 2024-4-15 09:16
asdadqw2 发表于 2024-4-15 08:38
我在仿真上面的结果595级联是可以正常输出,有异常的话,你可以用keil单步调试,查看各个变量的值是怎么 ...

都说了,好的芯片是没问题的,板子不是很多,10多年前一次性买了一整盘,用了10多年,一直正常的。好不容易用完了,再买就出问题了,后级某个输出会偶尔跳动。并且几个月后会完全损坏。于是重新购买,包括在立创商城也买过,结果都不行,有的甚至直接错位输出,最后买到一种,上面的LOGO类似><的。就没问题了。我也是纳闷,这样古老的一个东西,而且大量被使用在LED点阵上面,居然还有问题。
ID:619259 发表于 2024-4-15 08:47
xiaobendan001 发表于 2024-4-15 07:30
大哥,我不是用来显示的,我是用来扩展输出的,2片级联16个输出推动三极管+继电器。这个有使能端,还有RC ...

1.595两片联级,一片传段码,一片传位码,可以不用消隐。楼主的案例是5个595,段码共用,不消隐不行呵。
2.你用595扩展输出驱动三极管+继电器,继电器电路有反峰保护吗?
ID:298743 发表于 2024-4-15 08:38
xiaobendan001 发表于 2024-4-13 07:12
595不是有控制端吗?怎么还消隐?164才需要消隐吧。我用2片595级联输出,发现市场上大部分595都不能用,只 ...

我在仿真上面的结果595级联是可以正常输出,有异常的话,你可以用keil单步调试,查看各个变量的值是怎么变化的,来查出原因
ID:1109793 发表于 2024-4-15 07:30
cy009 发表于 2024-4-14 22:27
不能怪595不好,是你没消隐造成

大哥,我不是用来显示的,我是用来扩展输出的,2片级联16个输出推动三极管+继电器。这个有使能端,还有RCK,就算显示也没必要消隐吧,把数据更新到芯片,然后RCK给个上升沿,把每个芯片的数据更新到输出脚上去,这样不行吗?消隐我觉得是比如164没有RCK这种功能,在更新数据过程中每个脚都被实时更新,状态不是想要的,此时先关闭显示,等更新完成再打开,这样显示比较干净。
ID:619259 发表于 2024-4-14 22:27
xiaobendan001 发表于 2024-4-13 07:12
595不是有控制端吗?怎么还消隐?164才需要消隐吧。我用2片595级联输出,发现市场上大部分595都不能用,只 ...

不能怪595不好,是你没消隐造成
ID:619259 发表于 2024-4-14 17:19
27个数码管采用动态扫描,理论上是可以实现无闪显示。动态扫描刷新频率理论上不低于50Hz,能达到100Hz为最佳,扫描周期即为20-10ms。若取中间值15ms,每个数码管刷新时间为0.56ms,经仿真可以成功稳定显示,因多位数码管共用段端口,程序必须加上消隐。
ID:1109793 发表于 2024-4-14 10:33
Hephaestus 发表于 2024-4-14 10:25
大面积敷地可以改善问题。

截图里面蓝色就是铺地啊,实际上之前的板子是没有的,就是因为芯片问题才铺了,结果没什么卵用
ID:1109793 发表于 2024-4-14 10:32
perseverance51 发表于 2024-4-14 10:17
74hc595也是分型号的,例如74HC595A和75HC595D,它们使用都是存在差异,外部的硬件电路可能都不同,具体参 ...

百度了一下,只是封装不一样而已。而且几个品牌如果只用一片都好使,其中最差的一个大概在几个月后会坏掉。较好的则针对自己同品牌可以用级联,但是也不稳定,偶尔出现意外的跳动,时间短的只能在LED上看到,但是继电器没有动作,长的就能听到继电器有声音,虽然强电输出也看不到,但是我认为这会影响继电器的寿命。只有一个牌子的可以,级联信号送个其他品牌都能正常稳定的输出。用示波器看了,实在看不出来问题。但是就是不好使,软件上面调整了各种顺序和延时,会略有改善,无法根除。
ID:883242 发表于 2024-4-14 10:25
xiaobendan001 发表于 2024-4-14 07:08
麻烦帮我看看这个要怎么改才能正常使用其他品牌的595.

大面积敷地可以改善问题。

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

Powered by 单片机教程网

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