[英]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
讀取數據並將其放在緩沖區的開頭(如果緩沖區已滿,請大聲抱怨) 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.