STM32 UART flags dengan pooling methed

Sep 28 2020

Saya mencoba membangun baud rate changer sederhana dengan pil Biru stm32f103 menggunakan API HAL.

Yang ingin saya capai: Satu terminal tua yang terkunci pada 9600 baud. Satu printer termal lama yang memiliki maks 300 baud.

Proyek ini terdiri dari 2 "Pil Biru", satu yang hanya menempatkan aliran karakter pada 9600. Pil Biru lainnya mengambil aliran pada 9600 dan membuang setiap 4 byte ke dalam register untuk UART 3. Menggunakan kontrol aliran perangkat keras, isinya dibuang ke UART2 yaitu 300 baud.

Ini bekerja dengan baik selama alirannya terus menerus tetapi ketika saya menghentikan pemancar utama saya memerlukan UART hilir untuk menghentikan transmisi. Saya sudah mencoba menggunakan flag RXNE, TXE dan TC tetapi tidak berfungsi seperti yang diharapkan. Ketika saya menghentikan transmisi dari aliran utama, UART2 (300 baud), masuk ke "TIME OUT" dan terus mencetak apa pun yang tersisa di buffernya.

    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);
    }
}

Kode ini dimodifikasi untuk tujuan pengujian. Seperti yang Anda lihat, saya berpikir saya bisa menyalakan LED ketika kondisi bendera terpenuhi tetapi LED tidak menyala. Satu hal aneh lainnya adalah meskipun LED tidak menyala, HAL_Delay pasti sedang dijalankan.

Mungkin seseorang bisa menjelaskan kesalahan yang saya lakukan. Terima kasih

Jawaban

1 Codo Sep 29 2020 at 08:14

Karena perbedaan kecepatan, buffer mungkin harus digunakan (seperti yang disebutkan di komentar). Jadi kode di bawah ini mengasumsikan bahwa kode untuk buffer seperti itu (mungkin buffer cincin) ada dengan API ini:

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

Loop utama bekerja byte demi byte:

  • Jika byte tersedia di UART3, terima dan tambahkan ke buffer
  • Jika UART2 sudah siap dan buffer tidak kosong, hapus satu byte dan kirimkan

Ini bisa terlihat seperti ini:

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);            
    }
}