
以下作品由安信可社区用户
ckdsx.cn制作
1.什么是Modbus, RS485?
1.1RS485 VS RS232
1.2RS485,RS232两种协议之间的主要区别
1.3Modbus的内容是什么?
1.4帧结构
1.5Modbus指令实例1.5.1
1.6 Modbus-RTU协议
2.外设介绍
2.1常用芯片选择
2.2初始化过程
3.移植过程
3.1资料介绍
3.2示例参考程序代码
演示视频
Modbus就是一种用在工业上的简单协议!顾名思义,它是一个Bus,即总线协议。比如串口协议、IIC协议、SPI都是通信协议。
01
RS485 VS RS232
RS485和RS232串行通信协议已经使用了50多年,并且仍在整个商业和工业中广泛使用。扩展RS232标准的功能是开发RS485协议的动力。下表概述了这两个标准。
02
RS485,RS232两种协议之间的主要区别
发射器和接收器的数量
RS232串行接口设计用于连接两个设备。该协议支持单个发射器和接收器之间的通信。 RS485接口,最多可以将32个串行设备连接到一个变送器。
操作距离
使用RS232协议的设备在发送器和接收器之间的距离限制为15米,同时仍能实现最大数据传输速率。如果可以容忍较慢的数据速率,则可以延长此长度。 RS485协议大大延长了操作距离。它支持1200米长度的最大数据速率,使RS485协议成为物理上相距遥远的设备之间通信的绝佳选择。
数据传输速度
RS232接口的传输速度为1Mb/s,传输距离可达15米。RS485在15米的距离内提供高达10Mb/s的更高速度。当达到1200米的最大长度时,RS485协议以100Kb/s的速度传输数据。
电气噪声问题和接地电位
RS232接口是一种基于电压电平的系统,在接地电位差异最小的情况下性能最佳。表现出高水平电噪声和可变接地电位的环境会影响RS232有效传输数据的能力,并可能导致数据丢失或损坏。
RS485协议采用差分电压系统,使其能够在具有较高电噪声水平的环境中有效运行。差分电压系统的一个副产品是数据传输距离的延长、传输速度的提高以及RS485所见的更低电压的使用。
03
Modbus的内容是什么?
Modbus-RTU,Modbus-ASCII,Modbus-TCP以上三种协议,一个设备只会有一种协议,如果你的设备使用的是Modbus-RTU,只需查看以下对应部分,一般来说大部分的设备都是Modbus-RTU协议的。
04
帧结构
地址
占用一个字节,范围0-255,其中有效范围是1-247,其他有特殊用途,比如255是广播地址(广播地址就是应答所有地址,正常的需要两个设备的地址一样才能进行查询和回复)。
功能码
占用一个字节,功能码的意义就是,知道这个指令是干啥的,比如你可以查询从机的数据,也可以修改数据,所以不同功能码对应不同功能。
数据
根据功能码不同,有不同结构,在下面的实例中有说明。
校验
为了保证数据不错误,增加这个,然后再把前面的数据进行计算看数据是否一致,如果一致,就说明这帧数据是正确的,我再回复;如果不一样,说明你这个数据在传输的时候出了问题,数据不对的,所以就抛弃了。
这是一个基于ModbusRTU协议的Ai-WB2modbus库,它支持以下几种modbus协议命令:
05
Modbus指令实例
查询从机地址为01的数据
主机发送:01 03 00 00 00 01 84 0A
从机回复:01 03 02 19 98 B2 7E
发送数据解析

回复数据解析

查询数据基本流程就是:
发送:从机的地址+要干嘛的功能码+要查的寄存器的地址+要查的寄存器地址的个数+校验码
回复:从机的地址+主机发我的功能码+要发送给主机数据的字节数+数据+校验码
修改从机地址为01的数据
主机发送:01 06 00 00 00 01 48 0A
从机回复:01 06 00 00 00 01 48 0A
发送数据解析

