最后遗留的一个问题,在Modbus-RTU的读取功能中就完美解决了[灵光一闪]。发送帧的第5字节数据就要要读取的长度,响应帧的第3字节数据就是返回数据的长度,后面的字节就是返回数据。因为1个寄存器数据是2个字节。这里的发送和接收就不是同样的长度,而且保证正确。
再重声明发送的一帧数据解读01 06 00 01 00 FE 59 8A,01是设备地址,就是下位机的硬件地址,每个下位机有一个唯一的不重复的地址,自己规划好。06是Modbus写一个寄存器的功能码。00 01是寄存器内部地址,由你在下位机程序中定义,就是一段RAM数组你定义的数组下标。00 FE是写入的数据。59 8A是CRC16校验码。[ok]
具体程序,包括接收到数据处理,转移到中间处理数组,方便原rec_buf数组接收新的数据。还有响应帧发送函数,就是一段串口发送函数,只是增加了RS485的方向控制。再次强调,发送完最后一位数据后的延时。[机智]
关键的接收数据解析函数。LOCAL_ADDRESS就是设备(下位机)的地址,宏定义为0x01,其它具体解释都在源码中了。我只处理了接收数据的低字节,高字节保持为0。同时读出的数据在1602上显示。最后0x09的地址寄存器用来控制单片机引脚,控制一只LED的闪烁或者关闭。同时完成响应帧数据的处理。
我们往寄存器00-08中写入数据10到18。寄存器09中写入非零数,控制LED闪烁。最后我们的显示效果如图,完美的达成了我们的效果[ok]。在图片中我一再的解释数据的意思,让大家理解基本的两个功能码的使用,理解一帧数据的组成和处理。[机智]
使用了RS485-RTU通讯,解决了干扰问题。其实它和固定字节或变字节串口通讯本质上没有区别,只是数据处理上,大家都统一了,方便解析和移植。
小伙伴们,多做实验,了解485通讯的过程吧。[来看我]