USART-Interrupt funktioniert nicht wie erwartet [STM32 Nucleo]

könnte jemand erklären, warum ich nur 13 Zeichen mit USART-Interrupt empfangen kann? Ich verwende '\n', um das Ende der Zeichenfolge zu erkennen.Geben Sie hier die Bildbeschreibung ein

#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);
    }
Was passiert, wenn Sie es ohne CR oder in kleineren Teilen senden?
Komisch, dass Sie sagen, dass Sie prüfen, \naber Ihr Code prüft, \rwas 13 ist, und Sie verarbeiten nur 13 Bytes, aber warum gibt dann strlenmehr als 13 an und sendet einige 0x00-Bytes mit (<0>) - die Nachricht, die Sie zurückbekommen ist die Länge der übertragenen Nachricht nur der Inhalt der letzten 3 Bytes falsch.
@Trevor_G Wenn ich kleinere Chunks (weniger als 14) einsende, ist es in Ordnung, alles funktioniert gut. Und wenn ich ohne CR sende, erscheint es überhaupt nicht.
Ja, ich meinte, wenn Sie 12345678 senden, dann senden Sie 12345678 +CR, was bekommen Sie zurück.
@Trevor_G das habe ich: Empfangene Daten: 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
mach es nochmal.. (oder zweimal) bekommst du das gleiche
Nach dem Senden 1 Mal ohne CR und 1 Mal mit CR. Zweimal wiederholt. 16:12:57.286> Empfangene Daten: 1234567812345<0><0><0> 16:13:00.722> Empfangene Daten: 1234567812345<0><0><0
YA Ich denke, der erste Mist ist, dass Sie den Puffer nicht initialisieren. Aber ich denke auch, dass Sie die Daten an der falschen Stelle erhalten. Siehe diesen Cross-Post electronic.stackexchange.com/a/266976/139766
Was passiert, wenn Sie versuchen, "abcdefghijklmno" zu senden?
@Trevor_G STM32 CubeMX generiert keine void HAL_UART_MspInit (UART_HandleTypeDef* huart) Funktion, also ist es vielleicht nicht notwendig. @MITU RAJ Wenn ich "abcdefghijklmno" sende, bekomme ich abcdefghijklm<0><0>
Können Sie die Baudrate reduzieren und erneut prüfen?
@MITURAJ Ich habe die Baudrate auf 9600 reduziert und dann sende ich dieselbe Zeichenfolge, die ich bekomme: <0><0><0><0><0><0><0><0><0><0><0 ><0><0> . Also ist es vielleicht ein Problem mit der Baudrate?
Hast du sowohl deine stm32 als auch die Terminal-Baudrate auf 9600 geändert?
Ja, sie sind beide 9600.
Wenn es bei 9600 funktioniert hätte, hätten wir daraus schließen können, dass die hohe Baudrate das Problem war.
Guter Fang ... das ist genau der Grund, warum es bei langsamerer Baudrate schlimmer wurde, es kam zu einem Überlauf am RX-Puffer auf der PC-Seite.
Ich denke, Sie können jetzt die Antwort auf Ihre eigene Frage aufschreiben.
Dies ist nicht das erste Mal, dass Verzögerungen alles durcheinander bringen.

Antworten (2)

Ich habe das Problem gefunden. In der Funktion void USART2_receive(void const * argument) habe ich die Verzögerung von 50 auf 100 erhöht und dann funktioniert alles einwandfrei. Wie @MITURAJ erwähnt hat, kann dies durch einen Pufferüberlauf verursacht werden.

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));
        }
    }
}
Was ist der Zweck der Verzögerung, und warum wurde das Problem durch eine Erhöhung behoben?
Ich weiß nur nicht, wie ich einen Kommentar als hilfreiche Antwort markieren soll

Wenn Sie feststellen, dass Sie eine längere Verzögerung benötigen, sollten Sie darauf hinweisen, dass Sie nicht darauf warten, dass der Tx tatsächlich beendet wird. HAL_UART_Transmit_IT verwendet einen Interrupt, um Bytes zu senden (es ist nicht blockierend). Sie sagen ihm im Grunde, dass er senden soll, warten ein wenig und stopfen Daten erneut in den Puffer, bevor die Übertragung abgeschlossen ist!

Stattdessen schlage ich vor, dass Sie den Rückruf an HAL_UART_TxCpltCallback überwachen und sobald dies geschieht, ein Flag setzen. Warten Sie in Ihrer USART2_receive-Funktion, bis das Flag gesetzt ist, bevor Sie es auffordern, Dinge erneut zu senden. Denken Sie daran, das Flag zu löschen, bevor Sie darauf warten, dass es wieder gesetzt wird :)

Vielen Dank für die detaillierte Erklärung, es war ziemlich schwierig, diese Änderungen zu implementieren, da ich Junior-Entwickler bin. Vielleicht gibt es Beispiele, denen ich für diese Funktion folgen könnte?
@Into_Embedded, es ist ziemlich einfach, es ist wie die HAL_UART_RxCpltCallback-Funktion. Der CubeMx generiert wahrscheinlich die TxCpltCallback-Funktion für Sie und Sie müssen sie nur noch ausfüllen. Schauen Sie sich auch die STM32-Beispiele an, da sollte etwas für nicht blockierendes UART dabei sein.
Ich werde mir das jetzt auf jeden Fall ansehen, es sieht nicht so gelehrt aus, wie es zuerst aussah.