回复数据解析
06
Modbus-RTU协议
只需要看懂功能码0x03、0x06、0x10这三个基本的就已经足够了,分别回想下其数据域部分:
0x03—主机需要发送起始地址+寄存器数量,从机回复总字节数+数据;
0x06—主机发送起始地址+数据内容(因为你只需要修改一个,所以起始地址就是所要修改的地址),从机返回起始地址+数据内容(发现居然一样!)
0x10—主机发送起始地址+寄存器个数+总字节数+数据,从机返回起始地址+寄存器数量
RS485转TTL模块
RS485远程I/O联网模块IODO控制器modbus
01
常用芯片选择
SN75276
SN75179
SN75180
MAX485
MAX488
02
初始化过程
引入头文件
设置初始化参数
波特率:默认串口配置为9600波特率,8位数据位,无校验位,1位停止位。
hosal_uart_dev_tuart_dev_log = {.config= {.uart_id= 1,.tx_pin= 16, // TXD GPIO.rx_pin= 7, // RXD GPIO.cts_pin= 255,.rts_pin= 255,.baud_rate= 115200,.data_width= HOSAL_DATA_WIDTH_8BIT,.parity= HOSAL_NO_PARITY,.stop_bits= HOSAL_STOP_BITS_1,.mode= HOSAL_UART_MODE_POLL,},};hosal_uart_init(&uart_dev_log);
配置用到的引脚
默认使用串口引脚:硬件串口
使用板载引脚4个:TX,RX,3.3V,GND(接线方法见模块说明书或下图) RS485引脚:A+连接A+,B-连接B-,数据有干扰的情况下GND接地。
01
资料介绍
地址和命令可以直接以16进制的方式写到数组里,CRC16校验需要计算或查表获得;
参考网上CRC教程,使用本地CRC库文件二次封装完成CRC校验及校验值追加与打印函数(有关更多CRC计算请参考网上教程);
由于手头方便的仅有modubusRS485远程控制IO模块,仅以此模块完成命令发送控制其输出继电器开关的例程。
电路连线图
Ai-WB2 => 串口TTL=> MAX485 => A,B双绞线=>RS485设备
注:AI-WB2与模块之间连线时,RX连接RX,TX连接TX。请根据模块说明自行调整接线!

01
示例参考程序代码
RS485发送示例代码如下:
----------------------intcounter = 0;voidsetup() {RS485.begin(9600);}voidloop() {RS485.beginTransmission();RS485.print("hello");RS485.println(counter);RS485.endTransmission();counter++;delay(1000);}-------------------------------
RS485接收并串口打印示例代码如下:
-----------------------------------voidsetup() {Serial.begin(9600); while(!Serial);RS485.begin(9600);//enable reception, can be //disabled with: RS485.noReceive();RS485.receive();}voidloop() {if(RS485.available()) {Serial.write(RS485.read()); }}--------------------------------
注:通过串口助手直接输出指令,有可能因为不是十六进制,或指令尾部被增加回车换行(0D0A)而导致失败!
程序运行过程:wb2通过串口向RS485转TTL模块发送指令,远程IO模块通过Modbus端口A、B接收数据并解析,然后执行指令动作。
程序运行现象:RS485转TTL模块,TX指示灯每隔两秒点了一下,远程IO模块输出端口1234顺序开启,然后顺序关闭。
若无硬件,则可以使用串口助手观察命令发送情况,请注意勾选HEX显示。(见下图)
程序代码见原贴中的附件
【外设移植】Ai-WB2+Modbus 485 RTU 远程控制。程序太过简单,未制作成库文件,各位可直接修改使用,make相关内容同helloworld文件一样。
PS:感谢园长、银、狗哥、杰哥、妖哥等各位安信可技术社区的大佬热情帮助!编译烧录请参考安信可技术社区教程!想不到的问题请大家在原贴中提问,笔者会尽量协助回答、解决!
微信改版,容易错过最新资讯和福利?
快将“安信可科技”设为星标⭐
可以第一时间接收小安的推送!
▼

安信可Ai-WB2系列的优势是?一秒读懂!
星闪网卡:Wi-Fi6+SLE+BLE,三模合一Linux网卡
安信可更多产品信息可进入以下链接查阅:
●开发资料:https://docs.ai-thinker.com/
●官方教程:https://blog.csdn.net/Boantong_
●安信可官网:www.ai-thinker.com
●安信可社区:https://bbs.ai-thinker.com
●业务咨询请联系:18022036575



