news 2026/4/22 17:40:27

解决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/4/17 7:55:58

28、Linux网络服务与Samba配置全解析

Linux网络服务与Samba配置全解析 1. 网络信息服务(NIS)相关操作 在完成NIS配置的部分步骤后,还需进行一些验证操作。首先,点击“Open Port in Firewall”复选框,然后点击“Finish”。接着,为确保NIS服务器正在运行,可在终端中输入 ypwhich 并按下回车键,查看显示信…

作者头像 李华
网站建设 2026/4/17 7:56:06

C++ Primer 中文版:初学者终极完整学习指南

想要快速掌握C编程语言&#xff1f;这份高清带目录的《C Primer》中文版电子书是您的理想选择&#xff01;作为最受推崇的C入门书籍&#xff0c;它以其系统性和实用性成为无数编程学习者的首选C学习资源。 【免费下载链接】CPrimer中文版-高清带目录 C Primer 中文版 - 高清带目…

作者头像 李华
网站建设 2026/4/17 9:03:08

32、深入探究openSUSE Linux系统的性能调优与问题解决

深入探究openSUSE Linux系统的性能调优与问题解决 1. 系统监控与初步操作 首先,登录运行GNOME的openSUSE Linux机器。在终端中输入 gnome-system-monitor 并按下回车键,随后花费几分钟时间查看各个选项卡,尤其关注每个进程所使用的内存量。完成后,关闭终端窗口并关闭虚…

作者头像 李华
网站建设 2026/4/18 11:53:46

Wan2.2-T2V-A14B在儿童内容安全过滤方面的机制解析

Wan2.2-T2V-A14B在儿童内容安全过滤方面的机制解析 如今&#xff0c;AI生成视频已经不再是科幻电影里的桥段。从短视频平台的自动剪辑&#xff0c;到教育类App中动态生成的教学动画&#xff0c;文本到视频&#xff08;Text-to-Video, T2V&#xff09;技术正快速渗透进我们日常生…

作者头像 李华
网站建设 2026/4/20 23:32:49

TrollInstallerX 终极安装指南:iOS 14.0-16.6.1 一键越狱神器

TrollInstallerX 是一款专为 iOS 14.0 至 16.6.1 系统设计的全能 TrollStore 安装工具&#xff0c;以其卓越的可靠性和用户友好性著称。无论您是技术新手还是资深玩家&#xff0c;都能通过本指南快速掌握这款神器的安装和使用技巧。 【免费下载链接】TrollInstallerX A TrollSt…

作者头像 李华
网站建设 2026/4/20 18:58:52

奶奶都能看懂的 C++ —— 手把手指针

引用在正式介绍指针之前&#xff0c;先来看看什么是引用。int a 10;int &ref1 a;你可能注意到了&#xff0c;上面的代码里有个 &。这就是我们的主角&#xff0c;引用。在变量名之前加上该符号&#xff0c;就可以指出它是个引用。我们常说的引用&#xff0c;就是把别人…

作者头像 李华