STM32 UART sinalizadores com pooling methed

Sep 28 2020

Estou tentando construir um trocador de taxa de transmissão simples com um comprimido azul stm32f103 usando a API HAL.

O que espero alcançar: um terminal antigo bloqueado a 9600 baud. Uma impressora térmica antiga com no máximo 300 baud.

O projeto consiste em 2 "pílulas azuis", uma que apenas coloca um fluxo de caracteres em 9600. A outra pílula azul leva o fluxo em 9600 e despeja a cada 4 bytes em um registro para UART 3. Usando o controle de fluxo de hardware, o conteúdo são despejados no UART2, que tem 300 baud.

Ele funciona bem desde que seja um fluxo contínuo, mas quando eu interrompo o transmissor primário, preciso que os UARTs downstream parem de transmitir. Tentei usar os sinalizadores RXNE, TXE e TC, mas eles não funcionam conforme o esperado. Quando eu paro a transmissão do stream primário, UART2 (300 baud), entra em "TIME OUT" e imprime continuamente o que resta em seu 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);
    }
}

Este código é modificado para fins de teste. Como você pode ver, eu estava pensando em acender o LED quando as condições de bandeira fossem atendidas, mas o LED não acende. Outra coisa estranha é que embora o LED não acenda, o HAL_Delay com certeza está sendo executado.

Talvez alguém pudesse lançar alguma luz sobre o que estou fazendo de errado. obrigado

Respostas

1 Codo Sep 29 2020 at 08:14

Devido à diferença de velocidade, um buffer provavelmente deve ser usado (conforme mencionado nos comentários). Portanto, o código a seguir assume que o código para esse buffer (provavelmente buffer de anel) existe com esta 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

O loop principal funciona byte a byte:

  • Se um byte estiver disponível no UART3, receba-o e adicione-o ao buffer
  • Se UART2 estiver pronto e o buffer não estiver vazio, remova um byte e transmita-o

Pode ser assim:

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