找回密码
 立即注册

QQ登录

只需一步,快速开始

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

74HC595芯片继电器模块外接电源无法正确控制继电器吸合

[复制链接]
跳转到指定楼层
楼主
各位大神好,小弟用74HC595这个串入并出的芯片控制继电器的吸合,但是继电器的外部三个端子上没有接任何电源的时候是可以正确按照我代码的控制顺序进行继电器的吸合。视频见https://v.youku.com/v_show/id_XNDExMDk2MjUyNA==.html
当外部24V独立DC电源接通后,可以看到在对应的继电器位置,会出现混乱,具体每次表现不一致,但是不能按照24V外部电源不接通的情况进行吸合, 视频见 https://v.youku.com/v_show/id_XNDExMDk2MTM1Mg==.html
这个是因为24V的直流电源对HC595芯片的引脚输出产生了干扰吗?线路检查了很多次,完全没有问题。继电器规格是可以3A 250VAC的,所以这么低的电压应该也不至于影响到继电器的控制信号啊。 希望有经验的大佬指点指点。

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

使用道具 举报

沙发
ID:466164 发表于 2019-3-25 22:27 | 只看该作者
你把接负载后变化频率调低点,或者说把继电器打开关闭时间给长点,再检查你电路继电器线圈上反接有二极管没,这两个建议足以解决你的问题。
回复

使用道具 举报

板凳
ID:475803 发表于 2019-3-25 23:25 | 只看该作者
4个级联的情况也试验了,程序里循环写两组数据,第一组发0xff,0x00,0x00,0xff,然后延时几秒后,第二组数据0x00,0xff,0xff,0x00。 在继电器外部的24VDC电源没有接上的情况下,继电器按照程序设计的进行吸合。视频见https://v.youku.com/v_show/id_XNDEwNTQzODAzNg==.html?spm=a2hzp.8244740.0.0

一旦外部24V直流电源接通,其实就是把正极从继电器的共同端吸合至常开端,接通24V电源控制其他设备。就会出现程序初始化就继电器全部吸合的状态,然后感觉是到了延时函数的时候继电器疯狂的吸合,感觉像是延时函数中的循环在不停的往HC595的DS端写入0和1导致。视频见:https://v.youku.com/v_show/id_XNDEwNTQzOTU5Ng==.html?spm=a2hzp.8244740.0.0

这一周都在反复改代码重新接线调整,但是一直失败。。。是一直失败。。。查了网上说的继电器在断在的时候线圈会产生反向电动势, 关键问题是程序初始化烧入单片机后,都没有断开的步骤直接就全部吸合了。


百思不得其解。望大家指点一二。谢谢!
回复

使用道具 举报

地板
ID:96682 发表于 2019-3-25 23:29 | 只看该作者
上视频不如上电路图。考究的电路都使用独立电源,并采用光电隔离措施避免干扰,视频都没看到这些
回复

使用道具 举报

5#
ID:475803 发表于 2019-3-26 08:22 来自手机 | 只看该作者
7358655 发表于 2019-3-25 22:27
你把接负载后变化频率调低点,或者说把继电器打开关闭时间给长点,再检查你电路继电器线圈上反接有二极管没 ...

继电器买的是封装好的,就是一块595的芯片外加一块驱动继电器的芯片,没有光耦。所以封装好的继电器应该是有反接二极管吧。我看看型号,再查一下。谢谢!
回复

使用道具 举报

6#
ID:475803 发表于 2019-3-26 08:33 来自手机 | 只看该作者
wc86110 发表于 2019-3-25 23:29
上视频不如上电路图。考究的电路都使用独立电源,并采用光电隔离措施避免干扰,视频都没看到这些

接线很简单,所有驱动继电器的12伏电源是独立一组,然后该12伏电源通过板子上的芯片降压然后驱动芯片的vcc,外接继电器的24V也是独立的一组电源。
光电隔离措施是指驱动继电器和hc595芯片之间吗?这个板子是买的现成的,问了老板,他说不需要啊。
回复

使用道具 举报

7#
ID:158375 发表于 2019-3-26 08:54 | 只看该作者
控制几十个继电器都无问题,估计是你的电路有瑕疵,上电路吧!
再个:你的继电器接的什么负载?
回复

