串口接收缓冲区定义
usart.h
#define BUFFER_SIZE 64
typedef struct
{
uint8_t buff[BUFFER_SIZE];
uint32_t length;
uint32_t rx_flag;
}uart_rx_msg;
/* 串口接收消息缓冲 */
extern uart_rx_msg rs422_rx_msg;
extern uart_rx_msg rs485_rx_msg;
extern uart_rx_msg rs232_rx_msg;
usart.c
/* 串口接收消息缓冲 */
uart_rx_msg rs422_rx_msg;
uart_rx_msg rs485_rx_msg;
uart_rx_msg rs232_rx_msg;
//在每个串口初始化函数里初始化缓冲BUF
/* 初始化缓冲区 */
memset(rs485_rx_msg.buff,0,BUFFER_SIZE);
rs485_rx_msg.rx_flag = 0;
rs485_rx_msg.length = 0;
memset(rs232_rx_msg.buff,0,BUFFER_SIZE);
rs232_rx_msg.length = 0;
rs232_rx_msg.rx_flag = 0;
memset(rs422_rx_msg.buff,0,BUFFER_SIZE);
rs422_rx_msg.length = 0;
rs422_rx_msg.rx_flag = 0;
使能IDLE中断和DMA接收
//使能IDLE中断
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
//DMA接收函数
HAL_UART_Receive_DMA(&huart1,rs232_rx_msg.buff,BUFFER_SIZE);
空闲中断回调函数
HAL库没有实现空闲中断回调,需自己实现,然后放到USART_IRQHandler中断函数中
void uart_dma_isr_process(UART_HandleTypeDef *huart)
{
if(huart->Instance == huart1.Instance)
{
uint32_t temp;
//获取IDLE标志位
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET)//idle标志被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
//停止DMA搬运
HAL_UART_DMAStop(&huart1);
// 获取DMA中未传输的数据个数
temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
//总计数减去未传输的数据个数,得到已经接收的数据个数
rs232_rx_msg.length = BUFFER_SIZE - temp;
// 接受完成标志位置1
rs232_rx_msg.rx_flag = 1;
}
}
if(huart->Instance == huart4.Instance)
{
uint32_t temp;
//获取IDLE标志位
if(__HAL_UART_GET_FLAG(&huart4,UART_FLAG_IDLE) != RESET)//idle标志被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart4);//清除标志位
//停止DMA搬运
HAL_UART_DMAStop(&huart4);
// 获取DMA中未传输的数据个数
temp = __HAL_DMA_GET_COUNTER(&hdma_uart4_rx);
//总计数减去未传输的数据个数,得到已经接收的数据个数
rs485_rx_msg.length = BUFFER_SIZE - temp;
// 接受完成标志位置1
rs485_rx_msg.rx_flag = 1;
}
}
if(huart->Instance == huart6.Instance)
{
uint32_t temp;
//获取IDLE标志位
if(__HAL_UART_GET_FLAG(&huart6,UART_FLAG_IDLE) != RESET)//idle标志被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart6);//清除标志位
//停止DMA搬运
HAL_UART_DMAStop(&huart6);
// 获取DMA中未传输的数据个数
temp = __HAL_DMA_GET_COUNTER(&hdma_usart6_rx);
//总计数减去未传输的数据个数,得到已经接收的数据个数
rs422_rx_msg.length = BUFFER_SIZE - temp;
// 接受完成标志位置1
rs422_rx_msg.rx_flag = 1;
}
}
}
DMA收,根据标志位进行数据回显
if(rs422_rx_msg.rx_flag == 1) //接收完成标志
{
// can_send_msg(0x01,rs422_rx_msg.buff,rs422_rx_msg.length);
// can_send_msg(0x02,rs422_rx_msg.buff,rs422_rx_msg.length);
//将接收到的数据回发
HAL_UART_Transmit_DMA(&huart6,rs422_rx_msg.buff, rs422_rx_msg.length);
rs422_rx_msg.length = 0;//清除计数
rs422_rx_msg.rx_flag = 0;//清除接收结束标志位
memset(rs422_rx_msg.buff,0,rs422_rx_msg.length);
}
HAL_UART_Receive_DMA(&huart6,rs422_rx_msg.buff,BUFFER_SIZE);//重新打开DMA接收
USART_IRQHandler调用回调函数
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
uart_dma_isr_process(&huart1);
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}