STM32串口桥
STM32 Uart Bridge
我在一个项目中工作,我需要在与 uart 之间架起一座桥梁。我使用的是 STM32F072CB 基本上,我接收到 uart1 rx 的所有数据都必须由 uart2 tx 发送。以同样的方式,我在 uart2 rx 中收到的内容必须通过 uart1 tx 发送。(两个 UART 具有相同的波特率)。我不知道我可以在 rx uarts 上接收多少数据。
这就是想法
Uart1 rx --------> Uart2 tx
Uart1 tx <-------- Uart2 rx
我将 DMA 与 HAL_UARTEx_ReceiveToIdle_DMA 结合使用以减少 cpu 处理。
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart2_rx;
#define RXBuffSize 10
uint8_t RxBuff1[RxBuffSize];
uint8_t RxBuff2[RxBuffSize];
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,RxBuff1,RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);
HAL_UARTEx_ReceiveToIdle_DMA(&huart2,RxBuff2,RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
while (1)
{}
}
下面是我的DMA中断回调函数
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == USART1)
{
HAL_UART_Transmit(&huart2,RxBuff1,RxBuffSize,1);
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,RxBuff1,RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);
}
else if (huart->Instance == USART2)
{
HAL_UART_Transmit(&huart1,RxBuff2,RxBuffSize,1);
HAL_UARTEx_ReceiveToIdle_DMA(&huart2,RxBuff2,RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
}
}
代码在输入到 rx 的数据为低电平时运行。如果我在另一个 uart 的 tx 中发送太多数据,我会得到第一个字节,但会丢失最后一个字节。我也尝试做 RXBuffSize = 1 ,也就是说接收一个字符并发送它但我得到相同的结果。
因为HAL_UART_Transmit以“轮询”方式运行,所以它会在该点停止,直到所有字符串都被传输。
因此,如果在HAL_UART_Transmit执行的过程中有另外的字符串进来,中断不执行,输入的字符串丢失。
激活cubemx中每个uart的TX DMA后,尝试应用如下所示的代码。
#include <string.h>
uint8_t TxBuff1[RxBuffSize];
uint8_t TxBuff2[RxBuffSize];
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
Size = Size > RxBuffSize ? RxBuffSize : Size;
if (huart->Instance == USART1)
{
memcpy(TxBuff2, RxBuff1, Size);
HAL_UART_Transmit_DMA(&huart2, TxBuff2, Size);
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, RxBuff1, RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
}
else if (huart->Instance == USART2)
{
memcpy(TxBuff1, RxBuff2, Size);
HAL_UART_Transmit_DMA(&huart1, TxBuff1, Size);
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, RxBuff2, RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);
}
}
直接传输RxBuff是危险的。当发送时从UART接收到一个字符,TX DMA可能会发送一个不正确的值,因为RX DMA改变了相应内存中的值。
因此,当RX DMA停用时,最好将相应的内存值复制到另一个位置后再启用。
我在一个项目中工作,我需要在与 uart 之间架起一座桥梁。我使用的是 STM32F072CB 基本上,我接收到 uart1 rx 的所有数据都必须由 uart2 tx 发送。以同样的方式,我在 uart2 rx 中收到的内容必须通过 uart1 tx 发送。(两个 UART 具有相同的波特率)。我不知道我可以在 rx uarts 上接收多少数据。
这就是想法
Uart1 rx --------> Uart2 tx
Uart1 tx <-------- Uart2 rx
我将 DMA 与 HAL_UARTEx_ReceiveToIdle_DMA 结合使用以减少 cpu 处理。
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart2_rx;
#define RXBuffSize 10
uint8_t RxBuff1[RxBuffSize];
uint8_t RxBuff2[RxBuffSize];
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,RxBuff1,RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);
HAL_UARTEx_ReceiveToIdle_DMA(&huart2,RxBuff2,RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
while (1)
{}
}
下面是我的DMA中断回调函数
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == USART1)
{
HAL_UART_Transmit(&huart2,RxBuff1,RxBuffSize,1);
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,RxBuff1,RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);
}
else if (huart->Instance == USART2)
{
HAL_UART_Transmit(&huart1,RxBuff2,RxBuffSize,1);
HAL_UARTEx_ReceiveToIdle_DMA(&huart2,RxBuff2,RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
}
}
代码在输入到 rx 的数据为低电平时运行。如果我在另一个 uart 的 tx 中发送太多数据,我会得到第一个字节,但会丢失最后一个字节。我也尝试做 RXBuffSize = 1 ,也就是说接收一个字符并发送它但我得到相同的结果。
因为HAL_UART_Transmit以“轮询”方式运行,所以它会在该点停止,直到所有字符串都被传输。
因此,如果在HAL_UART_Transmit执行的过程中有另外的字符串进来,中断不执行,输入的字符串丢失。
激活cubemx中每个uart的TX DMA后,尝试应用如下所示的代码。
#include <string.h>
uint8_t TxBuff1[RxBuffSize];
uint8_t TxBuff2[RxBuffSize];
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
Size = Size > RxBuffSize ? RxBuffSize : Size;
if (huart->Instance == USART1)
{
memcpy(TxBuff2, RxBuff1, Size);
HAL_UART_Transmit_DMA(&huart2, TxBuff2, Size);
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, RxBuff1, RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
}
else if (huart->Instance == USART2)
{
memcpy(TxBuff1, RxBuff2, Size);
HAL_UART_Transmit_DMA(&huart1, TxBuff1, Size);
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, RxBuff2, RxBuffSize);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);
}
}
直接传输RxBuff是危险的。当发送时从UART接收到一个字符,TX DMA可能会发送一个不正确的值,因为RX DMA改变了相应内存中的值。
因此,当RX DMA停用时,最好将相应的内存值复制到另一个位置后再启用。