第18章 RS485通信实验

第十八章 RS485 通信实验

1. 导入

在前面章节中, 我们学习如何使用 51 单片机的串口实现 RS232 通信, 它是一种全双工通信。 这一章我们来学习如何使用 51 单片机串口实现 RS485( 半双工) 通信。

开发板上集成了 RS485 模块, 可实现 RS485 通信。 本章要实现的功能是: 51 单片机通过串口( UART) 使 RS485 实现与 PC 机对话, 51 单片机的串口收到 PC 机发来的数据后原封不动的返回给 PC 机显示。

2. RS485通信介绍

典型的串口通信标准有 RS232 和 RS485, RS232 是全双工点对点的通信,而 RS485 是半双工通信( 2 线制) , 可以一点对多点进行组网, 而且 RS485 是用缆线两端的电压差值来表示传递信号, 这与 RS232 电气特性大不一样。 RS485仅仅规定了接收端和发送端的电气特性, 并没有规定或推荐任何数据协议, 因此RS485 的协议层可以和 RS232 一样。

RS485 推荐使用在点对点, 线型, 总线型网络中, 不能使用在星型和环型网络。

理想情况下 RS485 需要 2 个终端匹配电阻, 其阻值要求等于传输电缆的特性阻抗( 一般为 120Ω ) 。 没有特性阻抗的话, 当所有的设备都静止或者没有能量的时候就会产生噪声, 而且线移需要双端的电压差。 没有接电阻的话, 会使得较快速的发送端产生多个数据信号的边缘, 导致数据传输出错。 RS485 推荐的连接方式如下图所示:

屏幕截图 2024 06 11 111543

在 RS485 通信网络中, 通常会使用 485 收发器来转换 TTL 电平和 RS485 电平。节点中的串口控制器使用 RX 与 TX 信号线连接到 485 收发器上, 而收发器通过差分线连接到网络总线, 串口控制器与收发器之间一般使用 TTL 信号传输, 收发器与总线则使用差分信号来传输。 发送数据时, 串口控制器的 TX 信号经过收发器转换成差分信号传输到总线上, 而接收数据时, 收发器把总线上的差分信号转化成 TTL 信号通过 RX 引脚传输到串口控制器中。 通常在这些节点中只能有一个主机, 剩下的全为从机。 在总线的起止端分别加了一个 120 欧的匹配电阻。

开发板采用 MAX485 作为收发器, 该芯片支持 5V 供电, 最大传输速度可达 10Mbps, 支持多达 32 个节点, 并且有输出短路保护。 该芯片的框图如下图所示:

屏幕截图 2024 06 11 111657

图中 A、 B 为 RS485 总线接口, 用于连接 485 总线。 RO 是接收输出端, DI是发送数据输入端, RE 是接收使能信号( 低电平有效) , DE 是发送使能信号( 高电平有效) 。 因为 RS485 为半双工通信, 通过 RE 和 DE 就能控制发送与接收。

本章我们同样使用 51 单片机的串口跟 PC 机进行 RS485 通信, 这里要特别注意, 因为 PC 机不具有 RS485 接口, 所以我们需要使用一个 RS232/RS485 的转换器, DB9 接口连接 PC 机, RS485 总线接口连接我们开发板上 RS485 模块的A 和 B。 RS232/RS485 转换器如下图所示:

屏幕截图 2024 06 11 111919

只要配置好 51 单片机的串口即可实现 RS485 通信, 串口配置与前面串口通信章节是一样的。

更多关于RS485通信可以参考:终于讲透了,史上最详细的RS485串口通讯!-CSDN博客

3. 硬件设计

本实验使用到硬件资源如下:

  • 串口

  • RS485 收发器: MAX485

串口是 51 单片机内部资源, 只要对其配置即可使用。 下面来看下开发板上的 RS485 模块电路, 如下图所示:

屏幕截图 2024 06 11 112315

从上图中可以看出, 该电路是独立的, 芯片的串口通信管脚以及发送接收选择管脚接至 J56 端子上, 芯片的 RS485 输出管脚 A、 B 接到 J57 端子上。

要实现本章功能, 我们需要使用 2 根导线将开发板上 485 模块的 A 和 B 与RS232/RS485 转换器的 A 和 B 对应连接, 这里一定要注意不能交叉, 否则通信异常。

由于该模块电路是独立的, 所以 MAX485 芯片的发送接收控制管脚可以使用任意单片机管脚, 而 MAX485 芯片的串口通信管脚必须与单片机串口交叉连接,为了与我们例程程序配套, 这里使用 P1.0 管脚来控制 MAX485 芯片的发送和接收选择管脚, 即将 P1.0 管脚连接到 J56 的 RE 上。 当 P1.0 为 0 时, 为接收模式,当 P1.0 为 1 时, 为发送模式。 而 MAX485 芯片的 RXD2 接单片机的 P3.1( TXD)口, MAX485 芯片的 TXD2 接单片机的 P3.0( RXD) 口。

