簡體   English   中英

UART 到 UART 橋 STM32

[英]UART to UART Bridge STM32

有沒有一種簡單的方法可以通過軟件“橋接”2 個 U(S)ART 線(STM32F107 上的 USART1 和 UART5)?

我需要將在 USART1 傳入的數據轉發到 UART5 並反向。

目前的 MCU 是 STM32F107VCT7

我想要這樣做的主要原因是通過 UART 更新連接到我的 MCU 的設備。 MCU 連接到 PC。

PC --- STM32 --- 其他設備

您能將數據寫到適當的usart寄存器中嗎? 也就是說,如果在usart1線上有一個字節通過並將其存儲在usart1數據寄存器中,請對其進行讀取並將其寫入usart5數據寄存器,然后將該位置1以使芯片知道它已准備好傳輸該字節。 對usart5到usart1橋執行相同的操作。

如果您擔心讀/寫多個字節,請考慮添加發送和接收緩沖區來處理此問題。

如果我們要使用一種輪詢方法,則代碼將類似於(注意:我主要處理AVR,因此我可能不使用寄存器名,但是該方法應遵循以下原則):



// Check to see if data has been written to usart1 and transfer it usart5.
if(USART1_CR1&(1 << USART1_SR_RXNE))
{
    // May want to avoid race conditions, so disable interrupts.
    // Write the data in usart1 to usart5
    USART5_DR = USART1_DR;

    // Set the data ready bit on the usart5 control register.
    USART5_CR1 |= (1 << USART_SR_RXNE);
    // Enable interrupts.
}

我將本教程用於STM32語言。 禁用中斷不是重點。 您可能還想寫入緩沖區。

簡單地將字節從一個UART復制到另一個UART是行不通的。

如果發送方(PC串行適配器)僅比MCU快0.1%,它將在第1000個字節之后開始丟棄字節。 數據表中STM32F107內部時鍾的頻率精度在室溫下為-1.1%至+ 1.8%,因此它可能更早發生,而其他兩個參與者也可能不是十分准確。

在固件更新過程中將字節丟棄到其他無法訪問的部分將不會很有趣。

兩種方式都需要循環(FIFO)緩沖區

緩沖區的大小由數據包的大小以及參與設備中的頻率誤差之和決定。 例如,如果一個塊中有64 kB數據,並且兩個設備的頻率精度均為+/- 2%,則您至少需要65536 * 0.04〜2622字節的緩沖區。

無休止地這樣做,

  • USART1->SR檢查RXNE
  • 如果已設置,請從USART1->DR讀取數據並將其放在緩沖區的開頭(如果緩沖區已滿,請大聲抱怨)
  • 在UART5-> SR中檢查TXE
  • 如果已設置,並且緩沖區不為空,則將緩沖區尾部的字節寫入UART5->DR
  • 在另一個方向上做同樣的事情

假設兩個UART的速度相同,則簡單的雙向通信方法。

volatile uint8_t data[2];

void USART1_IRQHandler(void)
{
    if(USART1 -> SR & USART_SR_RXNE)
    {
        data[0] = USART1 -> DR;
        USART5 -> CR1 |= USART_CR1_TXEIE;
    }

    if( (USART1 -> CR1 & USART_CR_TXEIE) && (USART1 -> SR & USART_SR_TXE))
    {
        USART1 -> CR1 &= ~USART_CR1_TXEIE;
        USART1 -> DR = data[1];
    }
}

void USART5_IRQHandler(void)
{
    if(USART5 -> SR & USART_SR_RXNE)
    {
        data[1] = USART5 -> DR;
        USART1 -> CR1 |= USART_CR1_TXEIE;
    }

    if( (USART5 -> CR1 & USART_CR_TXEIE) && (USART5 -> SR & USART_SR_TXE))
    {
        USART5 -> CR1 &= ~USART_CR1_TXEIE;
        USART5 -> DR = data[0];
    }
}

我從上面嘗試了一下答案,並做了一些小改動:

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  if(USART1 -> SR & USART_SR_RXNE)
     {
         data[0] = USART1 -> DR;
         UART5 -> CR1 |= USART_CR1_TXEIE;
     }

     if( (USART1 -> CR1 & USART_CR1_TXEIE) && (USART1 -> SR & USART_SR_TXE))
     {
         USART1 -> CR1 &= ~USART_CR1_TXEIE;
         USART1 -> DR = data[1];
     }
  /* USER CODE END USART1_IRQn 1 */
}




/**
  * @brief This function handles UART5 global interrupt.
  */
void UART5_IRQHandler(void)
{
  /* USER CODE BEGIN UART5_IRQn 0 */

  /* USER CODE END UART5_IRQn 0 */
  HAL_UART_IRQHandler(&huart5);
  /* USER CODE BEGIN UART5_IRQn 1 */

  if(UART5 -> SR & USART_SR_RXNE)
     {
         data[1] = UART5 -> DR;
         USART1 -> CR1 |= USART_CR1_TXEIE;
     }

     if( (UART5 -> CR1 & USART_CR1_TXEIE) && (UART5 -> SR & USART_SR_TXE))
     {
         UART5 -> CR1 &= ~USART_CR1_TXEIE;
         UART5 -> DR = data[0];
     }

  /* USER CODE END UART5_IRQn 1 */
}

但是兩條UART線之間沒有通信。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM