我正在一个项目中工作,我需要在uart之间架起一座桥梁。我使用的是STM32F072CB。基本上,我接收到的所有到uart1-rx的数据都必须通过uart2-tx发送。同样,我在uart2-rx中接收到的数据也必须通过uaart1-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被停用时,最好在将相应的内存值复制到另一个位置后启用它。