在调试STM32F407的串口Modbus通讯之前,也使用过Modbus通讯,只不过都是在PLC或则昆仑通态的触摸屏上使用直接调用现成的库里面的模块,驱动就可以,相对于STM32来,使用PLC库里面的模块和触摸屏驱动都是初始化后配参数就可以了,但是用32写的时候比较麻烦了一些。由于STM32没有RS485通讯端口只能用UART端口转成RS485加了一个485芯片,在调试Modbus通信按照plc和触摸屏的经验慢慢琢磨也是挺有意思的。当最后你都调通的时候心里那种成就感是对于一个理工男来说是非常爽的!不啰嗦了下面介绍Modbus通信流程以及功能码:
1、数据目的:读输入继电器 1区 功能码:02 通信格式: 设备地址 功能码 起始地址 读数据位个数 CRC校验
例: 01 02 00 00 00 01 B9 CA
例 :01 02 00 00 00 01 B9 CA
返回数据:01 02 01 01 60 48 //返回01表示继电器1状态
01 02 01 00 A1 88 //返回00表示继电器0状态
2、数据目的:读输出继电器 0区 功能码:01 通信格式: 设备地址 功能码 起始地址 读数据位个数 CRC校验
例: 01 01 00 00 00 01 FD CA
例:01 01 00 00 00 01 FD CA
返回数据:01 01 01 01 90 48 //返回01表示继电器1状态
01 01 01 00 51 88 //返回00表示继电器0状态
3、数据目的:写输出继电器 0区 功能码:05 通信格式: 设备地址 功能码 起始地址 数据 CRC校验
例: 01 05 00 00 00 00 CD CA
例:01 05 00 00 00 00 CD CA //写继电器0状态
例:01 05 00 00 FF FFCC 7A //写继电器1状态
4、数据目的:读3区16位寄存器数据 3区 功能码:04 通信格式: 设备地址 功能码 起始地址 数据位数 CRC校验
例: 01 04 00 01 00 00 60 0A
例:01 04 00 01 00 01 60 0A //写继电器0状态
返回数据:01 04 02 00 05 79 33 //返回02带边数据位数 00 05代表返回的数据
5、数据目的:读4区16位寄存器数据 4区 功能码:03 通信格式: 设备地址 功能码 起始地址 数据位数 CRC校验
例: 01 03 00 01 00 00 D5 CA
例:01 03 00 01 00 01 D5 CA //写继电器0状态
返回数据:01 03 02 00 05 78 47 //返回02带边数据位数 00 05代表返回的数据
6、数据目的:写4区16位寄存器数据 4区 功能码:06 /10 通信格式: 设备地址 功能码 起始地址 数据 CRC校验
例: 01 06 00 01 00 00 9C 6B
例:01 06 00 01 0E 03 9C 6B //写00 01数据0E 03
啰嗦了半天功能码,接下来写一下Modbus的在STM32中的流程:
1、发送需要读取从站的地址以及功能码
2、发送完成后开始200ms定时中断等待从站数据是否返回(定时器中断优先级低于串口中断)若无数据返回重复1步骤
3、有数据返回开启2ms中断,接收间隔超过2ms代表数据接收完成。
4、解析数据,返回数据;
extern u8 RS485_BUFF[100]; u8 Rcv_Len; /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ extern