Flag UART STM32 con metodo di pooling
Sto cercando di costruire un semplice cambio di velocità di trasmissione con una pillola blu stm32f103 utilizzando l'API HAL.
Quello che spero di ottenere: un vecchio terminale bloccato a 9600 baud. Una vecchia stampante termica che ha un massimo di 300 baud.
Il progetto consiste in 2 "pillole blu", una che inserisce un flusso di caratteri a 9600. L'altra pillola blu prende il flusso a 9600 e scarica ogni 4 byte in un registro per UART 3. Utilizzando il controllo del flusso hardware, il contenuto vengono scaricati in UART2 che è 300 baud.
Funziona bene fintanto che è un flusso continuo, ma quando fermo il trasmettitore principale ho bisogno degli UART a valle per interrompere la trasmissione. Ho provato a utilizzare i flag RXNE, TXE e TC ma non funzionano come previsto. Quando interrompo la trasmissione dal flusso principale, UART2 (300 baud) va in "TIME OUT" e stampa continuamente tutto ciò che è rimasto nel suo buffer.
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);
}
}
Questo codice viene modificato a scopo di test. Come puoi vedere stavo pensando che avrei potuto accendere il LED quando le condizioni della bandiera erano soddisfatte ma il LED non si accende. Un'altra cosa strana è che anche se il LED non si accende, HAL_Delay è sicuramente in esecuzione.
Forse qualcuno potrebbe far luce su quello che sto facendo di sbagliato. Grazie
Risposte
A causa della differenza di velocità, probabilmente dovrebbe essere usato un buffer (come menzionato nei commenti). Quindi il codice seguente presuppone che il codice per tale buffer (probabilmente ring buffer) esista con questa API:
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
Il ciclo principale funziona byte per byte:
- Se un byte è disponibile su UART3, riceverlo e aggiungerlo al buffer
- Se UART2 è pronto e il buffer non è vuoto, rimuovere un byte e trasmetterlo
Potrebbe essere così:
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);
}
}