要注意: 因为 STC89C5x 单片机内部只有一个串口, 所以 RS232 和 RS485 不能同时使用, 只能单独使用。 还有就是 USB 转串口模块上也是要接到单片机串口上, 所以在使用单片机串口( 除使用 USB 转串口模块) 时, 比如 WIFI、 蓝牙、GPS、 GSM/GPRS 等应用, 如果遇到通信不正常或者有干扰的情况, 可以把 CH340上的串口短接片拔掉, 这个在上一章串口通信中介绍过。

4. 软件设计

本章所要实现的功能是: 当串口助手发送数据给单片机, 单片机原封不动转发给串口助手显示。

#include <REGX52.H>

//定义控制引脚IO
sbit RS485_DIR = P1^0; // 发送和接收控制

void delay_10us(unsigned int ten_us)
{
    while(ten_us--);    
}

// 串口通信中断配置函数,通过设置TH和TL即可确定定时时间
void uart_init(unsigned char baud)
{
    TMOD|=0X20;    // 设置计数器工作方式2
    SCON=0X50;    // 设置为工作方式1
    PCON=0X80;    // 波特率加倍
    TH1=baud;    // 计数器初始值设置
    TL1=baud;
    ES=1;        // 打开接收中断
    EA=1;        // 打开总中断
    TR1=1;        // 打开计数器        
}

void uart() interrupt 4 //串口通信中断函数
{
    unsigned char rec_data;

    RI = 0;            // 清除接收中断标志位
    rec_data = SBUF; // 存储接收到的数据
    delay_10us(100);
    RS485_DIR = 1; // 配置RS485为发送模式
    SBUF = rec_data; // 将接收到的数据放入到发送寄存器
    while(!TI);     // 等待发送数据完成
    TI = 0;    // 清除发送完成标志位
    RS485_DIR = 0; // 配置RS485为接收模式                
}

void main()
{    
    uart_init(0XFA); // 波特率为9600
    RS485_DIR = 0; // 配置RS485为接收模式
    while(1)
    {            

    }        
}

5. 小结

来吧,还是分析一下,中断配置函数,有了前一章的基础,这还不手到擒来:

// 串口通信中断配置函数,通过设置TH和TL即可确定定时时间
void uart_init(unsigned char baud)
{
    TMOD|=0X20;    // 设置计数器工作方式2
    SCON=0X50;    // 设置为工作方式1
    PCON=0X80;    // 波特率加倍
    TH1=baud;    // 计数器初始值设置
    TL1=baud;
    ES=1;        // 打开接收中断
    EA=1;        // 打开总中断
    TR1=1;        // 打开计数器        
}

这个和前面的串口通信一模一样,重点在后面:

void uart() interrupt 4 //串口通信中断函数
{
    unsigned char rec_data;

    RI = 0;            // 清除接收中断标志位
    rec_data = SBUF; // 存储接收到的数据
    delay_10us(100);
    RS485_DIR = 1; // 配置RS485为发送模式
    SBUF = rec_data; // 将接收到的数据放入到发送寄存器
    while(!TI);     // 等待发送数据完成
    TI = 0;    // 清除发送完成标志位
    RS485_DIR = 0; // 配置RS485为接收模式                
}
  1. RI = 0;
  • 清除串口接收中断标志位,表示接收中断已被处理。
  1. rec_data = SBUF;
  • 从串口接收缓冲区 SBUF 读取接收到的数据。
  1. delay_10us(100);
  • 延迟 100 微秒。这个延迟是为了确保在切换到发送模式之前,接收到的数据已经稳定。具体的延迟时间可能需要根据实际的硬件情况进行调整。
  1. RS485_DIR = 1;
  • 配置 RS485 为发送模式。RS485 通常需要在发送和接收模式之间切换以正确发送和接收数据。
  1. SBUF = rec_data;
  • 将接收到的数据写入到串口发送缓冲区 SBUF,开始发送数据。
  1. while(!TI);
  • 等待发送完成标志位 TI 变为 1,表示数据发送完成。
  1. TI = 0;
  • 清除发送完成标志位,以便下一次数据发送可以正常进行。
  1. RS485_DIR = 0;
  • 配置 RS485 为接收模式,准备接收下一个数据。

2024.7.20 第一次修订

2024.8.21 第二次修订,后期不再维护

posted @ 2024-08-21 16:42  hazy1k  阅读(16)  评论(0编辑  收藏  举报