RS485问题记录

RS485正确调用方式

	HAL_UART_Receive_IT(&huart3, RxBuffer,MAX_RX_BUFFER_SIZE);
	HAL_UARTEx_ReceiveToIdle_IT(&huart3,RxBuffer,MAX_RX_BUFFER_SIZE);//两次激活

    while (1)
    {
		HAL_UARTEx_ReceiveToIdle_IT(&huart3,RxBuffer,MAX_RX_BUFFER_SIZE);//重复激活
		if (UART_Size > 0)
		{
			LED_Y(1);
			Process_UART();
		}
		LED_Y(0);
    }

//在中断里激活一次
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
//printf("IDLE callback IN\r\n");
		if (huart->Instance == USART3){
			UART_Size = Size;
			
			HAL_UARTEx_ReceiveToIdle_IT(&huart3,RxBuffer,MAX_RX_BUFFER_SIZE);
		}
}

无论何时重启都可以挂入

1.删除HAL_UART_Receive_IT(&huart3, RxBuffer,MAX_RX_BUFFER_SIZE);

仍然正常响应

2.删除HAL_UARTEx_ReceiveToIdle_IT(&huart3,RxBuffer,MAX_RX_BUFFER_SIZE);

仍然正常响应

3.均删除

仍然正常响应

4.删除主循环中的HAL_UARTEx_ReceiveToIdle_IT(&huart3,RxBuffer,MAX_RX_BUFFER_SIZE);

数据发送时仍然正常响应,但重启后再给入数据不再正常响应,这里就是最大的问题,为什么呢,

因为这里两个函数都有激活中断的作用

1.在外部给数据的情况下,程序执行到第一句HAL_UART_Receive_IT(&huart3, RxBuffer,MAX_RX_BUFFER_SIZE);的时候,进入的不是空闲中断,而是串口的IRQ函数,继而进入串口的非空闲中断回调程序,这个时候因为没有对中断标志位进行复位,当程序返回,再次初识化的时候,因为使能了空闲中断,因此后续的程序可以正常响应清除再响应。

2.在外部没给数据的情况下,程序执行到第一句HAL_UART_Receive_IT(&huart3, RxBuffer,MAX_RX_BUFFER_SIZE);的时候,不再进入中断,再次使能了空闲中断的时候,此时两个中断的都被使能,因为空闲中断的优先级较低,因此在后续数据给到的时候,优先响应了非空闲中断,并且此时的中断标志位没有被清除,因此后续就不再响应中断。

解决办法就是删去非空闲中断的使能。

经测试,删去后无论如何都可以正常响应

posted @ 2024-08-04 15:30  为鲸  阅读(6)  评论(0编辑  收藏  举报