文章目录
- modbus报文分析实例
- 移植libmodbus
- 问题
- 添加freertos
- 初始化
- 发送和接收
- 发送和接收的回调函数
- flush
- 主从设备代码分析-主控如何读写从机
- 1、串口传输,设置哪个串口、波特率、校验码、数据个数、体制位
- 2、connect连接只是初始化
- 3、主设备读写从设备1
- 4、硬件操作
- 注意:
stm32F103C8T6主控,发送libmodbus请求来读写寄存器,韦东山开发板
访问某一个设备需要5个参数
设备地址、寄存器类别、哪一个寄存器、读/写、具体值
modbus报文分析实例
libmodbus
rtu是使用串口来实现传输;
tcp是使用网络;
总体框架:三层、4个文件:
backend只有两个函数设计硬件,其他都是一样的,把这两个函数放到一个设备层里面;
移植libmodbus
用查询模式编写:
把设备写进一个结构体里面
问题
移植问题
搜索全部文件找这句,前面//去掉这一行
添加freertos
改造libmodbus
1、modbus.c
2、modbus_st_rtu
3、UART_Device
1、使能freertos
这个是hal库的时钟基准
时钟基准可以不改,改成TIM1也行
修改代码,用队列、信号量
使用uart的中断模式
使能中断,串口1、2都要使能
初始化
把队列、信号量、都创建出来;
使能发送中断
发送和接收
发送函数需要等待信号量,因为要发送完毕这一次才能发送下一次,主要原因是,你没发成功要返回一个报错,告知没成功,不然你咋知道发过去没
接收函数是直接读队列了,不需要等回调函数接收完成的信号,等队列就行了,如果收到数据,
发送和接收的回调函数
回调函数,发送函数不需要写队列的;
接收函数接收到数据后再写队列;
flush
清除数据,是接收数据,但是不使用,读取就是取走队列上的一个数据,只要不用就是清除;最后返回清除了多少个数据;
主从设备代码分析-主控如何读写从机
1、串口传输,设置哪个串口、波特率、校验码、数据个数、体制位
主控
从机,另外设置好自己的寄存器
设备地址保持一致,都是3
主设备发送的数据里面包含:设备地址是3;
从设备设置自己的设备地址为3,接收到发来的数据中函数有设备地址3,就知道是访问自己;
2、connect连接只是初始化
3、主设备读写从设备1
(ctx, 0 ,2, vals)这个函数从0地址开始,读2个寄存器的值放入vals
如上图是读只读寄存器,如果主设备要写入数据到可读可写寄存器的话,那就是从设备接收到这个query请求包,会进行相应的操作,把数据写到对应的寄存器里面;
4、硬件操作
前面的操作只是改了寄存器上面的值,并没有对硬件进行操作;
这个I2C是传感器内部的芯片和温湿度模块的芯片传输,不是modbus的主从设备传输;
注意:
1、modbus的1bit寄存器,虽然是1bit,但是分配的buff是1byte
16bit的寄存器分配的是unsigned short类型就是2type;
2、使用libmodbus时,他只是操作分配出来的4种寄存器的buff;
3、如果要操作硬件:用户去写代码,根据寄存器里面的值操作编写对应的功能来操作硬件;
4、启动调度后编写的代码不会执行:
原因是这个启动调度的函数不会返回;