当前位置:文档之家› Modbus协议

Modbus协议

㈠MODBUS规约MODBUS规约是MODICOM公司开发的一个为很多厂商支持的开放规约, Modbus 协议是应用于电子控制器上的一种通用语言。

通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。

它已经成为一通用工业标准。

有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。

最主要的是它被很多组态软件所兼容,开发速度较快,受到了很多工控厂商的追捧。

但是协议还是有点小麻烦的。

此协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。

它描述了控制器请求访问其它设备的过程,如果回应来自其它设备的请求,以及怎样侦测错误并记录。

它制定了消息域格局和内容的公共格式。

当在Modbus网络上通信时,此协议决定了每个控制器须要知道它们的设备地址,识别按地址发来的消息,决定要产生何种行动。

如果需要回应,控制器将生成反馈信息并用Modbus 协议发出。

在其它网络上,包含了Modbus协议的消息转换为在此网络上使用的帧或包结构。

这种转换也扩展了根据具体的网络解决节地址、路由路径及错误检测的方法。

标准的Modbus口是使用RS-232C兼容串行接口,它定义了连接口的针脚、电缆、信号位、传输波特率、奇偶校验。

控制器能直接或经由Modem组网。

控制器通信使用主—从技术,即仅设备(主设备)能初始化传输(查询)。

其它设备(从设备)根据主设备查询提供的数据做出相应反应。

典型的主设备:主机和可编程仪表。

典型的从设备:可编程控制器。

主设备可单独和从设备通信,也能以广播方式和所有从设备通信。

如果单独通信,从设备返回消息作为回应,如果是以广播方式查询的,则不作任何回应。

Modbus协议建立了主设备查询的格式:设备(或广播)地址、功能代码、所有要发送的数据、错误检测域。

从设备回应消息也由Modbus协议构成,包括确认要行动的域、任何要返回的数据和错误检测域。

如果在消息接收过程中发生错误,或从设备不能执行其命令,从设备将建立错误消息并把它作为回应发送出去。

在其它网络上,控制器使用对等技术通信,故任何控制都能初始和其它控制器的通信。

这样在单独的通信过程中,控制器既可作为主设备也可作为从设备。

提供的多个内部通道可允许同时发生的传输进程。

在消息位,Modbus协议仍提供了主—从原则,尽管网络通信方法是“对等”。

如果控制器发送消息,它只是作为主设备,并期望从从设备得到回应。

同样,当控制器接收到消息,它将建立一从设备回应格式并返回给发送的控制器。

.主设备查询查询消息中的功能代码告之被选中的从设备要执行何种功能。

数据段包含了从设备要执行功能的任何附加信息。

例如功能代码03是要求从设备读保持寄存器并返回它们的内容。

数据地址域功能域数据域错误检测域帧定界:51单片机实现实现MODBUS RTU协议一、通讯协议:1、通讯传送方式:通讯传送分为独立的信息头,和发送的编码数据。

以下的通讯传送方式定义也与MODBUS RTU通讯规约相兼容:编码 8位二进制起始位 1位数据位 8位奇偶校验位 1位(偶校验位)停止位 1位错误校检 CRC(冗余循环码)初始结构 = ≥4字节的时间地址码 = 1 字节功能码 = 1 字节数据区 = N 字节错误校检 = 16位CRC码结束结构 = ≥4字节的时间地址码:地址码为通讯传送的第一个字节。

这个字节表明由用户设定地址码的从机将接收由主机发送来的信息。

并且每个从机都有具有唯一的地址码,并且响应回送均以各自的地址码开始。

主机发送的地址码表明将发送到的从机地址,而从机发送的地址码表明回送的从机地址。

功能码:通讯传送的第二个字节。

ModBus通讯规约定义功能号为1到127。

本仪表只利用其中的一部分功能码。

作为主机请求发送,通过功能码告诉从机执行什么动作。

作为从机响应,从机发送的功能码与从主机发送来的功能码一样,并表明从机已响应主机进行操作。

如果从机发送的功能码的最高位为1(比如功能码大与此同时127),则表明从机没有响应操作或发送出错。

