继电器数据回环

Tutorial: 电子电路 Category: 嵌入式 Published: 2026-08-29 08:09:36 Views: 0 Likes: 0 Comments: 0

052.6.8 继电器数据回环

#include "reg52.h"
#include <intrins.h>

typedef unsigned char uchar;
typedef unsigned int uint;

uint count = 0;
uchar recv;

sbit LED1 = P1^0;
sbit LED2 = P1^1;
sbit LED3 = P1^2;
sbit LED4 = P1^3;
sbit BEEP = P1^6;
sbit JDQ1 = P2^0;

void Delay_xms(uint xms) //@11.0592MHz
{
    uchar data i, j;

    while (xms)
    {
        _nop_();
        i = 2;
        j = 199;
        do
        {
            while (--j);
        } while (--i);
        xms--;
    }
}

void UART_Send_Byte(uchar send_byte)
{
    SBUF = send_byte;
    while (TI == 0);
    TI = 0;
}

void UART_Send_Str(uchar *send_str)
{
    while (*send_str != '\0')
    {
        UART_Send_Byte(*send_str++);
    }
}

void main()
{
    SCON = 0x50;
    PCON &= 0x7F;
    TMOD &= 0x0F;
    TMOD |= 0x20;
    TH1 = 0xFD;
    TL1 = 0xFD;
    TR1 = 1;
    ES = 1;
    EA = 1; // 打开总中断

    while (1)
    {
        Delay_xms(1000);
    }
}

/*****************
串口的中断处理函数
*****************/
void UART_Routine(void) interrupt 4
{
    if (RI == 1)
    {
        RI = 0;
        recv = SBUF;
        SBUF = recv;
        while (TI == 0);
        TI = 0;
    }
}

一、继电器

1.1 继电器的原理

继电器本质上是一个由电信号控制的机械开关。单片机输出的是低压、小电流控制信号,继电器触点负责接通或切断另一条负载回路,因此可用小信号控制单片机引脚不能直接驱动的负载。

继电器模块应分成三个层次理解:

  1. 控制信号层:单片机的 P2.0 接模块的 IN,决定模块是否触发。
  2. 驱动与线圈层:模块上的限流、反相或放大电路驱动继电器线圈;单片机引脚不直接承担线圈电流。
  3. 触点与负载层COMNONC 是一组机械触点,它们接在独立的负载回路中。

视频中的单路模块采用低电平触发,功能链路如下。模块的具体晶体管接法可能随型号变化,但作用关系相同:

控制侧(低压)

单片机 P2.0
      │
      └── IN ──> 输入限流/反相电路 ──> 线圈驱动管 ──> 继电器线圈
                                              │            │
                                              ├─ 触发指示灯 │
                                              └────续流保护─┘

模块 VCC ──> 线圈和驱动电路供电
模块 GND ──> 与单片机 GND 相连,作为控制信号的共同参考点
  • 输入电阻限制 IN 端电流,保护单片机和驱动器件。
  • 驱动管完成电流放大或电平反相。继电器线圈通常需要的电流高于GPIO适合直接提供的电流,所以不能把裸继电器线圈直接接到 P2.0
  • 续流二极管通常反向并在线圈两端。线圈断电时会产生反向感应电压,二极管为线圈电流提供衰减通路,避免高压尖峰损坏驱动管。
  • 电源指示灯只说明模块已经得到工作电源;触发指示灯说明驱动端进入触发状态。指示灯亮或听到吸合声,并不能完全证明外部负载回路接线正确、触点也一定完好。

视频所用模块的触发关系为:

P2.0/IN状态模块状态线圈状态导通触点
低电平,约 0~1.2 V触发得电吸合COM—NO
高电平未触发失电释放COM—NC

这里的 0~1.2 V 是视频中这块模块标示的低电平范围,不是所有继电器的统一参数。有些模块是高电平触发,有些带光耦或 JD-VCC 独立线圈电源,接线前应以模块丝印和说明书为准。

代码中的 sbit JDQ1 = P2^0; 只是给 P2.0 起了一个便于理解的名字。本讲的数据回环程序没有再给 JDQ1 赋值,因此这段程序本身不执行继电器开关动作。

1.1.1 电磁继电器百度百科

电磁继电器的核心部件包括线圈、铁芯、衔铁、复位弹簧和触点:

线圈失电(释放)                       线圈得电(吸合)

       复位弹簧                              电磁吸力
          ↓                                     ↓
NC ●──────● COM      NO ●              NC ●      ●──────● NO
         动触点                                   动触点
                                                COM

结果:COM 与 NC 导通                    结果:COM 与 NO 导通

