概述
modbus协议使用串口,有ASC方式和RTU方式两种协议,鉴于ASC协议使用不多,我们这里目前只支持RTU模式。
RTU 模式简介
设备地址 + 功能代码+ 数据 + 校验
- 前后至少有3.5个字符的传播事件空余
- 设备地址:一个字节
- 功能代码:一个字节,有常用规范
- 数据:长度不定
- 校验:两个字节 CRC计算
RTU数据包发送
int bs;
bs=newbin(16); //创建一个存储区
defbin(bs,0,"00 00 00 04"); //定义modbus RTU的数据,纯数据不含校验码
modbus_send(0xfe,0x02,bs,4);//发送一个RTU数据包
freestr(bs);
此时,串口会发送一个RTU包,8个字节:
FE 02 00 00 00 04 6D C6
其中: - 0xfe 是设备地址 - 0x02 shi 功能代码 - 00 00 00 04 是数据 - 6d c6 是CRC校验码,由系统自动计算
RTU数据包的接收
- 第一步:设置状态,启动RTU接收模式
注意:不建议在开机界面放置这个语句,因为这样会影响串口更新ROM数据的功能,因为一上电就被设置成RTU模式,不再接收CMD命令字符串;
setcomadv(0,115200,8,0,1,1); //设置一号串口(编号0)为115200的RTU模式
此时,如果串口一收到了一个RTU包(识别方式,数据包中间不停顿,数据包前后有至少3.5字节时间的间隔),且CRC校验成功,则系统会自动调用app.onRTUrecv()事件,用于处理RTU包;
在appbase 全局控件中使用:
int bs=0; //RTU数据包存储句柄
int len=0; //RTU数据包的长度,含设备地址和功能代码以及数据,不含CRC
void create()
{ bs=newbin(256); //创建一个数据接收区
}
void onRTUrecv(){
//有RTU数据帧收到
echo("recv RTU!!!!");
len=rtucopy(bs);
//此时可以使用getv(bs,addr,type)来读取数据处理RTU包
//---以下语句仅仅是demo(或调试使用),串口发送显示出接收的数据包
int i;
for (i=0;i<len;i++){
echo(int2hex(getv(bs,i,1),2)+" ");
}
}