Мне не хватает некоторых символов, когда я использую метод прерывания UART в STM32F407VET - PullRequest
1 голос
/ 03 июня 2019

Я использую UART1 из STM32F407VE в режиме прерывания.Скорость передачи данных составляет 115200. Я использую последовательное окно Docklight, чтобы прочитать вывод UART.Я отправляю от 15 до 20 символов одновременно.У меня отсутствуют символы, когда я проверяю код с обратной связью, как показано ниже.

Я попытался изменить скорость передачи данных.Но когда я увеличиваю количество символов, та же проблема сохраняется.Это мой обработчик прерываний:

void USART1_IRQHandler(void) {
  uint8_t data;

  HAL_UART_IRQHandler(&huart1);
  __HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_RXNE);

  data = (uint8_t)(huart1.Instance->DR); //& (uint16_t)0x00FFU);

  HAL_UART_Transmit(&huart1, (uint8_t *)&data, 1, 10);
}

Ответы [ 3 ]

2 голосов
/ 03 июня 2019

Вы получаете байт и заносите его в регистр TDR вашего UART. Вероятно, он работает с той же скоростью передачи данных, поэтому до завершения передачи получено новое прерывание приема. Вызов HAL_UART_Transmit блокируется и проверяет, выполняется ли передача. Оператор if(huart->gState == HAL_UART_STATE_READY) вернет false и, таким образом, займет путь else. Это приведет к возвращаемому значению HAL_BUSY. Что указывает на то, что ни одна передача не произошла, потому что она все еще продолжалась.

Вам нужно будет добавить кольцевой буфер, чтобы это исправить. Сохраните полученный байт в контейнере хранения из вашего обработчика прерываний, и другая часть вашей программы должна проверить, не является ли контейнер хранения пустым, и передать содержимое, если оно не пусто. Вам нужно будет отключить прерывания при обновлении контейнера хранения, потому что может возникнуть состояние гонки.

Вы также можете добавить к концу передачи символ окончания передачи, указывающий на то, что безопасно возвращать его вам, и, таким образом, избегая состояния гонки. 0x04 отличный выбор для этого, если вы используете ASCII, потому что он определен как EOT (конец передачи).

Другой вариант - использовать HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) для получения установленного количества байтов в режиме прерывания.

Код библиотеки для UART находится внутри: stm32f4xx_hal_uart.c. HAL для STM довольно читабелен и информативен, не стесняйтесь заглядывать внутрь. Это может помочь в будущем найти другие ошибки. (ST не всегда делает очевидный или совместный выбор в своем коде)

0 голосов
/ 03 июня 2019

Кроме того, вы, вероятно, обгоняете USART. Чтобы подтвердить, попробуйте его на скорости 9600 бод, и если пропадет меньше символов, это ваша проблема. В этом случае вам нужно либо использовать HW handshaking, либо добавить буфер, и не выполнять передачу внутри вашего обработчика IRQ, а выполнять передачу в основном цикле.

0 голосов
/ 03 июня 2019

На самом деле здесь почти все не так.Не снимайте флажок RXNE таким образом.Это очищается аппаратным обеспечением, когда uC читает данные из регистра данных.Не используйте функции блокировки в обработчике прерываний.

Если вы используете HAL, используйте функции обратного вызова.

Мой совет: сначала прочитайте документацию по UC и руководство по HAL, затем начните программирование.

...