使用道具 举报

8#
ID:213173 发表于 2019-3-26 09:03 | 只看该作者
首先要找干扰源,从你表述的现象看是继电器触点开关产生的火花干扰(直流电尤甚)。这种干扰的频谱范围很宽,独立DC电源并不能消除空间辐射干扰。建议:1.在继电器动、静触点间加装阻容吸收电路。2.MCU与74HC595的信号线及信号地线加共模磁环(信号线及信号地线成对),尽量缩短74HC595之间联级信号线及信号地线加共模磁环。3.降低信号传输阻抗(MCU的IO口设为强推挽,信号线与地之间跨接1K电阻)。4.改为光耦隔离,MOS管代替继电器。
回复

使用道具 举报

9#
ID:475803 发表于 2019-3-26 11:40 | 只看该作者
笨笨兔 发表于 2019-3-26 08:54
控制几十个继电器都无问题,估计是你的电路有瑕疵,上电路吧!
再个:你的继电器接的什么负载?

一个负载大概也就是几百mA的电流,不通过继电器用直流的24V正负极直接接负载端没有问题,而且电源功率很足,计算过即使所有板子的继电器同时开也不可满足电流需求。电路我得画一下,刚接触硬件这行业,好多工具还没有。谢谢!
回复

使用道具 举报

10#
ID:475803 发表于 2019-3-26 11:45 | 只看该作者
wulin 发表于 2019-3-26 09:03
首先要找干扰源,从你表述的现象看是继电器触点开关产生的火花干扰(直流电尤甚)。这种干扰的频谱范围很宽 ...

强烈感谢wulin总工您的回复,您说的好多名词我得先搜搜看怎么做。新手入行,要学习的太多了。 真的十分感谢您的耐心指点!
回复

使用道具 举报

11#
ID:123289 发表于 2019-3-27 08:46 | 只看该作者
按沙发的指点做。
回复

使用道具 举报

12#
ID:475803 发表于 2019-3-29 09:50 | 只看该作者
yzwzfyz 发表于 2019-3-27 08:46
按沙发的指点做。

我尝试了把继电器吸合过后的时间调整的很长,大概有5秒左右的时间才会跳转到下一个控制指令,但是吸合的一瞬间如果继电器的外部端子还是有电源接通的话,干扰还是继续存在。我尝试过了吸合后,把外部电源的线轻轻的放在继电器的常开端子上,有时候没干扰,有时候还是会引起其他的继电器打开。负载端反接二极管还没尝试,手边没有二极管,已经下单买了,等收到后试一下。。。谢谢!

回复

使用道具 举报

13#
ID:213173 发表于 2019-3-29 11:20 | 只看该作者
izhonguo 发表于 2019-3-29 09:50
我尝试了把继电器吸合过后的时间调整的很长,大概有5秒左右的时间才会跳转到下一个控制指令,但是吸合的 ...

你既然已经明确的知道干扰源来自继电器触点火花,为什么不在此处设法解决?其它方法都是隔靴搔痒。
回复

使用道具 举报

14#
ID:96682 发表于 2019-3-29 12:48 | 只看该作者
izhonguo 发表于 2019-3-29 09:50
我尝试了把继电器吸合过后的时间调整的很长,大概有5秒左右的时间才会跳转到下一个控制指令,但是吸合的 ...

楼主所谓的独立电源是不是使用同一个电源引出的不同电压?尤其用的是开关电源驱动大负载对整个电路的稳定性影响肯定不小
是在继电器两端并接二极管
回复

使用道具 举报

15#
ID:475803 发表于 2019-4-1 10:29 | 只看该作者
wulin 发表于 2019-3-29 11:20
你既然已经明确的知道干扰源来自继电器触点火花,为什么不在此处设法解决?其它方法都是隔靴搔痒。

嗯嗯,上周按照您的指点,在网上买了排除干扰的一些硬件,但是还没有收到。所以想试试其他的方法是否可以解决。控制单片机的代码现在简化之后,如果通过串口发送数据到单片机执行相应的继电器闭合的话,外部24V接在继电器的外部端子上,竟然没有问题。但是如果直接把数据写死在程序里,就会出现控制的问题。即使发送的是同样的数据。写死在程序里的数据如果要实现两组隔段时间输出的话,中间要加一个延时函数,有没有可能是延时函数导致的单片机输出0/1,从而引起的继电器不受控?

