本文使用STM32CubeMX,STM32F103RCT6
1,在Pinout中激活USART1和USART2
2,在Configration 中点击Connectivity-> USART1 设置参数
DMA设置如下
3,在Configration 中点击Connectivity-> USART2 设置参数
DMA设置如下
两个USART波特率并不一致
4,生成初始化代码,
5,在usart.h中修改如下内容
/* USER CODE BEGIN Private defines */
#define RECEIVELEN 128
#define USART_DMA_SENDING 1//发送未完成
#define USART_DMA_SENDOVER 0//发送完成
typedef struct
{
uint8_t receive_flag:1;//空闲接收标记
uint8_t dmaSend_flag:1;//发送完成标记
uint16_t rx_len;//接收长度
uint8_t usartDMA_rxBuf[RECEIVELEN];//DMA接收缓存
}USART_RECEIVETYPE;
extern USART_RECEIVETYPE UsartType1,UsartType2;
void UsartReceive_IDLE(UART_HandleTypeDef *huart);
void Usart1SendData_DMA(uint8_t *pdata, uint16_t Length);
void Usart2SendData_DMA(uint8_t *pdata, uint16_t Length);
/* USER CODE END Private defines */
6,在usart.c中修改如下内容
/* USER CODE BEGIN 0 */
USART_RECEIVETYPE UsartType1,UsartType2;
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
//DMA发送函数
void Usart1SendData_DMA(uint8_t *pdata, uint16_t Length)
{
while(UsartType1.dmaSend_flag == USART_DMA_SENDING);
UsartType1.dmaSend_flag = USART_DMA_SENDING;
HAL_UART_Transmit_DMA(&huart1, pdata, Length);
}
void Usart2SendData_DMA(uint8_t *pdata, uint16_t Length)
{
while(UsartType2.dmaSend_flag == USART_DMA_SENDING);
UsartType2.dmaSend_flag = USART_DMA_SENDING;
HAL_UART_Transmit_DMA(&huart2, pdata, Length);
}
//DMA发送完成中断回调函数
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
__HAL_DMA_DISABLE(huart->hdmatx);
if( huart->Instance == huart1.Instance)
UsartType1.dmaSend_flag = USART_DMA_SENDOVER;
if( huart->Instance == huart2.Instance)
UsartType2.dmaSend_flag = USART_DMA_SENDOVER;
}
//串口接收空闲中断
void UsartReceive_IDLE(UART_HandleTypeDef *huart)
{
uint32_t temp;
if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(huart);
HAL_UART_DMAStop(huart);
if(huart->Instance == huart1.Instance)
{
temp = huart1.hdmarx->Instance->CNDTR;
UsartType1.rx_len = RECEIVELEN - temp;
UsartType1.receive_flag=1;
HAL_UART_Receive_DMA(&huart1,UsartType1.usartDMA_rxBuf,RECEIVELEN);
}
if(huart->Instance == huart2.Instance)
{
temp = huart2.hdmarx->Instance->CNDTR;
UsartType2.rx_len = RECEIVELEN - temp;
UsartType2.receive_flag=1;
HAL_UART_Receive_DMA(&huart2,UsartType2.usartDMA_rxBuf,RECEIVELEN);
}
}
}
/* USER CODE END 1 */
7,在stm32f1xx_it.c中修改如下内容
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
UsartReceive_IDLE(&huart1);
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/**
* @brief This function handles USART2 global interrupt.
*/
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
UsartReceive_IDLE(&huart2);
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
8,在main.c中修改如下内容
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart1, UsartType1.usartDMA_rxBuf, RECEIVELEN);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart2, UsartType2.usartDMA_rxBuf, RECEIVELEN);
__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
/* USER CODE END 2 */
9,接收判断(空闲时才触发)
if(UsartType1.receive_flag) {
UsartType1.receive_flag = 0;
}
可通过 UsartType1.rx_len 获取数据长度
10,发送数据
Usart1SendData_DMA(&data,1);
Usart2SendData_DMA(&data,1);