繁体   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