工作过程可以分为四步:

  1. 线圈通电后产生磁场,铁芯成为电磁铁。
  2. 电磁力吸引衔铁,使与衔铁相连的动触点发生位移。
  3. 动触点离开 NC,转而接触 NO,负载回路随之切换。
  4. 线圈断电后磁力消失,复位弹簧使衔铁回到静止位置,COM 再次接回 NC

“常开”和“常闭”中的“常”,是指线圈未通电、继电器未吸合的常态,不是指单片机输出高电平或低电平:

触点名称线圈未得电线圈得电
NO(Normally Open,常开)COM 断开COM 导通
NC(Normally Closed,常闭)COM 导通COM 断开
COM(Common,公共端)接向 NC切换到 NO

电磁继电器的线圈侧和机械触点侧在器件内部没有直接导线连接,因而能够实现控制回路与负载回路之间的电气隔离。不过,“继电器有隔离”不等于整块模块在任何条件下都绝对安全:模块是否带光耦、控制电源是否真正分开、PCB爬电距离和外壳防护是否合格,都要单独判断。

1.1.2 继电器插图

视频中的蓝色接线端子标有 NOCOMNC。辨认端子时必须看模块丝印,不能只凭“中间一定是COM”来判断,因为不同模块的端子排列可能不同。

用低压灯理解负载侧接法

对初学者可先用安全的直流低压灯或LED灯模块验证,不要直接进行220V市电实验。例如希望继电器吸合后灯才亮,可使用 NO

12 V 电源正极 ── 保险丝 ── COM
                              \
                               \  线圈吸合后,COM 与 NO 接通
                                NO ── 12 V 灯 ── 12 V 电源负极

单片机侧:P2.0 ── IN      继电器模块:VCC、GND
负载侧:  12 V电源与灯    只经过COM、NO触点

此时的电流通路为:

线圈未吸合:COM 与 NO 断开 → 负载回路无电流 → 灯灭
线圈已吸合:12V+ → 保险丝 → COM → NO → 灯 → 12V- → 灯亮

如果希望设备在继电器未触发时默认工作,触发后停止,则把负载回路改用 COMNCCOM 只是机械开关的公共触点,并不天然等于电源正极、负极或地;它接什么电位由负载回路的设计决定。

控制侧与负载侧的边界

flowchart LR
    A[51单片机 P2.0] -->|低电平触发| B[模块输入与驱动电路]
    B --> C[继电器线圈]
    C -.磁力推动.-> D[机械触点 COM/NO/NC]
    E[独立的负载电源] --> D
    D --> F[灯或其他负载]
    F --> E

虚线表示磁力造成的机械动作,不是控制侧和负载侧之间的导线。继电器适合控制灯、风扇、电磁阀等负载,但选择时必须同时检查:

  • 线圈额定电压是否与模块供电匹配;
  • 触点的交流/直流电压、电流和负载类型是否在额定范围内;
  • 电机、灯丝等负载的启动电流可能远高于稳定工作电流;
  • 继电器有机械寿命和电气寿命,不适合无节制地高速开关。

安全提示: 220V市电可能造成致命触电和火灾。初学阶段只做隔离的低压直流实验。市电控制还涉及保险、接地、阻燃外壳、线径、爬电距离和接线端防触碰等要求,不应仅凭一块裸露继电器模块搭接。

二、数据回环

2.1 继续上节代码

数据回环是指:单片机从串口收到一个字节后,不改变其数值,立即把同一个字节从串口发回。完整路径是:

电脑串口助手
    │ 发送
    ▼
USB转TTL的 TXD ──> 单片机 RXD(P3.0)
                         │
                         ▼
                  接收移位寄存器
                         │ 收满1帧,RI=1
                         ▼
                       SBUF
                         │ 串口中断读取
                         ▼
                       recv
                         │ 再写入SBUF
                         ▼
                  发送移位寄存器
                         │ 发送完成,TI=1
                         ▼
USB转TTL的 RXD <── 单片机 TXD(P3.1)
    │ 接收
    ▼
电脑串口助手显示回传数据

初始化寄存器的作用如下:

语句关键位作用
SCON = 0x50SM0=0, SM1=1串口方式1,8位UART,可变波特率
SCON = 0x50REN=1允许串口接收
PCON &= 0x7FSMOD=0波特率不加倍
TMOD &= 0x0F清除高4位清除定时器1原来的模式设置,不影响定时器0
`TMOD= 0x20`M1=1, M0=0
TH1 = TL1 = 0xFD重装值为253配合11.0592 MHz晶振产生9600 bit/s
TR1 = 1TCON.TR1=1启动定时器1
ES = 1IE.ES=1允许串口中断
EA = 1IE.EA=1打开总中断开关

