基于STM32F103和HC-SR04的12路RS485与Modbus通信方案
引言:
随着科技的快速发展,智能汽车技术已成为汽车工业的一个重要发展方向。在智能汽车的众多技术中,环境感知系统扮演着至关重要的角色。超声波雷达作为环境感知系统中的一种低成本、高可靠性的传感器,广泛应用于车辆的自动泊车辅助、障碍物检测以及距离测量等功能。
·
当前,智能汽车上普遍配置有12路超声波雷达,这些雷达通过内置的微控制器(MCU)直接输出数字化的测距结果。为了实现数据的高效传输和设备的互联互通,通常采用串口RS485作为硬件接口,并使用Modbus协议作为通信协议。RS485以其差分信号传输方式,提供了良好的抗干扰性能和较长的传输距离,而Modbus协议则以其标准化、简单性和灵活性,成为工业自动化领域广泛采用的通信标准。
·
本实验旨在设计并实现一款基于STM32F103微控制器和HC-SR04超声波模块的12路车载超声波雷达系统。系统将采用RS485作为物理通信接口,并实现Modbus协议以支持设备间的通信。通过本实验,我们不仅能够深入理解超声波雷达的工作原理和Modbus通信协议,还能够掌握微控制器编程、硬件设计、系统集成以及测试验证等关键技术。
·
希望你在本次学习过后,能够有一定的收获!!!
推荐歌曲–认真的雪–薛之谦
冲啊!!!! ٩(͡๏̯͡๏)۶ ٩(͡๏̯͡๏)۶ ٩(͡๏̯͡๏)۶
文章目录
- 基于STM32F103和HC-SR04的12路RS485与Modbus通信方案
- 一、任务介绍
- 二、RS232介绍
- 三、RS485介绍
- 四、RS485与RS232不同
- 五、Modbus协议是什么
- 六、整体设计
- 硬件设计
- 软件设计
- 具体实现步骤
- 硬件连接
- 软件开发
- 代码示例
一、任务介绍
- 理解RS485与RS232之间的差距
- 了解Modbus协议
- 对外提供RS485和Modbus协议,采用 stm32F103+HC-SR04超声波模块,完成12路车载超声波雷达的设计
二、RS232介绍
-
RS232的历史:
- 起源:RS232由美国电子工业协会(EIA)在1962年发布,是数据终端设备(DTE)和数据电路端接设备(DCE)之间的电气/机械接口标准。
- 命名:“RS”代表“Recommended Standard”(推荐标准),“232”是标准标识号。
- 改版:RS232经历了多次更新:
- 1969年发布了RS232-C版本。
- 1986年发布了RS232-D版本。
- 1991年发布了RS232-E版本。
- 1997年发布了RS232-F版本,目前广泛应用于工业自动化领域。
-
RS232的接口:
-
25针接口:早期的RS232使用25针的串行接口,其中公头(Male)用于DTE设备,母头(Female)用于DCE设备。
-
9针接口:RS232-F版本简化为9针串口,以适应现代设备,减少不必要的针脚。
-
针脚定义:每个针脚都有特定功能,如TxD(发送数据)、RxD(接收数据)、DTR(数据终端就绪)、DSR(数据集就绪)等。
如下图所示:
实物如下图所示:
针脚定义见下面的表格:
编号 名称 缩写 1 Shield/屏蔽 2 Transmitted Data/发送数据 TxD 3 Received Data/接收数据 RxD 4 Request To Send/请求发送 RTS 5 Clear To Send/允许发送 CTS 6 DCE Ready/Data Set Ready数据集就绪 DSR 7 Signal ground/common return信号接地 SG 8 Received line signal detector 9 Reserved for data set testing/保留 10 Reserved for data set testing/保留 11 Unassigned/未分配 12 Secondary received line signal detector 13 Secondary Clear To Send (S)CTS 14 Secondary Transmitted Data (S)TxD 15 Transmission signal element timing 16 Secondary Received Data (S)RxD 17 Receiver Signal Element Timing(DCE) 18 Local Loopback 19 Secondary Request To Send (S)RTS 20 DTE Ready/Data Terminal Ready DTR 21 Remote Loopback/Signal Quality Detector 22 Ring Indicator RI 23 Data Signal Rate Selector 24 Transmit signal element timing (DTE) 25 Test Mode 25针串口针脚太多,用起来比较繁琐。为了简化RS232串口,在F版本中定义了9针串口,同样包括公头(用于DTE)和母头(用于DCE)两种,如下图所示:
针脚定义见下面的表格:
编号 名称 缩写 1 Data Carrier Detect/数据载波监测 DCD 2 Received Data/接收数据 RxD 3 Transmitted Data/发送数据 TxD 4 Data Terminal Ready/数据终端就绪 DTR 5 Ground/接地 GND 6 Data Set Ready/数据集就绪 DSR 7 Request To Send/请求发送 RTS 8 Clear To Send/允许发送 CTS 9 Ring Indicator/振铃提示 RI
-
-
RS232的电气信号:
- 信号表示:RS232的电信号是相对于地线(GND)的电压信号。
- 逻辑“0”:电压在+3V到+15V之间,表示二进制的“0”。
- 逻辑“1”:电压在-3V到-15V之间,表示二进制的“1”。
- 未定义区域:电压在-3V到+3V之间,这个范围内的电压没有具体定义。
-
RS232的电平转换芯片:
- TTL电平:单片机等设备通常使用TTL电平,需要转换为RS232电平才能进行通信。
- 转换芯片:使用如MAX3232或ST3232等电平转换芯片来实现TTL电平到RS232电平的转换。
-
RS232的数据传输:
-
波特率:定义为单位时间内传输的位数,单位是bit/s(bps),常见的波特率有9600、38400、115200等。
-
数据帧结构
:RS232的数据帧由起始位、数据位、校验位、停止位组成。
- 起始位:1位,逻辑0,表示数据帧开始。
- 数据位:通常为7或8位,表示实际传输的数据。
- 校验位:0位(无校验)或1位(奇校验或偶校验)。
- 停止位:1位、1.5位或2位,逻辑1,表示数据帧结束。
-
传输速率计算:以波特率9600bps、数据位8位、无校验位、停止位1位为例,数据帧长度为10位,实际数据传输速率为960字节/秒。
-
假设某RS232通信设置数据位=7,奇校验,停止位=2,则帧和逻辑值如下图所示:
-
-
应用领域:
- RS232在工业自动化领域中用于连接触摸屏、读卡器、扫码枪、打印机等设备与PLC(可编程逻辑控制器)。
-
连接方式:
- 直连:DTE与DCE设备通信时,使用直连方式。
- 交叉连接:两个DTE设备通信时,使用交叉连接方式。
- 最小连接:仅使用TxD、RxD和GND三根线进行通信,也称为“null modem”连接。
三、RS485介绍
RS-485是一种工业领域广泛应用的通信接口,以下是对RS-485的详细介绍:
- 定义和起源
RS-485是美国电子工业协会(EIA)在1983年批准的一种推荐标准(Recommended Standard),编号为485。它也被称为ANSI/TIA/EIA-485,其中包含标准协会名称的缩写。
- 电气特性
RS-485使用差模传输,这与共模传输相对。差模传输可以有效抵消共模干扰,因为差模传输的信号+和信号-相位相反,理想情况下共模噪声在两条线上等幅同相存在,接收端相当于一个减法器,可以抵消噪声。
- 电气参数
- 共模电压范围:-7V至+12V。
- 多点拓扑连接:支持最多32个设备连接。
- 传输速率:使用40英尺(约12米)线缆时,可达10Mbps;使用4000英尺(约1219米)线缆时,可达100kbps。
- 通信方式:半双工,即在同一时刻设备要么接收数据,要么发送数据,不能同时进行。
- 差分电压容限:最小200mV,即接收端在差分电压低于200mV时就无法正确识别0/1。
- 接口电路
RS-485通信通常通过UART(通用异步收发传输器)接口与电平收发器相连。接口电路设计需要考虑UART与RS-485电平收发器的兼容性。
- 驱动能力
电气参数里总结说RS-485最大电气驱动能力,在多点网络拓扑结构下,可最大驱动32个站点,每个站点的接收电路具有12kΩ的标准等效输入阻抗。
下面这个图就是所谓的多点网络拓扑,所有的站点都是沿着双绞线的排布并接在总线上的。
- 数据监控
可以通过USB转RS-485转换线或软件监控总线上的所有报文。
- 应用设计
设计时需要考虑端接、接口芯片选择和隔离设计:
- 端接设计:由于RS-485采用双绞线传输,需要端接电阻以匹配特征阻抗,减少信号反射。
- 接口设计:选择与使用的处理器电平兼容的RS-485收发器芯片。
- 隔离设计:采用隔离技术降低接地噪声,提高系统稳定性。
四、RS485与RS232不同
这两者之间的差距,体现在一下的几个方面。
- 接口的电子特性
RS232
- 信号电平:RS232接口采用较高的信号电平,其中信号“1”(逻辑"0")为-3V至-15V,信号“0”(逻辑"1")为+3V至+15V。
- 兼容性问题:RS232的信号电平与TTL(晶体管-晶体管逻辑)电平不兼容,TTL电平通常定义为逻辑"0"小于0.8V,逻辑"1"大于2.0V。因此,要实现与TTL电路的连接,需要使用电平转换电路。
- 抗干扰能力:RS232接口的抗干扰能力相对较差,容易受到电磁干扰的影响。
RS485
- 信号电平:RS485传输使用差分信号,逻辑"1"由两线间的电压差+(2-6)V表示,逻辑"0"由电压差-(2-6)V表示。
- 芯片保护:RS485的接口信号电平较RS232为低,减少了对接口电路芯片的损害风险。
- 兼容性优势:RS485的电平与TTL电平兼容,方便与TTL电路直接连接,无需额外的电平转换。
·
- 通讯距离长短
RS232
- 传输距离:RS232的传输距离相对有限,标准最大传输距离为15米。
- 通讯方式:RS232仅支持点对点通讯,不适合构建网络。
- 传输速率:在最大传输距离下,最大传输速率为20kB/s。
RS485
- 传输距离:RS485的最大无线传输距离可达1200米,远超过RS232。
- 传输速率:在100Kb/s的传输速率下,RS485能够实现最大通信距离;最大传输速率可达10Mbps。
- 传输增强:通过使用阻抗匹配和低衰减的专用电缆,传输距离可以延长至1800米。
- 中继器应用:超过1200米时,可以通过添加中继器(最多8只)来扩展传输距离,理论上可接近10Km。
·
- 能否支持多点通讯
RS232
- 多点通讯:RS232接口在总线上仅支持连接一个收发器,不具备多点通讯的能力,限制了其在设备网络构建中的应用。
RS485
- 多点通讯:RS485接口允许在总线上连接多达128个收发器,具备强大的多点通讯能力。
- 设备网络:利用RS485接口,用户可以方便地建立起复杂的设备网络,增强了系统的扩展性和灵活性。
·
- 通讯线的差别
RS232
- 线缆类型:RS232通常使用三芯双绞线或三芯屏蔽线,适用于短距离通信。
- 应用场景:尽管RS232的最大传输距离较短(约15米),但它在多种设备连接中仍然发挥着重要作用,如监控系统、设备升级和调试等。
- 与USB的结合:随着USB端口的普及,出现了许多USB到RS232的转换装置,这不仅扩展了USB的用途,也解决了USB接口不能远距离传输的问题。
RS485
- 线缆类型:RS485可以使用两芯双绞线或两芯屏蔽线,适合高速和长距离通信。
- 高速通信:在高速、长线传输或干扰环境中,推荐使用阻抗匹配(120Ω)的RS485专用电缆(STP-120Ω一对18AWG)。
- 恶劣环境下的解决方案:在干扰严重的情况下,应采用铠装型双绞屏蔽电缆(ASTP-120Ω一对18AWG)以增强抗干扰能力。
·
- RS232的应用及特点
应用
- 广泛用途:RS232接口尽管传输距离有限,但其应用非常广泛,特别是在设备连接、监控和调试方面。
- 与USB的兼容性:通过USB到RS232的转换装置,可以连接更多的RS232设备,实现高速传输和即插即用,同时解决了USB的传输距离限制。
特点
接口位置:RS232通常指的是电脑机箱后方的9芯插座(DB9)。
技术限制
:
- 信号电平较高,可能损坏接口电路芯片。
- 与TTL电平不兼容,需要电平转换电路。
- 传输速率较低,异步传输时波特率约为20Kbps。
- 使用共地传输,容易产生共模干扰,抗噪声干扰性较弱。
- 传输距离有限,标准最大值为50英尺(约15米)。
·
- RS485的特点
技术优势
- 电气特性:RS485使用差分信号,逻辑"1"和"0"分别由正负电压差表示,电平与TTL兼容,无需额外转换电路。
- 传输速率:RS485的数据最高传输速率可达10Mbps。
- 抗干扰性:采用平衡驱动和差分接收,显著增强了抗共模干扰能力,即抗噪声干扰性好。
- 传输距离:RS485的最大传输距离标准值为4000英尺(约1219米),实际应用中可达3000米。
- 多点通讯能力:RS485总线上可连接多达128个收发器,支持多站通讯,便于构建设备网络。
接口设计
- 网络构建:RS485接口的半双工网络通常只需两根连线,因此多采用屏蔽双绞线传输。
- 连接器:RS485接口的连接器通常采用DB-9类型的9芯插头和插座,具体类型(孔或针)根据连接设备而定。
通过上述对比,RS485在电子特性、通讯距离、多点通讯支持等方面均展现出明显的优势,使其成为现代工业和商业环境中更受欢迎的通信接口。
五、Modbus协议是什么
Modbus是一种由Modicon(施耐德电气公司)于1979年开发的串行通信协议,主要用于可编程逻辑控制器(PLC)和其他工业电子设备之间的通信。
1. 什么是Modbus?
-
开发背景:Modbus最初是为Modicon公司的PLC设计的。
-
开放性:作为一种开放式协议,Modbus允许制造商免费地将其集成到产品中。
-
支持的通信介质:Modbus支持通过RS232、RS485、RS422以及调制解调器进行串行通信。
- 主从模式
- 架构:Modbus网络遵循主/从模型,其中主站(Master)负责请求信息,而从站(Slave)提供信息。如下图所示。
- 地址标识:每个从设备都有一个唯一的地址标识。
- 信息交互:主站可以读取从站的内部寄存器,也可以向其写入信息。
- 协议的分类
Modbus协议主要有以下几种实现方式:
{1} Modbus ASCII
- 编码方式:使用ASCII码表示数据,每个8位字节作为两个ASCII字符传输。
- 效率:由于每个字节需要两个字符表示,效率低于RTU模式。
{2} Modbus RTU
- 编码方式:采用二进制数据表示,结合CRC错误检查。
- 适用性:适合工业应用,因其传输效率比ASCII模式更高。
{3} Modbus TCP
- 实现:允许Modbus ASCII/RTU协议在TCP/IP网络上传输。
- 特点:将Modbus消息嵌入TCP/IP帧内,但需考虑TCP/IP网络的不确定性。
{4} Modbus Plus
- 专有协议:Modicon专有的扩展版本,需要专门的协处理器。
- 物理层:使用1Mbit/s的双绞线,每个节点都有转换隔离设备。
- libmodbus
- 开源库:支持Linux、Mac OS X、FreeBSD、QNX和Win32等操作系统。
- 功能:根据Modbus协议发送和接收数据,支持RTU和TCP通信。
- freemodbus
- 嵌入式系统实现:提供Modbus ASCII/RTU和Modbus TCP的实现。
- 开源协议栈:从版本0.7开始支持Modbus/TCP,0.9版添加了使用lwIP TCP/IP堆栈的嵌入式系统支持。
- 主机模式:FreeModbus协议栈支持主机模式,提供多种请求模式和灵活的超时设置。
六、整体设计
设计一款12路车载超声波雷达系统,采用STM32F103微控制器和HC-SR04超声波模块,并通过RS485接口和Modbus协议对外通信,下面为详细的设计方案:
硬件设计
- 超声波雷达模块
- 超声波传感器:12个HC-SR04模块,每个模块有Trig和Echo引脚。
- 连接方式:将每个HC-SR04模块的Trig和Echo引脚分别连接到STM32F103的GPIO引脚上。
- 微控制器
- 微控制器:STM32F103系列,至少需要12个GPIO用于超声波模块的Trig和Echo信号。
- 时钟设置:72MHz的系统时钟频率。
- 通信接口
- RS485接口:采用MAX485芯片,实现RS485物理层通信。
- 串口配置:STM32的USART接口用于与MAX485通信。
- 电源管理
- 电源:汽车电源通常为12V,需要DC-DC转换器将12V转换为STM32和HC-SR04模块所需的5V和3.3V。
软件设计
- 底层驱动
- GPIO驱动:配置GPIO引脚为输出模式(Trig)和输入模式(Echo)。
- 定时器驱动:使用定时器捕获HC-SR04的Echo信号高电平时间,计算距离。
- USART驱动:配置USART用于RS485通信,波特率根据具体需求设置,一般为9600或115200。
- 测距算法
- 触发信号:发送至少10us的高电平到Trig引脚。
- 捕获回波:定时器捕获Echo信号的高电平时间,通过时间计算距离。
- Modbus协议栈
- 帧格式:实现Modbus RTU协议的帧格式,包括地址域、功能码、数据域和CRC校验。
- 读写操作:支持基本的读寄存器和写寄存器操作,读取超声波模块的测距数据。
- 数据处理
- 距离测量:每个超声波模块测量到的距离存储在STM32的寄存器中。
- 错误处理:处理测量超时或无效数据的情况,确保系统的可靠性。
具体实现步骤
硬件连接
- 超声波模块连接:将每个HC-SR04的Trig和Echo分别连接到STM32的GPIO引脚,例如:Trig1 -> PA0, Echo1 -> PA1, Trig2 -> PA2, Echo2 -> PA3,依此类推。
- RS485连接:MAX485的DI连接到STM32的TX引脚,RO连接到STM32的RX引脚,DE和RE引脚连接在一起并连接到STM32的一个控制引脚(例如PA4),用于控制发送和接收状态。
- 电源连接:确保所有模块都供电正常,STM32和HC-SR04都需要3.3V/5V供电,MAX485需要5V供电。
软件开发
-
初始化
- 配置系统时钟。
- 初始化GPIO引脚。
- 初始化定时器用于捕获Echo信号。
- 初始化USART用于RS485通信。
-
超声波测距
- 触发每个HC-SR04模块,启动测距。
- 捕获Echo信号高电平时间,通过定时器计算距离。
- 将距离数据存储在寄存器中,供Modbus协议读取。
-
Modbus通信
- 实现Modbus RTU协议的帧解析和生成。
- 处理Modbus主站的请求,根据请求的功能码读取或写入寄存器。
- 返回对应的距离数据或执行相应操作。
-
测试与调试
- 使用Modbus主站测试工具,验证通信协议的正确性。
- 通过调试工具和串口监视器,调试距离测量和通信功能。
代码示例
GPIO和定时器初始化
void GPIO_Init(void) {
// 配置Trig引脚为输出,Echo引脚为输入
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2; // Trig1, Trig2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_3; // Echo1, Echo2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void Timer_Init(void) {
// 配置定时器用于捕获Echo信号
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 72-1; // 1MHz
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
TIM_Cmd(TIM2, ENABLE);
}
Modbus通信示例
void USART_Init(void) {
// 配置USART用于RS485通信
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // USART1_TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // USART1_RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
void Send_Modbus_Response(uint8_t* response, uint8_t length) {
// 发送Modbus响应帧
for (uint8_t i = 0; i < length; i++) {
USART_SendData(USART1, response[i]);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
}
}
以上是一个完整的设计方案,涵盖硬件连接、软件开发、初始化代码示例等。实际开发过程中,需要根据具体的应用环境和需求进行进一步的调试和优化。
最后感谢大佬友情链接:
- 【总线】一文看懂RS232和RS485通信总线_485和232的区别-CSDN博客
- 一文快速认识Modbus协议 - 知乎 (zhihu.com)