STM32移植FreeModbus RTU教程1(ModbusRTU协议说明 )

STM32移植FreeModbus RTU从机教程1(ModbusRTU协议简要说明)

ModbusRTU说明

Modbus 协议是应用于电子控制器上的一种通用语言, 实现控制器之间、控制器由网络和其
它设备之间的通信,支持传统的RS232/RS422/RS485 和最新发展的以太网设备,最常用的是
TIA/EIA-485 (RS485) 两线制接口。它已经成为一种通用工业标准。有了它, 不同厂商生产的控制设备可以连成工业网络, 进行集中控制。此协议定义了一个控制器能认识使用的消息结构。
Modbus 协议是一种请求——应答方式的协议。
有两种串行传输模式分为ASCII与RTU两种模式,通常使用RTU(Remote Terminal Unit)模式。

RTU模式特点及基本术语、公共功能码

  1. RTU模式特点
    ① 消息中每个8bit 字节包含两个4bit 的十六进制字符,因此,在波特率相同的情况下,传输效率比ascii 传输方式大
    ② 1 个起始位、8 个数据位、1 个奇偶校验位和1 个停止位(或者两个停止位)
    ③ 错误检测域是CRC 检验
    ④ 消息发送至少要以3.5 个字符时间的停顿间隔开始。整个消息帧必须作为一连续的流传输。如果在帧完成之前有超过1.5 个字符时间的停顿时间, 接收设备将刷新不完整的消息并假定下一个字节是一个新消息的地址域。同样地, 如果一个新消息在小于3.5 个字符时间内接着前个消息开始,接收的设备将认为它是前一消息的延续。1.5~3.5 个字符间隔就算接收异常,只有超过3.5 个字符间隔才认为帧结束。

  2. 基本术语 ,字word 、字节byte 、位bit
    1 word = 2 byte;
    1 byte = 8 bit.;
    CRC校验码:校验码是由前面的数据通过某种算法得出的,用以检验该组数据的正确性。

  3. 公共功能码及相关寄存器地址
    MODBUS 数据模型有四种,通过不同的功能码来读写这些数据对象。

对象类别对象类型访问类型内容说明
离散量输入单个bit只读相当于开关量,每个bit对应一个开关信号状态(只能读取输入的开关量,无法通过应用程序进行更改,列如读取外部拨码开关的值。)
线圈单个bit读写相当于开关量,每个bit对应一个开关信号状态(可进行读写,列如通过1byte可控制8个IO口输出高低电平,此8个IO口电平可控可读)
输入寄存器16bit只读I/O 系统提供这种类型数据(无法通过应用程序进行更改的外部设备模拟量数据,如温度、气体浓度值等)
保持寄存器16bit读写通过应用程序改变这种类型数据(例如可通过应用程序进行读写的当前设备RTC时钟值、设备运行模式等。)

常用的功能码有:01H、02H、03H、04H、05H、06H、0FH、10H。
但在实际应用中, 厂家通常会根据实用性做些变通,但并不影响数据的读写,如当前设备开关量较少的情况下,将离散量输入值(如读取到的拨码开关8421码)归入04H输入寄存器中,将线圈开关量(输出高低电平控制继电器的通断)读写归入03H 06H 10H保持寄存器中。
最常用的功能码有:03H、04H、06H、10H。

Modbus 协议定义的寄存器地址是5 位十进制地址,即:
线圈( DO)地址: 00001~09999
触点( DI)地址: 10001~19999
输入寄存器( AI)地址: 30001~39999
输出寄存器( AO)地址: 40001~49999

由于上述各类地址是唯一对应的,因此有些资料就以其第一个数字区分各类地址,
即: 0x 代表线圈( DO)类地址, 1x 代表触点( DI)类地址、3x 代表输入寄存器( AI)类地
址、4x 代表输出寄存器( AO)类地址。
在实际编程中, 由于前缀的区分作用, 所以只需说明后4 位数, 而且需转换为4 位十六进制地址。*

Modbus 协议中寄存器地址从1 开始,而实际存储中地址从0 开始。
计算公式为:实际报文寄存器地址(16进制) = PLC地址位低四位(10进制) - 1;
如要读取寄存器编号为40005 (4 为块编号, 5 为modbus 中寄存器地址)的寄存器的数据,则应把00 04 放入报文的地址域。

功能码描述寄存器编号(10进制)实际报文寄存器地址(16进制)
01H读线圈寄存器00001~099990x0000~0xFFFF
02H读离散量输入寄存器10001~199990x0000~0xFFFF
03H读保持寄存器40001~499990x0000~0xFFFF
04H读输入寄存器30001~399990x0000~0xFFFF
05H写单个线圈寄存器00001~099990x0000~0xFFFF
06H写单个保持寄存器40001~499990x0000~0xFFFF
0FH写多个线圈寄存器00001~099990x0000~0xFFFF
10H写多个保持寄存器40001~499990x0000~0xFFFF

MODBUS功能码与Modbus 协议定义的寄存器地址对应关系:
一般厂商的码表或者信息点表、地址映射表里面有相对地址(实际发送报文寄存器地址)及寄存器号(Modbus 协议定义的寄存器地址)的说明。

