Многострочная передача по USART с использованием CubeMx

Я пытался USART используя STM32F407VGT6 а также CubeMX,

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

я использую HAL_UART_Transmit_IT отправить данные.
Я включил __HAL_UART_ENABLE_IT(&huart3,UART_IT_TC);,

Вот мой код:

int main(void)
{
  HAL_Init();
  MX_GPIO_Init();
  MX_USART3_UART_Init();
  Green_Blink(100);
  Orange_Blink(100);
  Blue_Blink(100);
  Red_Blink(100);
  HAL_Delay(100);

  __HAL_UART_ENABLE_IT(&huart3,UART_IT_TC);
  char buff[] = {'2','4','.','0','0'};
  while (1)
  {
        HAL_UART_Transmit_IT(&huart3,(uint8_t*)"OK\r\n ",5);
        HAL_UART_Transmit_IT(&huart3,(uint8_t*)buff,5);
        HAL_UART_Transmit_IT(&huart3,(uint8_t*)"OK\r\n ",5);
        HAL_UART_Transmit_IT(&huart3,(uint8_t*)buff,5);
        HAL_UART_Transmit_IT(&huart3,(uint8_t*)"OK\r\n ",5);
        HAL_UART_Transmit_IT(&huart3,(uint8_t*)buff,5);
        HAL_Delay(1000);
        Blue_Blink(100);

  }
}

Поэтому я отправляю данные такого рода. Сначала я отправляю OK а затем я отправляю данные буфера, как вы можете видеть.

Но в терминале (тера термин в моем случае) я не вижу данные буфера.
я могу видеть OK,

Я не знаю, почему это происходит. И как это решить?
Какие-либо предложения?

1 ответ

Решение

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

Вы просто переопределяете буфер и начинаете передачу заново.

Для такого рода сообщений используйте функции блокировки. Используйте DMA или прерывания, когда ваша основная программа что-то делает во время общения, и вы хотите, чтобы общение происходило в фоновом режиме.

редактировать

Некоторое объяснение. Функции прерывания HAL не ожидают завершения передачи. Они немедленно возвращаются вызывающей стороне, и связь завершается в фоновом режиме. Основная программа может выполняться параллельно, выполняя другие задачи. Когда все байты отправлены (или в случае ошибки), библиотека HAL вызывает соответствующий обратный вызов. Для конца передачи это: void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)

Из-за асинхронного выполнения, если вы хотите начать другую передачу, вам нужно знать, если предыдущая уже завершена.

Редактировать 2

В этом случае нет смысла отправлять асинхронно. Вам нужно дождаться окончания предыдущих передач:

volatile int USART3TransferCompleted;

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    USART3TransferCompleted = 1; // this functions should check the instance as well
}

и в основной функции:

        USART3TransferCompleted = 0;
        HAL_UART_Transmit_IT(&huart3,(uint8_t*)"OK\r\n ",5);
        while(!USART3TransferCompleted);
        USART3TransferCompleted = 0;
        HAL_UART_Transmit_IT(&huart3,(uint8_t*)buff,5);
        while(!USART3TransferCompleted);
        ...
if(HAL_UART_Transmit(&huart2, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 5000)!= HAL_OK)
    {
      Error_Handler();
    }

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

Я создал свою учетную запись, чтобы поблагодарить P__J__.

Я изо всех сил пытался отправить несколько HAL_UART_Transmit_IT в строке, как показано ниже.

HAL_UART_Transmit_IT(&huart1,(uint8_t*) Test_Buffer1, length1);HAL_Delay (1000);HAL_UART_Transmit_IT(&huart1,(uint8_t*) Test_Buffer2, length2);

Решение P__J__, указанное выше, с использованием HAL_UART_TxCpltCallback для ожидания окончания предыдущих передач РАБОТАЕТ отлично.

Другие вопросы по тегам