Прерывание USART не работает должным образом [STM32 Nucleo]

может кто-нибудь объяснить, почему я могу получить только 13 символов с прерыванием USART? Я использую '\n' для определения конца строки.введите описание изображения здесь

#define BUFFER_SIZE 100

char receive_buffer[BUFFER_SIZE];
char receive_data;
int receive_index = NULL;
int data_ready_index = NULL;

void USART2_receive(void const * argument){
         for(;;){
                if(data_ready_index == 1){
                HAL_UART_Transmit_IT(&huart2, (uint8_t *)"Received data: ", strlen("Received data: "));
                HAL_Delay(50);
                HAL_UART_Transmit_IT(&huart2, (uint8_t *)receive_buffer, strlen(receive_buffer));
                memset(receive_buffer, NULL, sizeof(receive_buffer));
                HAL_Delay(50);
                HAL_UART_Transmit_IT(&huart2, (uint8_t *)"\r\n", strlen("\r\n"));
                data_ready_index = NULL;
                }
         }
     }

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {

        if (huart->Instance == USART2){
            if (receive_data != 13){
                receive_buffer[receive_index++]=receive_data;
            }else{
                    receive_index = NULL;
                    data_ready_index = 1;                                                               
                    // Received data ready to be processed
            }
      }
    }

    void USART2_IRQHandler(void){

      HAL_UART_IRQHandler(&huart2);
      HAL_UART_Receive_IT(&huart2, (uint8_t *) &receive_data, 1);
    }
Что происходит, когда вы отправляете его без CR или небольшими порциями?
Забавно, что вы говорите, что вы проверяете, \nно ваш код проверяет, \rчто равно 13, и вы обрабатываете только 13 байтов, но тогда почему выдаете strlenбольше 13 и отправляете с ними несколько 0x00 байтов (<0>) - сообщение, которое вы возвращаете это длина передаваемого сообщения, только содержимое последних 3 байтов неверно.
@Trevor_G, если я отправлю небольшими порциями (менее 14), все в порядке, все работает нормально. А если я отправляю без CR, то он вообще не появляется.
Я имел в виду, если вы отправите 12345678, то отправите 12345678 + CR, что вы получите в ответ.
@Trevor_G вот что я получил: Полученные данные: 1<0><0><0><0><0><0><0><0><0><0><0><0><0> <0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0 ><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0>< 0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0> <0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0 ><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0 16:06:36.636> >231231231231231231234567812345678
сделать это снова .. (или дважды) вы получите то же самое
После отправки 1 раз без CR и 1 раз с CR. Повторил дважды. 16:12:57.286> Полученные данные: 1234567812345<0><0><0> 16:13:00.722> Полученные данные: 1234567812345<0><0><0
YA Я думаю, что первая хрень в том, что вы не инициализируете буфер. Но я также думаю, что вы получаете данные не в том месте. См. этот перекрестный пост electronics.stackexchange.com/a/266976/139766
Что произойдет, если вы попытаетесь отправить «abcdefghijklmno»
@Trevor_G STM32 CubeMX не генерирует функцию void HAL_UART_MspInit(UART_HandleTypeDef* huart), поэтому, возможно, в этом нет необходимости. @MITU RAJ Если я отправлю «abcdefghijklmno», я получу abcdefghijklm<0><0>
Можете ли вы уменьшить скорость передачи данных и проверить еще раз?
@MITURAJ Я уменьшил скорость передачи данных до 9600, а затем отправляю ту же строку, что и получаю ab<0><0><0><0><0><0><0><0><0><0><0 ><0><0> . Так что, может быть, проблема со скоростью передачи данных?
Вы изменили скорость передачи stm32 и терминала на 9600?
Да, они оба 9600.
Если бы он работал на скорости 9600, мы могли бы сделать вывод, что проблема заключается в высокой скорости передачи данных.
Хороший улов ... именно поэтому все стало хуже при более низкой скорости передачи данных, произошло переполнение буфера rx на стороне ПК.
Думаю, теперь вы можете написать ответ на свой вопрос.
Это уже не первый раз задержки потом все портят.

Ответы (2)

Я нашел проблему. В функции void USART2_receive(void const * arguments) я увеличил задержку с 50 до 100, после чего все работает нормально. Как упоминал @MITURAJ, это может быть вызвано переполнением буфера.

void USART2_receive(void const * argument){
    for(;;){
        if(data_ready_index == 1){
            HAL_UART_Transmit_IT(&huart2, (uint8_t *)"Received data: ", 
            strlen("Received data: "));
            HAL_Delay(100);
            HAL_UART_Transmit_IT(&huart2, (uint8_t *)receive_buffer, 
            strlen(receive_buffer));
            HAL_Delay(100);
            HAL_UART_Transmit_IT(&huart2, (uint8_t *)"\r\n", strlen("\r\n"));
            data_ready_index = NULL;
            memset(receive_buffer, NULL, sizeof(receive_buffer));
        }
    }
}
Какова цель задержки и почему ее увеличение решило проблему?
Я просто не знаю, как пометить чей-то комментарий как полезный ответ

Обнаружение того, что вам нужна более длительная задержка, должно подсказать вам, что вы не ждете фактического завершения Tx. HAL_UART_Transmit_IT использует прерывание для отправки байтов (это не блокирует). По сути, вы говорите ему передать, немного подождать и снова втиснуть данные в буфер, прежде чем передача будет завершена!

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

Спасибо за подробное объяснение, реализовать эти изменения довольно сложно, так как я младший разработчик. Может быть, есть какие-нибудь примеры, которым я мог бы следовать для этой функции?
@Into_Embedded, это довольно просто, это похоже на функцию HAL_UART_RxCpltCallback. CubeMx, вероятно, генерирует для вас функцию TxCpltCallback, и вам просто нужно ее заполнить. Взгляните также на примеры STM32, там должно быть что-то для неблокирующего UART.
я определенно посмотрю сейчас, он не выглядит таким ученным, как выглядел сначала.