数据区:数据区是根据不同的功能码而不同。

数据区可以是实际数值、设置点、主机发送给从机或从机发送给主机的地址。

读取保持寄存器(单个和多个,以字为最小单位)设备地址:1~247功能码:3H数据地址:0~65535 具体范围与相关设备有关数量:1~65535 具体范围与相关设备有关校验码:CRC16校验设备地址:1~247功能码:3H数据量:实际的读取数据数量数据:返回数据的意义a=HoldStart命令有误:1)没有任何返回bytN设备地址:1~247功能码:10H数据地址:0~65535 具体范围与相关设备有关数量:1~122 具体范围与相关设备有关字节数:设置的字节个数bytN= DataNum×2数据:具体的字节数据校验码:CRC16校验设备地址:1~247功能码:10H数据地址:0~65535 具体范围与相关设备有关数量:1~122 具体范围与相关设备有关校验码:CRC16校验命令有误:1)没有任何返回uint16 testRegister; //用于测试字地址0uint8 localAddr = 1; //地址uint8 sendCount; //发送字节个数uint8 receCount; //接收字节个数uint8 sendPosi; //发送位置uint8 sendBuf[32],receBuf[32]; //发送,接收缓冲区uint8 checkoutError; //校验结果uint8 receTimeOut; //接收超时//CRC较验计算uint16 crc16(uint8 *puchMsg, uint16 usDataLen){uint8 uchCRCHi = 0xFF ; /* 高CRC字节初始化*/uint8 uchCRCLo = 0xFF ; /* 低CRC 字节初始化*/uint32 uIndex ; /* CRC循环中的索引*/while (usDataLen--) /* 传输消息缓冲区*/{uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC */ uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;uchCRCLo = auchCRCLo[uIndex] ;}return (uchCRCHi << 8 | uchCRCLo) ;}//uint16 crc16(uint8 *puchMsg, uint16 usDataLen)//MODBUS状态机,在主程序中调用即可void checkComm0Modbus(void){uint16 crcData;uint16 tempData;if(receCount > 4){switch(receBuf[1]){// 其它的功能码可以参照协议自行编写case 1://读取线圈状态(读取点16位以内)case 3://读取保持寄存器(一个或多个)case 5://强制单个线圈case 6://设置单个寄存器if(receCount >= 8){//接收完成一组数据//应该关闭接收中断UCSRB &= ~BIT(7);if(receBuf[0]==localAddr && checkoutError==0) {crcData = crc16(receBuf,6);if(crcData == receBuf[7]+(receBuf[6]<<8)){//校验正确if(receBuf[1] == 1){//读取线圈状态(读取点16位以内)readCoil();}else if(receBuf[1] == 3){//读取保持寄存器(一个或多个)readRegisters();}else if(receBuf[1] == 5){//强制单个线圈forceSingleCoil();}else if(receBuf[1] == 6){//presetSingleRegister();}}}receCount = 0;checkoutError = 0;UCSRB |= BIT(7);}break;case 15://设置多个线圈tempData = receBuf[6];tempData += 9; //数据个数if(receCount >= tempData){//应该关闭接收中断UCSRB &= ~BIT(7);if(receBuf[0]==localAddr && checkoutError==0){crcData = crc16(receBuf,tempData-2);if(crcData == (receBuf[tempData-2]<<8)+ receBuf[tempData-1]){//forceMultipleCoils();}}receCount = 0;checkoutError = 0;UCSRB |= BIT(7);}break;case 16://设置多个寄存器tempData = (receBuf[4]<<8) + receBuf[5];tempData = tempData * 2; //数据个数tempData += 9;if(receCount >= tempData){//应该关闭接收中断UCSRB &= ~BIT(7);if(receBuf[0]==localAddr && checkoutError==0){crcData = crc16(receBuf,tempData-2);if(crcData == (receBuf[tempData-2]<<8)+ receBuf[tempData-1]){ presetMultipleRegisters(); } } receCount = 0; checkoutError = 0; UCSRB |= BIT(7); } break; default: break; } }}。

相关主题