程序卡死,上位机接受不到数据(Modbus通讯)

使用Modbus通讯传输数据,上位机每隔300ms发送一次指令,在调试过程中,发现刚开始还正常,但是过一会就会卡死,上位机不再能接收到数据。

现象:上位机传输一段时间后,接收不到数据,但程序可以看见能接收到上位机下发的指令(因为仍然可以看到Rxbuf数据会刷新,也就是可以接收数据,但是却不执行该对应的操作。),所以似乎是卡在了接收中断。

推测1:是否卡在主函数某个循环?

没有,因为加断点在while1后并未停下。也就是没有进入while1

推测2:是否因为标志位未清除?RXNE?ORE?TC?

网上搜了一通,基本上都是标志位问题,于是我加上了标志位清除,错误处理,接收完成标志位清除等。在调试状态,可以看见标志位是否清除成功。但仍然在几分钟到一小时不等的时间内会出现卡死。(应该先测试是否标志位未清除,再加上相应的清除操作才对)

Keil5查看寄存器/标志位,具体操作方法如下:

程序卡死,上位机接受不到数据(Modbus通讯)_第1张图片

 以下是HAL的空闲标志位清除函数:

if(__HAL_USART_GET_FLAG(&husartx_rs232,USART_FLAG_IDLE)!= RESET) 
	{
		__HAL_UART_CLEAR_FLAG(&husartx_rs232,USART_FLAG_IDLE); 
    }

其它标志为同理,可以用该函数清除:(或者如果出现清除不了的情况,可以用读写寄存器的方法,具体操作大家自行搜索)

 程序卡死,上位机接受不到数据(Modbus通讯)_第2张图片

 其实,一般只需要判断RXNE+IDLE就足够,加了太多其他的没有意义。除非是能确定某个中断标志位一直不能清除成功。

推测3:是否卡在了其他地方?

经加断电后单步调试,发现最后总会进入AD采样的while循环中。此处在AD转换时,这里写了一个while需要一直等待一个高电平信号,才继续往下执行,代表开始转换。

程序卡死,上位机接受不到数据(Modbus通讯)_第3张图片

解决办法想法是加入一个时间,如果到达该时间还未结束就跳出该while循环。(此处加入计数)

	  while((GPIOB->IDR & MS5182_SDO_PIN)!=0)
		{
			a1++;
			if(a1==5000)
			{
				a1=0;
				break;
			}
		}

经调试,再未出现程序卡死。

你可能感兴趣的:(STM32,单片机,stm32)