地址位00001-09999 用01H/05H/0FH功能码读写,报文寄存器地址(即相对地址)为0x0000~0xFFFF
地址位10001-19999 用02H功能码读取,报文寄存器地址(即相对地址)为0x0000~0xFFFF
地址位30001-39999 用04H功能码读取,报文寄存器地址(即相对地址)为0x0000~0xFFFF
地址位40001-49999 用03H/06H/10H功能码读取,报文寄存器地址(即相对地址)为0x0000~0xFFFF

4. 最常用功能代码报文格式说明

功能码03H
描述:读保持寄存器。可读取单个或多个保持寄存器。报文格式如下+CRC校验低字节+CRC校验高字节
在这里插入图片描述
N=读取寄存器个数;
在这里插入图片描述
功能码04H
描述:读输入寄存器命令。该命令支持单个寄存器访问也支持多个寄存器访问。报文格式如下+CRC校验低字节+CRC校验高字节
在这里插入图片描述
功能码06H
描述:读输入寄存器命令。该命令支持单个寄存器访问也支持多个寄存器访问。报文格式如下+CRC校验低字节+CRC校验高字节
在这里插入图片描述
功能码10H
描述:写多个保持寄存器。报文格式如下+CRC校验低字节+CRC校验高字节
在这里插入图片描述

Modbus RTU通信报文格式

读数据:假如读40001 、40002 两个寄存器,假设从机地址为1

从机地址范围: 1~247,0 为广播地址,占一个字节。
理论上Modbus 协议可以接247 个从机,但若用于485 接口上则由于485 接口的限制,在没有中继情况下,最多可以接32 个从机。

下行报文:

从机地址功能码寄存器起始地址高字节寄存器起始地址低字节读取寄存器个数高字节读取寄存器个数低字节CRC校验低字节CRC校验高字节
0x010x030x000x000x000x020xC40x0B

上行报文:

从机地址功能码返回数据字节数05寄存器数据高字节05寄存器数据低字节06寄存器数据高字节06寄存器数据低字节CRC校验低字节CRC校验高字节
0x010x030x040x000x000x0B0xB80xFD0x71

写数据:假如向42001寄存器中写入数据 00 40,假设从机地址为1

下行报文:

从机地址功能码寄存器起始地址高字节寄存器起始地址低字节要写的数据高字节要写的数据低字节CRC校验低字节CRC校验高字节
0x010x060x070xD00x000x400x880xB7

上行报文:

从机地址功能码寄存器起始地址高字节寄存器起始地址低字节写入的数据高字节写入的数据低字节CRC校验低字节CRC校验高字节
0x010x060x070xD00x000x400x880xB7

从机若正常返回,则功能不变,若错误返回,则功能码的最高位为1,且从机会将一独特的代码(错误代码由厂家定义说明)放到回应消息的数据域中, 以便于告诉主设备发生了什么错误。主设备应用程序得到异议的回应后, 典型的处理过程是重发消息, 或者诊断发给从设备的消息并报告给操作员。如03 功能码,错误返回为83 。
设备异常返回信息(03功能码):01地址 + 03|0x80 + ErrCode + CRC
如下表某厂家设备的错误代码说明:

错误代码( ErrCode)内容说明
0x00成功没有错误
0x01功能码错误指定了不存在的功能代码。请确认功能代码。
0x02寄存器地址错误指定了指定功能代码不能使用的寄存器号地址。
0x03数据值域错误寄存器中被提交存储的数据项有一个应用程序期望之外的值
0x04写入失败正在设法执行请求的操作时,产生不可重新获得的差错。
  • 2
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103是一款非常常用的微控制器,它具有丰富的外设接口和功能强大的处理能力。要实现在STM32F103上同时运行Modbus RTUModbus TCP,我们可以移植FreeModbus协议栈来实现。 首先,我们需要了解Modbus RTUModbus TCP的基本原理和通信协议Modbus RTU是一种串口通信协议,而Modbus TCP是基于以太网的通信协议。它们之间的通信方式和数据格式略有不同。 在移植FreeModbus时,我们可以使用STM32F103上的通用串口外设来实现Modbus RTU的通信。我们需要编写串口中断处理函数来接收和发送Modbus RTU帧。同时,我们还需要实现Modbus TCP的通信功能。这可以通过STM32F103上的以太网接口来完成。我们需要编写TCP/IP协议栈的相关代码来处理Modbus TCP的通信。 在移植FreeModbus时,我们需要进行以下步骤: 1. 配置STM32F103的串口和以太网外设。我们需要设置串口的波特率、数据位、停止位等参数,以及配置以太网接口的IP地址和端口号。 2. 编写串口接收中断处理函数。当接收到串口数据时,我们需要解析Modbus RTU帧,提取出功能码和数据内容。 3. 编写串口发送函数。根据Modbus协议,我们需要根据功能码和数据内容生成Modbus RTU帧,并发送到串口。 4. 编写TCP/IP协议栈。我们需要编写用于处理Modbus TCP通信的TCP/IP协议栈代码。这包括解析TCP报文、提取出Modbus TCP报文、根据功能码和数据内容生成响应报文等。 5. 整合以上功能。将串口接收中断处理函数、串口发送函数和TCP/IP协议栈整合到一个主循环中,以实现同时运行Modbus RTUModbus TCP。 通过以上步骤,我们可以在STM32F103上实现同时运行Modbus RTUModbus TCP的功能。这样,我们就可以通过串口和以太网来实现与其他设备的通信。同时,我们还可以根据实际需求,对FreeModbus进行修改和优化,以满足项目的具体要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值