在串口方式1、SMOD=0、定时器1方式2时:

$ \text{Baud}=\frac{2^{SMOD}}{32}\times\frac{f_{osc}}{12\times(256-TH1)} $

代入 fosc = 11.0592 MHzTH1 = 0xFD = 253

$ \text{Baud}=\frac{1}{32}\times\frac{11059200}{12\times(256-253)}=9600\ \text{bit/s} $

串口中断入口 interrupt 4 由接收标志 RI 和发送标志 TI 共用。本程序的回环过程为:

if (RI == 1)
{
    RI = 0;          // 软件清除接收完成标志
    recv = SBUF;     // 读出刚收到的1字节
    SBUF = recv;     // 把同一字节交给发送硬件
    while (TI == 0); // 等待发送完成
    TI = 0;          // 软件清除发送完成标志
}

SBUF在程序中只有一个名字,但硬件内部的接收缓冲器和发送缓冲器是分开的:读 SBUF 取得接收数据,写 SBUF 启动发送。RITI 都必须由软件清零。

按照常见的 8N1 格式,一个字节在线路上包含1个起始位、8个数据位和1个停止位,共10位。9600 bit/s时传完一帧约需:

$ t_{byte}=\frac{10}{9600}\approx1.04\ \text{ms} $

先接收一帧、再回发一帧,纯线路往返时间至少约为 2.08 ms,还要叠加中断响应、USB转换和串口助手显示延迟。

本例为了直观看到回环,在串口中断里一直等待 TI=1,约占用1 ms。低速、少量数据时可以工作,但工程中通常要求中断服务尽快结束;连续高速接收时,长时间停留在中断中可能造成后续字节来不及处理。更稳妥的方式是中断中只读取 SBUF 并放入缓冲区,再由主循环或发送中断逐字节发送。

还要注意,当前的 UART_Send_Byte()UART_Send_Str() 没有被调用。如果以后在 ES=1 时从主程序使用轮询发送,发送完成也会触发串口中断;届时中断函数必须同时判断并处理 TI,否则可能反复进入串口中断。应统一采用“轮询发送”或“发送中断”中的一种完整策略。

2.2 程序文件打开

下载程序前要先关闭串口助手占用的COM口。一个串口通常不能同时被下载工具和串口助手独占打开;若提示端口打开失败或下载无响应,应先检查串口助手是否仍处于“打开”状态。

经过单片机的数据回环测试

  1. 下载程序后,打开对应COM口,设置为 9600、8位数据位、无校验、1位停止位
  2. 串口助手的发送区和接收区都选择 ASCII,发送字符 a,接收区也应显示 a
  3. 两边都选择 HEX,发送 61,接收区也应显示 61。因为ASCII字符 a 的字节值就是十六进制 0x61
  4. 如果一边选ASCII、另一边选HEX,同一个字节会显示成不同外观;数据并没有因此改变。

视频所用软件以蓝色显示发送、绿色显示接收,这是该串口助手的界面规则,不是串口协议规定的颜色。

USB转TTL自身的硬件回环测试

把USB转TTL模块的 TXDRXD 短接,不连接单片机,即可检查转换模块的基本收发通路:

电脑应用 ──USB──> USB转TTL发送器 ── TXD
                                      │
                                      └──短接线──> RXD
                                                   │
电脑应用 <─USB──── USB转TTL接收器 <────────────────┘

操作时应先确认引脚丝印,只短接 TXDRXD,不要把电源脚与地脚短接。选择正确COM口并打开后,发送任意数据,若接收区出现完全相同的字节,说明USB枚举与驱动、串口助手、转换芯片的基本发送端和接收端大体正常。

在这种自身回环中,没有第二个独立设备使用另一套时钟来解释数据;同一个USB转TTL转换器按照当前配置发送,又按照同一配置接收,所以可在芯片支持范围内换用多种波特率进行测试。波特率仍然参与UART收发,并不是“回环时不需要波特率”。一旦连接单片机或其他串口设备,双方的波特率、数据位、校验位和停止位必须一致。

自身回环成功只能说明转换模块和电脑侧链路基本正常,不能证明以下部分没有问题:

  • 单片机程序与晶振频率;
  • 单片机 TXD/RXD 的交叉接线和共地;
  • 3.3 V、5 V等逻辑电平是否兼容;
  • 外部设备的波特率和帧格式;
  • 继电器模块及其负载回路。

因此排查串口故障时,可先做USB转TTL自身回环,再接入单片机测试。这样能把问题逐步缩小到电脑侧、转换模块、接线或单片机程序中的某一部分。