资讯动态

Modbus RTU 完整开发教程:帧格式、功能码解析、主机状态机收发全套代码

发布时间:2026/10/16 2:18:02 来源:尧图企业网站定制
前言MODBUS协议是一种工业领域的串行通信协议由 Modicon现隶属于施耐德电气于 1979 年开发主要用于工业自动化系统中控制器与远程设备之间的通信。它具有结构简单、开源免费、跨平台兼容的特点是目前常用的应用层通信协议。MODBUS协议是OSI模型第 7 层上的应用层报文传输协议通信方式分为主从通信主机发送协议指令从机收到指令之后产生应答如果没有应答主机会再次发送协议指令直到超时即停止发送。这里对MODUBUS协议的格式及协议通信框架做一下总结便于复用。一、协议格式MODBUS协议和自定义的协议基本差不多是一种数据传输格式也是由起始帧、数据帧、校验帧等组成只不过Modbus协议更为规范。MODBUS协议格式从机地址功能码数据校验码CRC16。MODBUS协议帧格式如下图地址域从机的地址范围1~2551个地址表示一个设备功能码有03,04,06,0x10等功能码03/04表示读数据功能码06表示写单个寄存器数据0x10表示写多个寄存器数据数据主机发送协议中数据表示寄存器从机应答协议中的数据表示上报的数据校验码对地址域、功能码、数据这些进行CRC16校验校验值低位在前高位在后。二、举例2.1 03H,04H命令——读输入寄存器。主机请求数据从机返回数据2.2 06命令——写单个寄存器主机下发数据从机返回数据三、代码交互框架3.1 主机发送读数据框架主机发送数据设计为一个状态机每个状态计时时间为150ms。主机发送请求读数据之后等待接收应答数据当超过150ms没有收到应答数据时计数变量加1连续加到4时判断为接收数据超时通信异常标志位置1。代码实现如下void pri_mppt_send(void) { static uint8_t su8MpptState 1; switch(su8MpptState) { case 1: PS_MpptComm_Send_Soc(); HAL_UART_Transmit(huart4,(uint8_t*)g_su8MpptSendCmd, sizeof(g_su8MpptSendCmd),100); MODBUS_CLR_BIT(SysTimHandle.g_su16SystemTimFlag,SYSTEM_150MS_FLAG); SysTimHandle.g_su16SysTim150ms 0; // pri_mppt_clr_tim_2s(); //调试 su8MpptState 2; break; case 2: if(MODBUS_GET_BIT(SysTimHandle.g_su16SystemTimFlag,SYSTEM_150MS_FLAG)) // if(MODBUS_GET_BIT(SysTimHandle.g_su16SystemTimFlag,SYSTEM_2S_FLAG)) //调试 { g_su8MpptSendCnt; if(g_su8MpptSendCnt 4) //通信超时计数142.1s超时 { su8MpptState 3; } else { su8MpptState 1; } } break; case 3: //MPPT通信异常故障码E40 MpptFltFlag.Bit.g_ubPVCommFault 1; SysIsFlt.g_sbMpptIsFlt 1; su8MpptState 1; g_su8MpptSendCnt 0; break; default: break; } }3.2 主机接收应答数据框架主机收到应答数据之后首先判断是否接收完成然后再判断接收的数据长度接收数据的地址接收数据的功能码全都没问题则进行CRC16位数据校验校验也没问题最后就可以处理数据。代码实现如下//返回数据 void pri_mppt_resp(void) { if(MpptDataHandle.g_sbUartRxOkFlag) { MpptDataHandle.g_sbUartRxOkFlag 0; if((MpptDataHandle.g_su8RxCnt ! 12) (MpptDataHandle.g_su8RxBuf[0] ! 1) (MpptDataHandle.g_su8RxBuf[1] ! 3) MpptDataHandle.g_su8RxBuf[2] ! 6) { MpptDataHandle.g_su8RxCnt 0; return; } PS_AlgorithmCalc_Crc_Check(MpptDataHandle.g_su8RxBuf,MpptDataHandle.g_su8RxCnt-2); if(su16CrcDate (MpptDataHandle.g_su8RxBuf[MpptDataHandle.g_su8RxCnt-1]8)MpptDataHandle.g_su8RxBuf[MpptDataHandle.g_su8RxCnt-2]) { g_su8MpptSendCnt 0; MpptFltFlag.Bit.g_ubPVCommFault 0; SysIsFlt.g_sbMpptIsFlt 0; ...... MpptDataHandle.g_su8RxCnt 0; memset(MpptDataHandle.g_su8RxBuf, 0, sizeof(MpptDataHandle.g_su8RxBuf)); } else { MpptDataHandle.g_su8RxCnt 0; } } }四、总结MODBUS协议交互应用起始蛮简单的使用过一次熟悉之后后面基本都是复制粘贴代码都可以拿来复用。有几个点需要注意下-发送数据超时数据不能一直发送要设计超时机制-接收数据判断根据协议格式逐个判断数据的正确性这样更严谨。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