Я использую прерывание на основе UART IO (без DMA).
HAL_UART_Transmit_IT
функция устанавливает EIE
бит в CR3
регистре. В соответствии с таблицей данных STM32F407 (и реальным поведением), это генерирует прерывание только в многобуферном режиме (когда DMAR
бит установлен). EIE
позволяет генерировать прерывания для ошибки кадра ( FE
), ошибки переполнения ( ORE
), ошибки шума ( NE
). Эта ошибка, как я понимаю, только для получения.
Часть HAL_UART_IRQHandler
функции:
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
/* UART Over-Run interrupt occurred ----------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_OREFLAG(huart);
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}
if(huart->ErrorCode != HAL_UART_ERROR_NONE)
{
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
HAL_UART_ErrorCallback(huart);
}
HAL_UART_IRQHandler
проверяет каждую ошибку. Если произошла ошибка и EIE
бит установлен, он сбрасывает состояние UART, но не сбрасывает биты разрешения прерываний, поэтому TXE
прерывание будет всегда генерироваться, но UART_Transmit_IT
функция обрабатывает состояние HAL_UART_STATE_READY
как недействительное и ничего не делает. Бесконечный цикл.
Часть UART_Transmit_IT
функции:
static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
{
uint16_t* tmp;
uint32_t tmp1 = 0;
tmp1 = huart->State;
if((tmp1 == HAL_UART_STATE_BUSY_TX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX))
{
}
else
{
return HAL_BUSY;
}
}
Это ошибка в Cube HAL?
источник
Ответы:
Это ошибка.
Я задал тот же вопрос на форуме ST: https://my.st.com/d5c15f59
Они подтвердили это.
источник
Вы пытались загрузить последнюю версию Cube HAL для своего MCU?
Моя функция HAL_UART_Transmit_IT (), кажется, сильно отличается от вашей. Может быть, у вас есть старая версия с ошибками.
Попробуйте зайти на st.com и найти последнюю версию Cube HAL. Внутри архива вы найдете несколько примеров с USART.
источник
HAL_UART_Transmit_IT
иUART_Transmit_IT
разные функции. Первый только устанавливает прерывания, а второй фактически передает данные