/*-----------------------------------------------
工程名:   STC操作74HC595级联 控制继电器程序
-----------------------------------------------*/
#include <reg51.H>
#define uint unsigned int
#define uchar unsigned char
uint status[5]={00};        //测试程序模式选择
uchar table0[] ="OK\n";        //用于串口助手返回验证
uchar table1[]="ERROR\n";//用于串口助手返回验证
bit flag=0;
uint rnum=5;
/*-----------------------------------------------
STC单片机 硬件设备引脚定义如下
-----------------------------------------------*/
        sbit   OE   = P3^4;           //使能线  
        sbit   SCK  = P3^6;           //时钟线
        sbit   RCK  = P3^7;           //锁存线  
        sbit   DATA = P3^5;           //数据线
        sbit   POWER = P0^0;  //闭合模块总电源继电器,模块通电
        sbit   RPOWER = P0^1;  //闭合模块总电源继电器,模块通电

/*-----------------------------------------------
全部变量函数定义
-----------------------------------------------*/
/*-----------------------------------------------
函数名:初始化程序
-----------------------------------------------*/
/*******************串口初始化函数*************************/
void URATinit()
{  
        PCON &= 0x7F;                //波特率不倍速9600
        SCON = 0x50;                //8位数据,可变波特率
        TMOD= 0x20;                        //设定定时器1为8位自动重装方式
        TL1 = 0xFD;                        //设定定时初值
        TH1 = 0xFD;                        //设定定时器重装值
        ET1 = 0;                           //禁止定时器1中断
        TR1 = 1;                           //启动定时器1
        EA = 1;                            //开总中断
        ES = 1;                            //开串口中断
}

/**********串口发送函数**************/
void SendOneByte(uchar i)
{
    SBUF = i;                //发送数据
    while(!TI);        //等待发送完成
    TI = 0;                        //发送中断请求标志位清0
}

/*-----------------------------------------------
函数名:single 74HC595写入字节函数
-----------------------------------------------*/
void SEND_HC595(uchar dat)
{        
                        uchar i;
                        for(i=0;i<8;i++)
                {
             dat <<= 1;
             DATA  = CY; //溢出位赋值数据输出端
             SCK = 1; //移位时钟
             SCK = 0;
                }
}
/*-----------------------------------------------
函数名:74HC595写入字节函数
-----------------------------------------------*/

void HC595()
{     
                   uchar i,j;
                if(flag==1)
                {
                        for(i=0;i<3;i++)
                {
                    SendOneByte(table0);//返回PC "OK"(用串口助手文本模式接收)
                }
                }
                ES=0;
                for(j=0;j<rnum;j++)
                {
                         SEND_HC595(status[j]);
                }
                RCK=1;
                OE=0;
                RCK=0;
                ES=1;
            flag=0;
}

/*-----------------------------------------------
函数名:main 主函数
-----------------------------------------------*/
void main(void)
{
        POWER = 1;  //闭合模块总电源继电器,模块通电
        RPOWER = 1; //闭合电磁铁模块总电源继电器,模块通电
        OE=1;
        SCK = 0;  //初始化移位时钟端
    RCK  = 0;  //初始化锁存输出端
        URATinit();         //初始化串口
        while(1)
        {
                HC595();
        }
}
/*-----------------------------------------------
函数名:中断函数
-------------------------------------------------*/
void receive() interrupt 4
{
        static uchar i=0;  //静态计数变量
        RI=0;        //接收中断请求标志位清0
        status=SBUF;  //接收到的数据串保存在模式选择中
                if(status[0]==0xAA)
                {
                    i++;
                        if(i>=rnum)
                        {
                          flag=1;
                                i=0;      //计数变量清0
                        }
                }
}
回复

使用道具 举报

16#
ID:475803 发表于 2019-4-1 10:32 | 只看该作者
wc86110 发表于 2019-3-29 12:48
楼主所谓的独立电源是不是使用同一个电源引出的不同电压?尤其用的是开关电源驱动大负载对整个电路的稳定 ...

