STM32 UART-Flags mit Pooling-Methode
Ich versuche, einen einfachen Baudratenwechsler mit einer blauen Pille stm32f103 unter Verwendung der HAL-API zu erstellen.
Was ich mir erhoffe: Ein altes Terminal, das auf 9600 Baud gesperrt ist. Ein alter Thermodrucker mit maximal 300 Baud.
Das Projekt besteht aus 2 "blauen Pillen", von denen eine nur einen Zeichenstrom bei 9600 setzt. Die andere blaue Pille nimmt den Strom bei 9600 auf und speichert alle 4 Bytes in ein Register für UART 3. Mithilfe der Hardware-Flusskontrolle wird der Inhalt werden in UART2 abgeladen, was 300 Baud entspricht.
Es funktioniert gut, solange es ein kontinuierlicher Stream ist, aber wenn ich den primären Sender stoppe, brauche ich die nachgeschalteten UARTs, um die Übertragung zu stoppen. Ich habe versucht, die RXNE-, TXE- und TC-Flags zu verwenden, aber sie funktionieren nicht wie erwartet. Wenn ich die Übertragung vom Primärstrom stoppe, geht UART2 (300 Baud) in "TIME OUT" und druckt einfach kontinuierlich, was noch in seinem Puffer ist.
while (1) {
if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_RXNE) == 0) { // 0 = Empty
HAL_GPIO_WritePin(BluePill_LED_GPIO_Port, BluePill_LED_Pin,GPIO_PIN_SET);
HAL_Delay(100);
}
HAL_UART_Receive(&huart3, (uint8_t*) uart1_buf, uart_buf_len, 500);
strcpy(uart2_buf, uart1_buf); // copy the contents of UART1 buffer to UART2 buffer
if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) == RESET) {
HAL_GPIO_WritePin(BluePill_LED_GPIO_Port, BluePill_LED_Pin,GPIO_PIN_SET);
HAL_Delay(200);
}
HAL_UART_Transmit(&huart2, (uint8_t*) uart2_buf, uart_buf_len, 1000);
if (!(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_TXE))) {
HAL_GPIO_WritePin(BluePill_LED_GPIO_Port, BluePill_LED_Pin,GPIO_PIN_RESET);
HAL_Delay(200);
}
}
Dieser Code wurde zu Testzwecken geändert. Wie Sie sehen, dachte ich, ich könnte die LED aufleuchten lassen, wenn die Flaggenbedingungen erfüllt sind, aber die LED leuchtet nicht auf. Eine andere seltsame Sache ist, dass, obwohl die LED nicht aufleuchtet, das HAL_Delay mit Sicherheit ausgeführt wird.
Vielleicht könnte jemand etwas Licht ins Dunkel bringen, was ich falsch mache. Vielen Dank
Antworten
Aufgrund des Geschwindigkeitsunterschieds sollte wahrscheinlich ein Puffer verwendet werden (wie in den Kommentaren erwähnt). Der folgende Code setzt also voraus, dass Code für einen solchen Puffer (wahrscheinlich Ringpuffer) mit dieser API vorhanden ist:
bool buffer_is_empty(); // returns true if buffer is empty
bool buffer_is_full(); // returns true if buffer is full
uint8_t buffer_remove_byte(); // removes and returns the oldest byte added to the buffer
void buffer_add_byte(uint8_t b); // adds a byte to the buffer
Die Hauptschleife arbeitet Byte für Byte:
- Wenn ein Byte in UART3 verfügbar ist, empfangen Sie es und fügen Sie es dem Puffer hinzu
- Wenn UART2 bereit ist und der Puffer nicht leer ist, entfernen Sie ein Byte und senden Sie es
Es könnte so aussehen:
uint8_t ch;
while (1) {
if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_RXNE) != 0) { // not empty
HAL_UART_Receive(&huart3, &ch, 1, 1);
if (!buffer_is_full()) {
buffer_add_byte(ch);
} else {
// buffer overflow - discard byte
}
}
if (!buffer_is_empty() && __HAL_UART_GET_FLAG(&huart2, UART_FLAG_TXE) != 0) {
ch = buffer_remove_byte();
HAL_UART_Transmit(&huart2, &ch, 1, 1);
}
}