Modbus对设备的控制是通过对一系列寄存器的读写完成的,是一种常用的串行通信协议,现在Modbus协议已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。
Modbus在luat lib没有对应的API封装,主要应用串口函数,对数据按照一定协议进行打包发送。
相应的串口API如下:
API接口 | 描述 |
---|---|
uart.on() | 注册串口的数据接收或发生函数 |
uart.setup() | 配置并且打开串口,可设置使用模块的串口ID号,波特率,数据位,奇偶校验位等 |
uart.write() | 向串口写字符串或者整型数据 |
uart.read() | 从串口读取字符串 |
uart.close() | 关闭uart对应接口 |
详细的API介绍见uart API章节
相关实例程序在脚本库的demo\modbus文件夹下,包含modbus协议通信实例。可以根据实际需要选择demo进行测试研究。
一条modbus报文,通常包含从机地址、功能码、数据地址、数据、CRC校验这几个数据结构,一个报文就是一帧数据,指的是一串完整的指令数据,如
从机地址 | 功能代码 | 数据地址 | 数据 | CRC校验 |
---|---|---|---|---|
8 位 | 8 位 | Nx8 位 | Nx8 位 | 16 位 |
01 | 06 | 00 01 | 00 17 | 98 04 |
通过pack.pack()对检验数据以十六进制格式进行打包,然后与前面数据结构中的数据进行拼接发送:
local function modbus_send(slaveaddr,Instructions,reg,value) local data = (string.format("%02x",slaveaddr)..string.format("%02x",Instructions)..string.format("%04x",reg)..string.format("%04x",value)):fromHex() local modbus_crc_data= pack.pack('<h', crypto.crc16("MODBUS",data)) local data_tx = data..modbus_crc_data uart.write(uart_id,data_tx) end
此处代码演示使用串口1作为modbus协议通信接口,所以使用uart.read(uart_id,1)来读取串口1接收到的数据,并将数据转换为十六进制,对接收到的数据用户可以自己定义解析做功能扩展,在每次打印和处理完之后,通过cacheData = ""清空串口接收数据缓存。
local function modbus_read() local cacheData = "" while true do local s = uart.read(uart_id,1) if s == "" then if not sys.waitUntil("UART_RECEIVE",35000/uart_baud) then -- 3.5个字符的时间间隔,只是用在RTU模式下面,因为RTU模式没有开始符和结束符, -- 两个数据包之间只能靠时间间隔来区分,Modbus定义在不同的波特率下,间隔时间是不一样的, -- 所以就是3.5个字符的时间,波特率高,这个时间间隔就小,波特率低,这个时间间隔相应就大 -- 4800 = 7.297ms -- 9600 = 3.646ms -- 19200 = 1.771ms -- 38400 = 0.885ms --uart接收数据,如果 35000/uart_baud 毫秒没有收到数据,则打印出来所有已收到的数据,清空数据缓冲区,等待下次数据接收 --注意: --因为在整个GSM模块软件系统中,软件定时器的精确性无法保证,例如本demo配置的是100毫秒,在系统繁忙时,实际延时可能远远超过100毫秒,达到200毫秒、300毫秒、400毫秒等 --设置的延时时间越短,误差越大 if cacheData:len()>0 then local a,_ = string.toHex(cacheData) log.info("modbus接收数据:",a) --用户逻辑处理代码 -- cacheData = "" end end else cacheData = cacheData..s end end end
注册一个任务sys.taskInit(),每隔5S钟由modbus_send()函数向串口发送数据
sys.taskInit(function () while true do sys.wait(5000) modbus_send("0x01","0x01","0x0101","0x04") end end)
答:https://doc.openluat.com/question_detail/225。
相关开发板购买链接
Air724UG开发板
Air724 开发板使用说明
来自转载:https://doc.openluat.com/wiki/21?wiki_page_id=2362