不是。。独立电源是从220V直接降压到24V的一组电源,控制继电器板子的12V电源也是从220V直接降到12V的一组电源,两个是完全独立的。。只不过都是从插排上接的市电。二极管我买了1A/50V的整流二极管,还没有收到。收到后,我也试试增加是否能排除干扰。谢谢!
回复

使用道具 举报

17#
ID:213173 发表于 2019-4-1 14:51 | 只看该作者
izhonguo 发表于 2019-4-1 10:29
嗯嗯,上周按照您的指点,在网上买了排除干扰的一些硬件,但是还没有收到。所以想试试其他的方法是否可以 ...

这段程序改这样才合理些。
  1. /*-----------------------------------------------
  2. 工程名:   STC操作74HC595级联 控制继电器程序
  3. -----------------------------------------------*/
  4. #include <reg51.H>
  5. #define uint unsigned int
  6. #define uchar unsigned char
  7. #define rnum 5
  8. uint status[5];        //串口接收缓存
  9. uchar table0[] ="OK\n";        //用于串口助手返回验证
  10. uchar table1[]="ERROR\n";//用于串口助手返回验证
  11. bit flag=0;

  12. /*-----------------------------------------------
  13. STC单片机 硬件设备引脚定义如下
  14. -----------------------------------------------*/
  15. sbit   OE   = P3^4;           //使能线  
  16. sbit   SCK  = P3^6;           //时钟线
  17. sbit   RCK  = P3^7;           //锁存线  
  18. sbit   DATA = P3^5;           //数据线
  19. sbit   POWER = P0^0;  //闭合模块总电源继电器,模块通电
  20. sbit   RPOWER = P0^1;  //闭合模块总电源继电器,模块通电

  21. /*-----------------------------------------------
  22. 全部变量函数定义
  23. -----------------------------------------------*/
  24. /*-----------------------------------------------
  25. 函数名:初始化程序
  26. -----------------------------------------------*/
  27. /*******************串口初始化函数*************************/
  28. void URATinit()
  29. {  
  30.         PCON &= 0x7F;                //波特率不倍速9600
  31.         SCON = 0x50;                //8位数据,可变波特率
  32.         TMOD= 0x20;                        //设定定时器1为8位自动重装方式
  33.         TL1 = 0xFD;                        //设定定时初值
  34.         TH1 = 0xFD;                        //设定定时器重装值
  35.         ET1 = 0;                           //禁止定时器1中断
  36.         TR1 = 1;                           //启动定时器1
  37.         EA = 1;                            //开总中断
  38.         ES = 1;                            //开串口中断
  39. }

  40. /**********串口发送函数**************/
  41. void SendOneByte(uchar i)
  42. {
  43.     SBUF = i;                //发送数据
  44.     while(!TI);        //等待发送完成
  45.     TI = 0;                        //发送中断请求标志位清0
  46. }

  47. /*-----------------------------------------------
  48. 函数名:single 74HC595写入1个字节函数
  49. -----------------------------------------------*/
  50. void SEND_HC595(uchar dat)
  51. {        
  52.         uchar i;
  53.         for(i=0;i<8;i++)
  54.         {
  55.                 dat <<= 1;
  56.                 DATA  = CY; //溢出位赋值数据输出端
  57.                 SCK = 1; //移位时钟
  58.                 SCK = 0;
  59.         }
  60. }
  61. /*-----------------------------------------------
  62. 函数名:74HC595写入4个字节函数
  63. -----------------------------------------------*/

  64. void HC595()
  65. {     
  66.         uchar i;
  67.         if(flag==1)
  68.         {
  69.                 flag=0;
  70.                 ES=0;
  71.                 for(i=0;i<3;i++)
  72.                 {
  73.                         SendOneByte(table0);//返回PC "OK"(用串口助手文本模式接收)
  74.                 }
  75.                 for(i=1;i<rnum;i++)
  76.                 {
  77.                         SEND_HC595(status[i]);//输出缓存status[1]~[4]数据
  78.                 }
  79.                 RCK=1;
  80.                 OE=0;
  81.                 RCK=0;
  82.                 ES=1;
  83.         }
  84. }

  85. /*-----------------------------------------------
  86. 函数名:main 主函数
  87. -----------------------------------------------*/
  88. void main(void)
  89. {
  90.         POWER = 1;  //闭合模块总电源继电器,模块通电
  91.         RPOWER = 1; //闭合电磁铁模块总电源继电器,模块通电
  92.         OE=1;
  93.         SCK = 0;  //初始化移位时钟端
  94.         RCK  = 0;  //初始化锁存输出端
  95.         URATinit();         //初始化串口
  96.         while(1)
  97.         {
  98.                 HC595();
  99.         }
  100. }
  101. /*-----------------------------------------------
  102. 函数名:中断函数
  103. -------------------------------------------------*/
  104. void receive() interrupt 4
  105. {
  106.         static uchar i=0;  //静态计数变量
  107.         RI=0;        //接收中断请求标志位清0
  108.         status[i]=SBUF;  //接收到的数据串保存在模式选择中
  109.         if(status[0]==0xff)//验证数据头,后4字节为有效数据
  110.         {
  111.                 i++;
  112.                 if(i>=rnum)
  113.                 {
  114.                         flag=1;
  115.                         i=0;      //计数变量清0
  116.                 }
  117.         }
  118. }
