有没有一种简单的方法可以通过软件“桥接”两条U(S)ART线(STM32F107上为USART1和UART5)?
我需要将USART1传入的数据转发到UART5并反转。
当前的MCU是STM32F107VCT7
我要这样做的主要原因是通过连接到我的MCU的UART更新设备。 MCU连接到PC。
PC --- STM32 ---其他设备
答案 0 :(得分:1)
您能将数据写到适当的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.
}
我将this tutorial用于STM32语言。禁用中断不是重点。您可能还想写入缓冲区。
答案 1 :(得分:0)
仅将字节从一个UART复制到另一个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->DR
答案 2 :(得分:0)
简单的双向通信方法,假设两个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];
}
}
答案 3 :(得分: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线之间没有通信。