首页 新闻 会员 周边 捐助

modbus03功能如何实现寄存器数值每秒加1

0
悬赏园豆:5 [待解决问题]

在下面程序中,保持寄存器内容是恒定的
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那一段注释掉后就正常了,求问应该如何写

风满楼观世界的主页 风满楼观世界 | 初学一级 | 园豆:192
提问于:2023-09-12 08:57
< >
分享
所有回答(2)
0

while(1)
{
if(TRUE)
{
usRegHoldingBuf[0]=value/5;
delay_ms(200); //调用之前写的毫秒延时函数
value++;

		(void)eMBPoll();
		a++;
		}
	}

注释处改成如上程序即可,由于modbus本身有超时限制,是500ms,因此导致timeout

风满楼观世界 | 园豆:192 (初学一级) | 2023-09-12 10:11
1

在你的代码中,你似乎尝试使用Modbus协议来更新寄存器的值,但由于一些原因,出现了超时问题。超时通常意味着Modbus通信中发生了错误或卡住。

首先,我注意到你在主循环中使用了 if(TRUE) 条件来更新寄存器。这个条件似乎是恒定为真的,导致你的Modbus请求在每次循环中都发送。这可能导致Modbus通信过于频繁,从而引发问题。你应该根据需要设置一个更合适的触发条件,例如根据时间间隔来更新寄存器。

另外,要实现寄存器每秒加一的功能,你可以使用一个计时器来控制更新频率。以下是一个示例代码,用于每秒更新一个寄存器的值:

c
Copy code

include "stm32f4xx.h"

include "mb.h"

include "mbport.h"

define REG_HOLDING_NREGS 8

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从设备。每秒更新一个寄存器,并依次更新,直到循环回到第一个寄存器。这样就实现了每秒加一的功能。请注意,你需要根据你的硬件和操作系统环境进行适当的修改和配置。

Technologyforgood | 园豆:7541 (大侠五级) | 2023-09-17 22:34

非常感谢,由于本身定时器相关内容学的不太好,水平也有限,就没敢用,看到你用的时hal库函数实现的,求问是否有通过定时器实现的程序。

支持(0) 反对(0) 风满楼观世界 | 园豆:192 (初学一级) | 2023-09-19 08:59

就是使用定时器标志位而非延时函数

支持(0) 反对(0) 风满楼观世界 | 园豆:192 (初学一级) | 2023-09-19 09:07
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册