使用Modbus通讯传输数据,上位机每隔300ms发送一次指令,在调试过程中,发现刚开始还正常,但是过一会就会卡死,上位机不再能接收到数据。
现象:上位机传输一段时间后,接收不到数据,但程序可以看见能接收到上位机下发的指令(因为仍然可以看到Rxbuf数据会刷新,也就是可以接收数据,但是却不执行该对应的操作。),所以似乎是卡在了接收中断。
推测1:是否卡在主函数某个循环?
没有,因为加断点在while1后并未停下。也就是没有进入while1
推测2:是否因为标志位未清除?RXNE?ORE?TC?
网上搜了一通,基本上都是标志位问题,于是我加上了标志位清除,错误处理,接收完成标志位清除等。在调试状态,可以看见标志位是否清除成功。但仍然在几分钟到一小时不等的时间内会出现卡死。(应该先测试是否标志位未清除,再加上相应的清除操作才对)
Keil5查看寄存器/标志位,具体操作方法如下:
以下是HAL的空闲标志位清除函数:
if(__HAL_USART_GET_FLAG(&husartx_rs232,USART_FLAG_IDLE)!= RESET)
{
__HAL_UART_CLEAR_FLAG(&husartx_rs232,USART_FLAG_IDLE);
}
其它标志为同理,可以用该函数清除:(或者如果出现清除不了的情况,可以用读写寄存器的方法,具体操作大家自行搜索)
其实,一般只需要判断RXNE+IDLE就足够,加了太多其他的没有意义。除非是能确定某个中断标志位一直不能清除成功。
推测3:是否卡在了其他地方?
经加断电后单步调试,发现最后总会进入AD采样的while循环中。此处在AD转换时,这里写了一个while需要一直等待一个高电平信号,才继续往下执行,代表开始转换。
解决办法想法是加入一个时间,如果到达该时间还未结束就跳出该while循环。(此处加入计数)
while((GPIOB->IDR & MS5182_SDO_PIN)!=0)
{
a1++;
if(a1==5000)
{
a1=0;
break;
}
}
经调试,再未出现程序卡死。