Многострочная передача по 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 для ожидания окончания предыдущих передач РАБОТАЕТ отлично.