有没有一种简单的方法可以通过软件“桥接”2 条 U(S)ART 线路(STM32F107 上的 USART1 和 UART5)?
我需要将 USART1 传入的数据转发到 UART5 并反向。
目前的MCU是STM32F107VCT7
我想这样做的主要原因是通过连接到我的 MCU 的 UART 更新设备。MCU 连接到 PC。
PC --- STM32 --- 其他设备
有没有一种简单的方法可以通过软件“桥接”2 条 U(S)ART 线路(STM32F107 上的 USART1 和 UART5)?
我需要将 USART1 传入的数据转发到 UART5 并反向。
目前的MCU是STM32F107VCT7
我想这样做的主要原因是通过连接到我的 MCU 的 UART 更新设备。MCU 连接到 PC。
PC --- STM32 --- 其他设备
简单地将字节从一个 UART 复制到另一个是行不通的。
如果发送端(PC 串行适配器)仅比 MCU 快 0.1%,它将在第 1000 个字节后开始丢弃字节。STM32F107 内部时钟的频率精度在数据表中给出的室温下为 -1.1% 至 +1.8%,因此它可能会更早发生,另外两个参与者也可能不是完全准确。
在固件更新过程中将字节丢弃到原本无法访问的部分不会很有趣。
您需要双向循环(FIFO)缓冲区
缓冲区的大小由数据包的大小和参与设备中的频率不准确的总和决定。例如,如果一个块中有 64 kB 数据,并且两个设备的频率精度都为 +/- 2%,那么您至少需要 65536*0.04 ~ 2622 字节的缓冲区。
在无限循环中执行此操作,
RXNE
_USART1->SR
USART1->DR
并将其放在缓冲区的头部(如果缓冲区已满,请大声抱怨)TXE
UART5->SR`UART5->DR
你能把数据写入适当的usart寄存器吗?也就是说,如果 usart1 线上有一个字节通过并且存储在 usart1 数据寄存器中,则读取它并将其写入 usart5 数据寄存器并设置该位以让芯片知道它已准备好传输字节。对 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 的速度相同的简单双向通信方法。
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];
}
}