使用的是stm32系列的407ZGT6做主机,103VET6做从机,采用modbus485通信,主机轮流查询11个从机的寄存器数据(03指令),从机返回相应指令对应的寄存器数据;刚开机一会儿没问题,每个从机都能发回相应的寄存器数据回来;但是大概几分钟后或者更长时间,从机慢慢的就卡死了(用了一个指示灯闪烁判断),现在就是从机为什么会卡死,网上都说是什么ORE中断那些,好像试了下还是没能解决问题
从机使用的串口中断接收主机发来的数据;以下贴的代码都是从机的代码,cubemx生成的标准的hal库函数
void USART2_IRQHandler(void)//串口2接收中断函数
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
HAL_UART_Receive_IT(&huart2, (uint8_t *)&RES,1);
if( modbus.reflag==1) //有数据包正在处理
{
return ;
}
modbus.rcbuf[modbus.recount++] = RES;
modbus.timout = 0;
if(modbus.recount == 1) //已经收到了第一个字符数据
{
modbus.timrun = 1; //开启modbus定时器计时
}
//这个代码就是典型的modbus485通信的代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定时器中断回调函数
{
if (htim->Instance == TIM1)
{
if(modbus.timrun != 0)//运行时间!=0表明已经接收到了一个数据了
{
modbus.timout++;
if(modbus.timout >=8) //8ms接收完数据
{
modbus.timrun = 0;
modbus.reflag = 1;//接收数据完毕
}
}
}
modbus.Host_Sendtime++;//发送完上一帧后的时间计数
if(modbus.Host_Sendtime>1000)//距离发送上一帧数据1s了
{
//1s时间到
modbus.Host_time_flag=1;//发送数据标志位置1
}
}
主函数中为Modbus_Event处理的03、06函数;
if(modbus.Host_time_flag)//每1s发送一次数据 //作为从机使用
{
modbus.Host_time_flag=0;//20220728
Modbus_Event();
osDelay(10);
}
刚开机的时候,11个主机都能正常返回主机对应的命令;但是时间一长几分钟甚至几十分钟慢慢的从机就失联了,工作指示灯灭或者长亮了;
试过将从机的发回的数据屏蔽掉,只做接收主机发来的数据;但是时间长了还是卡死,看来不是发生在从机发送数据给主机这里,而是从机接收数据这里;
解决掉从机死机的问题
先少接几个,比如先接1个,看看有没有这样的问题。如果有,和数量即负载无关,检查程序;如果没有问题,接2个设备,5个设备……如果设备数量超过一定值才会出现,增大轮询间隔
有没有 清从机的接收buff,是不是找不到通信指令了?要仿真监控下从机程序死在哪了?打些断点或者log
加多一些中断吧,stm32之间通信虽然我没试过,但之前我用的Arduino,不过都是单片机想来差不多,我们偶尔也出BUG,这样也方便试出问题的
看你的代码,有几个变量 一直++没有归0,这样的逻辑不会有问题?
单台从站长时间测试有问题没?
博主参考下下面的链接
https://b23.tv/WoLv9Bm
这在中断中调用RTOS的阻塞延时osDelay(10);,程序不死定了?
软件上找不到原因的话加个485集线器试试