news 2026/8/14 8:13:05

解决Modbus 主站回读数据时,eRcvState 一直保持在 STATE_M_RX_IDLE状态,导致无法正常接收数据的问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
解决Modbus 主站回读数据时,eRcvState 一直保持在 STATE_M_RX_IDLE状态,导致无法正常接收数据的问题

调试报告

问题描述

在 Modbus 主站回读数据时,eRcvState一直保持在STATE_M_RX_IDLE状态,导致无法正常接收数据。经过检查,发现问题出在主循环的轮询调用上。

BOOLxMBMasterRTUReceiveFSM(void){BOOL xTaskNeedSwitch=FALSE;UCHAR ucByte;assert_param((eSndState==STATE_M_TX_IDLE)||(eSndState==STATE_M_TX_XFWR));/* Always read the character. */(void)xMBMasterPortSerialGetByte((CHAR*)&ucByte);switch(eRcvState){/* If we have received a character in the init state we have to * wait until the frame is finished. */caseSTATE_M_RX_INIT:vMBMasterPortTimersT35Enable();break;/* In the error state we wait until all characters in the * damaged frame are transmitted. */caseSTATE_M_RX_ERROR:vMBMasterPortTimersT35Enable();break;/* In the idle state we wait for a new character. If a character * is received the t1.5 and t3.5 timers are started and the * receiver is in the state STATE_RX_RECEIVCE and disable early * the timer of respond timeout . */caseSTATE_M_RX_IDLE:/* In time of respond timeout,the receiver receive a frame. * Disable timer of respond timeout and change the transmiter state to idle. */vMBMasterPortTimersDisable();eSndState=STATE_M_TX_IDLE;usMasterRcvBufferPos=0;ucMasterRTURcvBuf[usMasterRcvBufferPos++]=ucByte;eRcvState=STATE_M_RX_RCV;/* Enable t3.5 timers. */vMBMasterPortTimersT35Enable();break;/* We are currently receiving a frame. Reset the timer after * every character received. If more than the maximum possible * number of bytes in a modbus frame is received the frame is * ignored. */caseSTATE_M_RX_RCV:if(usMasterRcvBufferPos<MB_SER_PDU_SIZE_MAX){ucMasterRTURcvBuf[usMasterRcvBufferPos++]=ucByte;}else{eRcvState=STATE_M_RX_ERROR;}vMBMasterPortTimersT35Enable();break;}returnxTaskNeedSwitch;}

在这个函数中,eRcvState 一直等于0x01 STATE_M_RX_IDLE,一次 case STATE_M_RX_RCV的分支都没执行

原因分析

原始代码中,Modbus 主站的轮询函数 eMBMasterPoll() 在主循环中调用频率过高,导致状态机无法正常切换。具体代码如下:

while(1){// 主机轮询eMBMasterPoll();// 非阻塞方式轮询,避免 HAL_Delay 占用 CPU。if(HAL_GetTick()-lastPollTime>=1000){test(MB_USER_READ_CALLBACK);lastPollTime=HAL_GetTick();// 延时1秒}HAL_Delay(MB_POLL_CYCLE_MS);// 延时1秒}

解决方案

将主循环中的轮询调用调整为合理的频率,确保状态机能够正常切换。调整后的代码如下:

while(1){MX_LWIP_Process();// Modbus 从机轮询eMBPoll();// 主站轮询,调整频率以避免回读问题if(HAL_GetTick()-lastPollTime1>=200){eMBMasterPoll();lastPollTime1=HAL_GetTick();// 延时200ms}// 非阻塞方式轮询,避免 HAL_Delay 占用 CPU。if(HAL_GetTick()-lastPollTime>=1000){test(MB_USER_READ_CALLBACK);lastPollTime=HAL_GetTick();// 延时1秒}}

总结

通过调整主循环中 Modbus 主站轮询的调用频率,解决了eRcvState一直保持在STATE_M_RX_IDLE的问题,确保了主站能够正常接收数据。此调试过程强调了合理设置轮询频率的重要性,避免因调用过于频繁导致状态机无法正常运作。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/13 16:48:14

13个OFD标准测试文件:完整验证套件快速获取指南

13个OFD标准测试文件&#xff1a;完整验证套件快速获取指南 【免费下载链接】OFD标准测试文件下载 本仓库提供了一个名为“ofd标准测试文件.zip”的资源文件下载。该文件包含了13个OFD测试文件&#xff0c;适用于OFD标准的测试和验证 项目地址: https://gitcode.com/open-sou…

作者头像 李华
网站建设 2026/8/13 17:36:34

gif-h动态GIF生成终极指南:三行代码搞定专业动画

gif-h动态GIF生成终极指南&#xff1a;三行代码搞定专业动画 【免费下载链接】gif-h Simple C one-header library for the creation of animated GIFs from image data. 项目地址: https://gitcode.com/gh_mirrors/gi/gif-h 还在为生成动态GIF而头疼吗&#xff1f;gif-…

作者头像 李华
网站建设 2026/8/13 18:19:47

代码绘图革命:用Diagrams轻松绘制专业云系统架构图

代码绘图革命&#xff1a;用Diagrams轻松绘制专业云系统架构图 【免费下载链接】diagrams :art: Diagram as Code for prototyping cloud system architectures 项目地址: https://gitcode.com/GitHub_Trending/di/diagrams 还在为绘制复杂的云系统架构图而头疼吗&#…

作者头像 李华
网站建设 2026/8/14 0:03:02

Wan2.2-T2V-A14B模型在按需付费Token体系中的定价策略建议

Wan2.2-T2V-A14B模型在按需付费Token体系中的定价策略建议从一个现实问题说起&#xff1a;为什么视频生成的“价格”不能照搬图文&#xff1f; 在当前AIGC服务普遍采用API化、按量计费的大趋势下&#xff0c;很多平台直接沿用自然语言处理中“Token词元”的定义来计量文本到图像…

作者头像 李华
网站建设 2026/8/12 15:59:52

CMLE053T-4R7MS:高性能金属粉尘磁芯电感器, 现货库存

型号介绍&#xff1a; 今天我要向大家介绍的是 Cyntec 的一款电感器——CMLE053T-4R7MS。 它采用金属粉尘磁芯&#xff0c;能够承受高达4.7μH的电感值&#xff0c;即使在3MHz的高频下也能稳定工作。它的直流电阻很低&#xff0c;损耗也很小&#xff0c;能够有效地将电能转化为…

作者头像 李华
网站建设 2026/8/14 2:58:43

能量比黄柱的多长的多绿色多跌得多实际操作很重要

{}多:IF(C>REF(C,1),V,0)/100; 空:IF(C<REF(C,1),V,0)/100; 正:EMA(MA(多,3),3); 负:EMA(MA(空,3),10),colorgreen,; STICKLINE(正,正,0,10,0),colorred; STICKLINE(正>0 AND 正>REF(正,1),正*4/5,0,10,0),COLOR10D3FF; STICKLINE(正>0 AND 正>REF(正,1),正*…

作者头像 李华