复制代码

回复

使用道具 举报

18#
ID:111634 发表于 2019-4-1 21:13 | 只看该作者
595驱动力不足
回复

使用道具 举报

19#
ID:158375 发表于 2019-4-2 14:40 | 只看该作者
给继电器线圈加反向二极管吧?
看起来你的负载不是感性负载。。。。。。
回复

使用道具 举报

20#
ID:202748 发表于 2019-4-2 15:55 | 只看该作者
你不接24V会正常,说明程序没问题。我估计问题是出在继电器这块板上。你仔细找一找,你接入24V电源的接口是否与电路板的其他地方有相连(比如电路板的正极)。
回复

使用道具 举报

21#
ID:475803 发表于 2019-4-2 19:25 | 只看该作者
wulin 发表于 2019-4-1 14:51
这段程序改这样才合理些。
/*-----------------------------------------------
工程名:   STC操作74H ...

wulin总工,您好,这个代码是我一行一行试出来的,之前按照很完美的逻辑并没有办法运行,我就开始从最简单的步骤一步一步往上加,比如说刚开始简化到只读取程序内写死的一个字节的代码,然后慢慢加到中断,加到四个模块,我估计八个模块也能用,但是板子没那么多,所以只用到了四个模块。之前很完美的程序包含了OK返回逻辑和ERROR返回逻辑,经过我一行一行代码增加去试验,之前我那个代码是目前没有办法消除外部干扰情况下还能达到目的最齐全的了。如果增加了ERROR返回逻辑,又开始报错。同样如果把除了返回OK的代码之外的放进去判断flag==1的逻辑里(就像您写的,不过status和table0应该是后面都忘记了加[ i],更符合逻辑的代码),就会报错。。。这个实在是变成玄学了。这是是一镜哦耶版的视频,真的无法解释了。。https://v.youku.com/v_show/id_XNDEyMjg5NTQ1Mg==.html

我试验出来的代码:(自动发送数据,间隔位1m)


对应继电器状态:


更符合逻辑的代码:


对应继电器的状态:


回复

使用道具 举报

22#
ID:475803 发表于 2019-4-2 19:31 | 只看该作者
笨笨兔 发表于 2019-4-2 14:40
给继电器线圈加反向二极管吧?
看起来你的负载不是感性负载。。。。。。

二极管我买了1A/50V的整流二极管, 但是继电器线圈怎么加方向二极管啊?这个是直接封装好的继电器,只有外部三个端口,共同端COM, 常闭端NC, 常开端NO。是说把NO和COM两个端口加反向二极管?可是这两个端子无所谓正负啊,我就是导通了负载的正极电源线而已,应该没有正反级的说法吧。。负载端我倒是可以试验一下反接二极管,但是还没有收到。。。
回复

使用道具 举报

23#
ID:475803 发表于 2019-4-2 19:33 | 只看该作者

不应该是驱动力不足啊,我看他这个板子上595的输出端口是直接接在了另一块驱动芯片LN2803上,单独一组12V的直流电源驱动的。请看我12楼的电路图。
回复

使用道具 举报

24#
ID:475803 发表于 2019-4-2 19:36 | 只看该作者
ysandi 发表于 2019-4-2 15:55
你不接24V会正常,说明程序没问题。我估计问题是出在继电器这块板上。你仔细找一找,你接入24V电源的接口是 ...

经过过去两周的无数次试验,应该确定是24V的电源接通到继电器的端子上,对内部产生了信号干扰。因为24V的接线是不会接触到板子上的任何电路的,继电器这个动/静触电是唯一接触24V的地方,而且继电器的规格上写的是可以到250V的电压,电流的承载能力应该是我负载的100倍至少。

回复

使用道具 举报

25#
ID:475803 发表于 2019-4-2 19:43 | 只看该作者
ysandi 发表于 2019-4-2 15:55
你不接24V会正常,说明程序没问题。我估计问题是出在继电器这块板上。你仔细找一找,你接入24V电源的接口是 ...

而且板子我买了三家不同的,都是这个问题,可以复现。我这周一尝试了直接用HC595的芯片插面包板上,自己将输出的八个引脚接到一组带光耦分离的继电器板子上,不过我现在还没有能把595面包板上对应的引脚电压给输出正确,程序还是同样的程序,但是烧入单片机之后输出到芯片上拿万用表量并不能实现我控制的引脚高低电平。 我用的是P3^4,P3^5,P3^6,P3^7这几个IO口,但是没有接上拉下拉电阻。
回复

使用道具 举报

26#
ID:475803 发表于 2019-4-2 22:23 | 只看该作者
wulin 发表于 2019-4-1 14:51
这段程序改这样才合理些。
/*-----------------------------------------------
工程名:   STC操作74H ...

奇怪,我回复了一条很长很详细的帖子,但是一直没有出现,我后面回复的几个帖子都通过审核了。。。所以只能靠记忆重新写一次。
代码是我接了继电器的外部电源后发现有问题,从最简单的开始一行一行测试的。这个是我目前能加到最多的逻辑而且能按照我期待的工作的(在没有增加排除干扰的其他硬件的前期下)。之前把其他的执行代码也放在了flag==1的括弧内,但是会出现继电器乱跳的情况。(wulin总工您代码里那个status和table0数组里循环写的时候应该有个在后面吧,可能是笔误)。我重新尝试了复原一遍把执行的代码放进去flag==1的逻辑内,就会出现视频中这种劈里啪啦乱吸的现象,但是我的那个代码是完全相同的情况下,能够按照我想要的结果执行。现在这是变成玄学了嘛?越符合逻辑的代码,反而会出错。我之前还把ERROR这个返回的信息也写进去了,但是无论如何都会报错。具体表现为一旦载入了程序就会立马开始不断收到ERRPR的错误在串口接收的窗口内。一镜哦耶版的视频在这儿,论坛不支持上传视频,所以传在优酷上了,可能有开头广告,抱歉。https://v.youku.com/v_show/id_XNDEyMjg5NTQ1Mg==.html?spm=a2ha1.12675304.uerCenter.5!3~5~5!2~DL~DD~A&amp;firsttime=118.93

为了方便阅读,我截图几张放在帖子里:
1. 之前15楼的不太符合逻辑的代码,自动发送01 02 03 04数组,时间间隔为1s.


2.执行结果(外部24V接通,没有增加任何防干扰的措施):


3.修改为更符合逻辑的代码(发送同样的数据):


4.执行结果(每次开的继电器不一致,截图不够完善,视频看的更清楚):





回复

使用道具 举报

27#
ID:202748 发表于 2019-4-3 08:57 | 只看该作者
izhonguo 发表于 2019-4-2 19:36
经过过去两周的无数次试验,应该确定是24V的电源接通到继电器的端子上,对内部产生了信号干扰。因为24V的 ...

去掉24v电源,就用板上的12V电源引到继电器,串一个小功率负载试试。我经常用继电器控制220V电源,都没出现过这样的问题。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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