主函数如下
int main(void)
{
float temp;
int sum;
delay_init(168);
//初始化 RTU模式 参数二:不用管,参数3:从机地址为1 参数4:9600 参数5:无效验
eMBInit(MB_RTU, 0x01, 0x01, 9600, MB_PAR_NONE);
//启动
LED_Init(); //初始化LED
LCD_Init(); //液晶初始化
Adc_Init(); //内部温度传感器ADC初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
eMBEnable();
p=(unsigned char*)&a;
while(1)
{
if(TRUE)
{
temp=Get_Temprate(); //得到温度值
sum=(int)temp;
if(sum<0)
{
sum=-sum;
usRegHoldingBuf[0]=sum;
printf("当前温度为:-%d",sum/100); //显示负号
}
else
{
usRegHoldingBuf[0]=sum;
printf("当前温度为:%d",sum/100); //无符号
}
printf("\r\n\r\n"); //插入换行
delay_ms(200);
(void)eMBPoll();
a++;
}
if(TRUE)
{
eMBRegHoldingCB(p,1,8,MB_REG_WRITE );
(void)eMBPoll();
a++;
}
}
}
现在用modbus poll读取温度数据出现了如下图的问题,每三秒会报错一次,其余两秒可以正常读取
后来怀疑是printf导致的冲突,于是把程序里所有的printf删除,结果poll里面直接timeout。程序里一共5个printf,注释掉两个,每三秒报一次checksum error;注释掉三个,每六秒报一次;注释掉四个,每我秒报两次。
求问这是什么原因导致的,以及如何修改。
无法直接运行你的代码并看到实际错误信息,只能根据你的描述和提供的代码给出一些可能的问题和建议。
Timing Issue: Modbus协议对计时有严格的要求。如果你的设备在规定的时间内没有响应,Modbus Poll可能会报告一个超时错误。此外,你使用的delay_ms(200);
可能影响读取过程,导致时序问题。
Buffer Overrun: usRegHoldingBuf[0]=sum;
在这里,你将温度值写入了寄存器缓冲区的首地址。如果在同一时刻有其他任务尝试访问或修改这个缓冲区,可能会引发一些问题。
Task Switching: 在你的代码中,Modbus处理(eMBPoll()
)与主循环并行进行。如果MCU在执行Modbus通信任务时被中断以处理其他任务,可能会出现问题。
以下是一些解决建议:
调整 Timing: 调整delay_ms(200);
,或者在应答Modbus请求之后添加一些延迟,确保有足够的时间来处理请求。
访问冲突: 如果存在访问冲突,可以考虑使用互斥锁(mutex)或者信号量(semaphore)来维护usRegHoldingBuf
的访问。
任务调度: 如果你的MCU支持多任务处理,可以考虑使用RTOS(Real-time operating system)来进行更好的任务管理。确保eMBPoll()
在被调用时能够完整运行,而不会被中断。