找回密码
 立即注册
查看: 60|回复: 3

MODBUS没有持续扫描,且移植程序理解

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-04-30 08:18:51

9

主题

44

回帖

333

积分

中级会员

积分
333
发表于 5 天前 | 显示全部楼层 |阅读模式
你好版主:

    我的问题如下,还望抽空指点下,
前文是移植32G_Project_modbus_rtu_host.zip这个程序,
目前的状态是通信也成功了,数值也有反馈,

Rx:19-11:02:11.414-01 03 03 01 00 01 D5 8E


Tx:20-11:02:11.414-01 03 02 00 64 B9 AF

所使用的MAIN程序是

  1. if (B_1MS)
  2.                 {
  3.                         B_1MS = FALSE;
  4.                         if (++SysCount[0] >= 10)
  5.                         {
  6.                                 SysCount[0]=0;
复制代码
Printf("modbus host read reg[%hu] value:%hu\n",REG_P01,g_tHostVar.P01);
}

按照我的理解它应该重复发送,并且读取这样一个循环。可是目前的情况是每次上电只发送和接收一次。具体程序如下
  1. /*******************************************************************************
  2. * 名    称: MODH_WriteParam_03H
  3. * 功    能: 读寄存器. 通过发送03H指令实现,发送之后,等待从机应答。循环MODBUS_HOST_RETRYCOUNT次写命令
  4. * 入口参数: _reg:寄存器地址  _num:写入的数量
  5. * 出口参数: 1 表示成功。0 表示失败(通信超时或被拒绝)
  6. * 作  者: Roger-WY
  7. * 创建日期: 2016-06-29
  8. * 修    改:
  9. * 修改日期:
  10. * 备    注:
  11. *******************************************************************************/
  12. uint8 MODH_ReadParam_03H(uint16 _reg, uint16 _num)
  13. {
  14.     int32 time1;
  15.     uint8 i;
  16.     for(i = 0; i < MODBUS_HOST_RETRYCOUNT; i++)
  17.     {
  18.         MODH_Send03H(g_SlaveAddr, _reg, _num);
  19.         time1 = bsp_GetRunTime();        /* 记录命令发送的时刻 */
  20.         while(1)
  21.         {
  22.             //bsp_Idle();
  23.                         MODH_Poll();
  24.             if(bsp_CheckRunTime(time1) > MODBUS_HOST_TIMEOUT)
  25.             {
  26.                 break;                /* 通信超时了 */
  27.             }
  28.             if(g_tModH.fAck03H > 0)
  29.             {
  30.                 break;
  31.             }
  32.         }
  33.         if(g_tModH.fAck03H > 0)
  34.         {
  35.             break;
  36.         }
  37.     }
  38.     if(g_tModH.fAck03H == 0)
  39.     {
  40.         return 0;        /* 通信超时了 */
  41.     }
  42.     else
  43.     {
  44.         return 1;        /* 写入03H参数成功 */
  45.     }
  46. }
复制代码
移植程序如附件

还望请大佬指点下

STC32G_Project_modbus_rtu_host.zip

223.85 KB, 下载次数: 2

回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 5 天前 | 显示全部楼层
你好,

根据你提供的信息,问题可能出在MODBUS主机的扫描机制上。MODBUS协议通常需要主设备(Host)持续发送请求以获取从设备(Slave)的响应。从你的描述来看,程序在上电后只发送和接收一次数据,而没有持续进行扫描和通信。以下是一些可能的原因和解决方案:

1. 主循环中的扫描机制
   你提到主程序中使用了一个1ms的定时器来触发MODBUS通信,但似乎只执行了一次。这可能是因为SysCount[0]的累加逻辑或条件判断存在问题。建议检查以下几点:
SysCount[0]的累加逻辑:确保SysCount[0]在每次1ms中断时正确累加,并且在达到10ms时重置为0。
MODBUS请求的触发条件:确保在SysCount[0]达到10ms时,MODBUS请求被正确触发。

   你可以尝试修改主循环中的代码,确保MODBUS请求被持续触发:

  
  1. c
  2.    if (B1MS)
  3.    {
  4.        B1MS = FALSE;
  5.        if (++SysCount[0] >= 10)
  6.        {
  7.            SysCount[0] = 0;
  8.            // 触发MODBUS请求
  9.            MODHReadParam03H(REGP01, 1); // 读取寄存器
  10.            Printf("modbus host read reg[%hu] value:%hu\n", REGP01, gtHostVarP01);
  11.        }
  12.    }
复制代码

2. MODBUS请求函数的实现
   你提到使用了MODHReadParam03H函数来读取寄存器。确保该函数在每次调用时都会发送MODBUS请求,并且等待从设备的响应。如果该函数内部有某种机制导致它只执行一次,可能需要检查其实现逻辑。

   例如,确保MODHReadParam03H函数中没有类似static变量的机制,导致函数只执行一次。

  
  1. c
  2.    uint8 MODHReadParam03H(uint16 reg, uint16 num)
  3.    {
  4.        // 发送MODBUS请求
  5.        if (MODHSendRequest(0x03, reg, num) == 1)
  6.        {
  7.            // 等待从设备响应
  8.            if (MODHWaitResponse() == 1)
  9.            {
  10.                // 处理响应数据
  11.                return 1; // 成功
  12.            }
  13.        }
  14.        return 0; // 失败
  15.    }
复制代码

3. MODBUS通信的超时处理
   如果MODBUS通信超时,可能会导致主设备停止发送请求。确保在MODHReadParam03H函数中正确处理超时情况,并在超时后重新发送请求。

  
  1. c
  2.    uint8 MODHWaitResponse()
  3.    {
  4.        uint32 timeout = MODBUSTIMEOUT; // 定义超时时间
  5.        while (timeout > 0)
  6.        {
  7.            if (CheckResponse()) // 检查是否有响应
  8.            {
  9.                return 1; // 成功接收到响应
  10.            }
  11.            timeout--;
  12.            Delay(1); // 延时1ms
  13.        }
  14.        return 0; // 超时
  15.    }
复制代码

4. 调试与日志输出
   为了进一步排查问题,建议在关键位置添加调试信息,例如在发送请求和接收响应时打印日志。这有助于你了解程序的执行流程,并确定问题出在哪个环节。

  
  1. c
  2.    uint8 MODHReadParam03H(uint16 reg, uint16 num)
  3.    {
  4.        Printf("Sending MODBUS request: Function 0x03, Reg: %hu, Num: %hu\n", reg, num);
  5.        if (MODHSendRequest(0x03, reg, num) == 1)
  6.        {
  7.            Printf("Waiting for response...\n");
  8.            if (MODHWaitResponse() == 1)
  9.            {
  10.                Printf("Response received successfully.\n");
  11.                return 1; // 成功
  12.            }
  13.            else
  14.            {
  15.                Printf("Response timeout.\n");
  16.            }
  17.        }
  18.        else
  19.        {
  20.            Printf("Failed to send request.\n");
  21.        }
  22.        return 0; // 失败
  23.    }
复制代码

5. 硬件与通信配置
   最后,确保硬件和通信配置正确,例如波特率、数据位、停止位等。如果通信配置不正确,可能会导致MODBUS通信失败。

总结
通过以上步骤,你应该能够排查出MODBUS通信只执行一次的原因。建议从主循环的扫描机制、MODBUS请求函数的实现、超时处理以及调试日志等方面入手,逐步排查问题。如果问题仍然存在,可以提供更多代码细节,以便进一步分析。

希望这些建议对你有所帮助,祝你顺利解决问题!

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2025-05-01 06:56:44
已绑定手机

56

主题

1319

回帖

2938

积分

荣誉版主

无情的代码机器

积分
2938
发表于 前天 12:18 | 显示全部楼层
看标题以为是学习心得贴,楼主问题解决了吗?
测试上传的工程是在循环发送呀

截图202504291218263530.jpg

三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-04-30 08:18:51

9

主题

44

回帖

333

积分

中级会员

积分
333
发表于 前天 13:46 | 显示全部楼层
erci*** 发表于 2025-4-29 12:18
看标题以为是学习心得贴,楼主问题解决了吗?
测试上传的工程是在循环发送呀

上传的程序没有问题,只适合学习用,后移植的发下其中不少问题,只发送接收一次原因是程序移植通信参数搞错了,后期还遇到在MODBUSSLAVE里面数据是对的,到程序里面是错误的,原因在串口中断的时候没有STC模块程序处理的完善,还是没有配置好的原因,上传程序的寄存器好只能是0X0301,
同样目前还有一个负值的问题,没有解决,P01和P02在遇到负值的时候没有处理的 方式


回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 19:02 , Processed in 0.116920 second(s), 73 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表