在下面程序中,保持寄存器内容是恒定的
uint16_t usRegHoldingBuf[REG_HOLDING_NREGS]= {0x147b,0x3f8e,0x147b,0x400e,0x1eb8,0x4055,0x147b,0x408e};
其中是16进制浮点型的数据,但如果我想让其中的一个数据每秒自加一,可以实现吗?我之前尝试写的程序如下
int main(void)
{
delay_init(168);
//初始化 RTU模式 参数二:不用管,参数3:从机地址为1 参数4:9600 参数5:无效验
eMBInit(MB_RTU, 0x01, 0x01, 9600, MB_PAR_NONE);
//启动
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
eMBEnable();
p=(unsigned char*)&a;
// timer2_init(5000-1);
// while(1)
// {
// if(TRUE)
// {
// usRegHoldingBuf[0]=value;
// delay_ms(1000); //调用之前写的毫秒延时函数
// value++;
//
// (void)eMBPoll();
// a++;
// }
// }
while(1)
{
if(TRUE)
{
eMBRegHoldingCB(p,1,8,MB_REG_WRITE );
(void)eMBPoll();
a++;
}
}
}
但是在modbuspoll中始终显示timeout,把timer2那一段注释掉后就正常了,求问应该如何写
while(1)
{
if(TRUE)
{
usRegHoldingBuf[0]=value/5;
delay_ms(200); //调用之前写的毫秒延时函数
value++;
(void)eMBPoll();
a++;
}
}
注释处改成如上程序即可,由于modbus本身有超时限制,是500ms,因此导致timeout
在你的代码中,你似乎尝试使用Modbus协议来更新寄存器的值,但由于一些原因,出现了超时问题。超时通常意味着Modbus通信中发生了错误或卡住。
首先,我注意到你在主循环中使用了 if(TRUE) 条件来更新寄存器。这个条件似乎是恒定为真的,导致你的Modbus请求在每次循环中都发送。这可能导致Modbus通信过于频繁,从而引发问题。你应该根据需要设置一个更合适的触发条件,例如根据时间间隔来更新寄存器。
另外,要实现寄存器每秒加一的功能,你可以使用一个计时器来控制更新频率。以下是一个示例代码,用于每秒更新一个寄存器的值:
c
Copy code
uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {0x147b, 0x3f8e, 0x147b, 0x400e, 0x1eb8, 0x4055, 0x147b, 0x408e};
uint32_t lastUpdateTime = 0;
uint16_t registerToUpdate = 0;
int main(void)
{
delay_init(168);
// 初始化Modbus
eMBInit(MB_RTU, 0x01, 0x01, 9600, MB_PAR_NONE);
eMBEnable();
while (1)
{
// 获取当前时间
uint32_t currentTime = HAL_GetTick();
// 检查是否已经过去1秒
if (currentTime - lastUpdateTime >= 1000)
{
// 更新寄存器的值
usRegHoldingBuf[registerToUpdate]++;
// 记录最后一次更新的时间
lastUpdateTime = currentTime;
// 发送Modbus请求来更新寄存器
eMBRegHoldingCB(usRegHoldingBuf, registerToUpdate, 1, MB_REG_WRITE);
}
// 调用Modbus轮询
(void)eMBPoll();
}
}
在上述示例中,我们使用了 HAL_GetTick() 函数来获取当前的系统时间,并检查是否已经过去了1秒。如果是,就更新寄存器的值,并通过Modbus请求将新的值发送给Modbus从设备。每秒更新一个寄存器,并依次更新,直到循环回到第一个寄存器。这样就实现了每秒加一的功能。请注意,你需要根据你的硬件和操作系统环境进行适当的修改和配置。
非常感谢,由于本身定时器相关内容学的不太好,水平也有限,就没敢用,看到你用的时hal库函数实现的,求问是否有通过定时器实现的程序。
就是使用定时器标志位而非延时函数