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参数成功 */
}
}移植程序如附件
还望请大佬指点下
你好,
根据你提供的信息,问题可能出在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 发表于 2025-4-29 12:18
看标题以为是学习心得贴,楼主问题解决了吗?
测试上传的工程是在循环发送呀
上传的程序没有问题,只适合学习用,后移植的发下其中不少问题,只发送接收一次原因是程序移植通信参数搞错了,后期还遇到在MODBUSSLAVE里面数据是对的,到程序里面是错误的,原因在串口中断的时候没有STC模块程序处理的完善,还是没有配置好的原因,上传程序的寄存器好只能是0X0301,
同样目前还有一个负值的问题,没有解决,P01和P02在遇到负值的时候没有处理的 方式
页:
[1]