当前位置: 首页 > news >正文

解决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的问题,确保了主站能够正常接收数据。此调试过程强调了合理设置轮询频率的重要性,避免因调用过于频繁导致状态机无法正常运作。

http://www.cnnetsun.cn/news/20188.html

相关文章:

  • 26、Linux系统桌面环境配置与资源管理指南
  • C++ Primer 中文版高清资源 - 带详细目录的完整学习指南
  • Tabby终极使用手册:从零到精通的完整指南
  • Milkdown终极指南:10分钟快速上手插件化Markdown编辑器
  • Gitee DevOps:信创生态下的企业数字化转型新引擎
  • 终极指南:如何使用Nools规则引擎实现智能决策系统
  • 助力AI+医疗诊断 东软荣获广东省科技进步一等奖
  • COMSOL相控阵超声仿真:phased_array_focus与压力声学模块的mph文件
  • 3分钟掌握VoxCPM:零基础搭建专业级语音克隆系统
  • 国产图数据库:开启数据新“视”界 悦数科技
  • 终极文件管理方案:3步打造专业级云盘系统
  • Python-Skill Bridge:无缝连接Python与Virtuoso的终极解决方案
  • AutoHotkey鼠标自动化终极指南:5分钟解放你的双手
  • reMarkable平板终极管理指南:6款GUI客户端帮你解锁完整生产力
  • 5G赋能全域连接:企业终端管理何以应对“失控”危机?
  • Phi-2模型:5个实用技巧让你快速上手AI文本生成
  • 【Java毕设源码分享】基于springboot+vue的互联网智慧医院体检平台的设计与实现(程序+文档+代码讲解+一条龙定制)
  • Windows文件rmclient.dll丢失或损坏问题 下载修复
  • Spring AOP表达式速查手册
  • QuickAdd API实战指南:打造你的专属智能笔记工作流
  • Windows系统文件samlib.dll缺失损坏问题 下载修复
  • 鸣潮自动化工具完整使用教程:从零开始轻松掌握智能辅助
  • MethylDackel:BS-seq甲基化提取的终极利器
  • RookieAI_yolov8:2025年游戏AI自瞄技术完全指南
  • pywebview与React集成的终极指南:高效构建跨平台桌面应用
  • 大模型微调:不冻结参数 vs 冻结主干
  • 30亿参数改写AI效率范式:Qwen3-30B-A3B如何让企业AI成本降60%?
  • ppInk:Windows平台上的终极协作写作与在线文档编辑指南
  • 3步彻底解决PDFMathTranslate中文乱码:从新手到专家的终极指南
  • React Stripe.js 终极指南:快速构建安全支付系统