zackwu 发表于 6 天前

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

你好版主:

    我的问题如下,还望抽空指点下,
前文是移植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程序是

if (B_1MS)
                {
                        B_1MS = FALSE;
                        if (++SysCount >= 10)
                        {
                              SysCount=0;Printf("modbus host read reg[%hu] value:%hu\n",REG_P01,g_tHostVar.P01);
}

按照我的理解它应该重复发送,并且读取这样一个循环。可是目前的情况是每次上电只发送和接收一次。具体程序如下/*******************************************************************************
* 名    称: MODH_WriteParam_03H
* 功    能: 读寄存器. 通过发送03H指令实现,发送之后,等待从机应答。循环MODBUS_HOST_RETRYCOUNT次写命令
* 入口参数: _reg:寄存器地址_num:写入的数量
* 出口参数: 1 表示成功。0 表示失败(通信超时或被拒绝)
* 作  者: Roger-WY
* 创建日期: 2016-06-29
* 修    改:
* 修改日期:
* 备    注:
*******************************************************************************/
uint8 MODH_ReadParam_03H(uint16 _reg, uint16 _num)
{
    int32 time1;
    uint8 i;

    for(i = 0; i < MODBUS_HOST_RETRYCOUNT; i++)
    {
      MODH_Send03H(g_SlaveAddr, _reg, _num);
      time1 = bsp_GetRunTime();      /* 记录命令发送的时刻 */

      while(1)
      {
            //bsp_Idle();
                        MODH_Poll();

            if(bsp_CheckRunTime(time1) > MODBUS_HOST_TIMEOUT)
            {
                break;                /* 通信超时了 */
            }

            if(g_tModH.fAck03H > 0)
            {
                break;
            }
      }

      if(g_tModH.fAck03H > 0)
      {
            break;
      }
    }

    if(g_tModH.fAck03H == 0)
    {
      return 0;      /* 通信超时了 */
    }
    else
    {
      return 1;      /* 写入03H参数成功 */
    }
}移植程序如附件

还望请大佬指点下

国芯人工智能 发表于 6 天前

你好,

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

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

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

   c
   if (B1MS)
   {
       B1MS = FALSE;
       if (++SysCount >= 10)
       {
         SysCount = 0;
         // 触发MODBUS请求
         MODHReadParam03H(REGP01, 1); // 读取寄存器
         Printf("modbus host read reg[%hu] value:%hu\n", REGP01, gtHostVarP01);
       }
   }

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

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

   c
   uint8 MODHReadParam03H(uint16 reg, uint16 num)
   {
       // 发送MODBUS请求
       if (MODHSendRequest(0x03, reg, num) == 1)
       {
         // 等待从设备响应
         if (MODHWaitResponse() == 1)
         {
               // 处理响应数据
               return 1; // 成功
         }
       }
       return 0; // 失败
   }

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

   c
   uint8 MODHWaitResponse()
   {
       uint32 timeout = MODBUSTIMEOUT; // 定义超时时间
       while (timeout > 0)
       {
         if (CheckResponse()) // 检查是否有响应
         {
               return 1; // 成功接收到响应
         }
         timeout--;
         Delay(1); // 延时1ms
       }
       return 0; // 超时
   }

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

   c
   uint8 MODHReadParam03H(uint16 reg, uint16 num)
   {
       Printf("Sending MODBUS request: Function 0x03, Reg: %hu, Num: %hu\n", reg, num);
       if (MODHSendRequest(0x03, reg, num) == 1)
       {
         Printf("Waiting for response...\n");
         if (MODHWaitResponse() == 1)
         {
               Printf("Response received successfully.\n");
               return 1; // 成功
         }
         else
         {
               Printf("Response timeout.\n");
         }
       }
       else
       {
         Printf("Failed to send request.\n");
       }
       return 0; // 失败
   }

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

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

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

[本文内容由国芯人工智能辅助生成,仅供参考]

ercircle 发表于 3 天前

看标题以为是学习心得贴,楼主问题解决了吗?
测试上传的工程是在循环发送呀



zackwu 发表于 3 天前

ercircle 发表于 2025-4-29 12:18
看标题以为是学习心得贴,楼主问题解决了吗?
测试上传的工程是在循环发送呀


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


页: [1]
查看完整版本: MODBUS没有持续扫描,且移植程序理解