У меня проблема с поведением USART, и мне интересно, может ли кто-нибудь из вас помочь! Я использую STM32F303 с тремя используемыми USART, из которых USART1 настроен как асинхронный порт RS485 с автоматически управляемой линией DE. Выводы TX, RX и DE микроконтроллера подключены к приемопередатчику TI SN65HVD1792 RS485, который предоставляет пользователю для связи четыре линии (TX+, TX-, RX+, RX-).
Я использую связь USART, управляемую прерываниями, которая в большинстве случаев работает абсолютно нормально. Однако у меня возникла проблема с обработкой состояния ошибки, при котором канал RS485 настроен как двухпроводной (TX+/RX+ и TX-/RX- соединены вместе, чтобы сформировать пару +ve/-ve, используемую для обоих передача и прием) и несколько устройств на шине пытаются передавать одновременно. Когда это происходит, STM32 перестает отвечать на все последовательные сообщения до тех пор, пока не будет отключено питание.
Присмотревшись немного ближе к происходящему, я вижу, что USART1_IRQHandler в stm32f3xx_it.c вызывается неоднократно — снова и снова, пока я не выключу и снова не включу плату. Это вызывает HAL_UART_IRQHandler(&huart1) в stm32f3xx_hal_uart.c, функция которого состоит в том, чтобы проверить, какое прерывание произошло (ошибка четности, ошибка кадра, ошибка шума, переполнение, пробуждение после остановки, регистр rx не пуст, tx готов, tx завершен), обработайте его соответствующим образом, а затем очистите состояние прерывания. Однако ни одно из этих конкретных прерываний не распознается как сработавшее — выполнение просто проходит мимо всех операторов «если», функция завершается, а затем снова запускается — бесконечно.
Я не могу найти никакого способа распознать, что это произошло, так как это не вызывает ни одного из распознанных условий ошибки. Я знаю, что конфликтов на шине RS485 следует избегать при правильном проектировании системы, но мы не можем исключить вероятность того, что это произойдет, когда система будет установлена у клиента, и она должна быть способна распознавать ошибка, проигнорируйте сообщение «столкновение» и продолжайте — необходимость выключения и выключения питания неприемлема.
Есть ли у кого-нибудь идеи о том, как распознать это состояние/остановить систему от входа в цикл прерывания?
заранее спасибо
Процедура прерывания выглядит следующим образом (файл HAL версии 1.2.0, дата 13 ноября 15)
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
/* UART parity error interrupt occurred -------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE) != RESET))
{
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF);
huart->ErrorCode |= HAL_UART_ERROR_PE;
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
}
/* UART frame error interrupt occurred --------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
{
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF);
huart->ErrorCode |= HAL_UART_ERROR_FE;
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
}
/* UART noise error interrupt occurred --------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_NE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
{
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF);
huart->ErrorCode |= HAL_UART_ERROR_NE;
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
}
/* UART Over-Run interrupt occurred -----------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
{
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
huart->ErrorCode |= HAL_UART_ERROR_ORE;
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
}
/* Call UART Error Call back function if need be --------------------------*/
if(huart->ErrorCode != HAL_UART_ERROR_NONE)
{
HAL_UART_ErrorCallback(huart);
}
/* UART wakeup from Stop mode interrupt occurred -------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_WUF) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_WUF) != RESET))
{
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_WUF);
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
HAL_UARTEx_WakeupCallback(huart);
}
/* UART in mode Receiver ---------------------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET))
{
UART_Receive_IT(huart);
/* Clear RXNE interrupt flag */
__HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
}
/* UART in mode Transmitter ------------------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE) != RESET))
{
UART_Transmit_IT(huart);
}
/* UART in mode Transmitter (transmission end) -----------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_TC) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET))
{
UART_EndTransmit_IT(huart);
}
}
stm32f3xx_it.c
, который вызываетHAL_UART_IRQHandler(UART_HandleTypeDef *huart)
. - person imbearr   schedule 27.04.2016