首先将引脚配置为串口功能:
接着配置串口的参数:
点击ADD将UART5的接收设为DMA接收方式
开启串口和DMA中断:
使用DMA接收时在串口初始化后面加入如下函数:
HAL_UART_Receive_DMA(&huart5, UsartType.RX_pData, RX_LEN);
__HAL_UART_ENABLE_IT(&huart5, UART_IT_IDLE);
函数的功能为开启DMA接收和串口空闲中断。
自己写个串口空闲中断处理的函数并在生成代码里的中断函数调用。
#define RX_LEN 1024
typedef struct
{
uint8_t RX_flag:1; //IDLE receive flag
uint16_t RX_Size; //receive buf real length
uint8_t RX_pData[RX_LEN]; //DMA receive max buffer
}USART_RECEIVETYPE;
USART_RECEIVETYPE UsartType;
void UsartReceive_IDLE(UART_HandleTypeDef *huart)
{
uint32_t temp;
if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart5);
HAL_UART_DMAStop(&huart5);
temp = huart5.hdmarx->Instance->CNDTR;
UsartType.RX_Size = RX_LEN - temp;
UsartType.RX_flag=1;
HAL_UART_Receive_DMA(&huart5,UsartType.RX_pData,RX_LEN);
}
}
扫描二维码关注公众号,回复:
12910697 查看本文章
主要原理是开启DMA接收后,串口会不断的接收数据并送到一个固定地址,但不会触发串口中断。当一帧数据接收完(一帧数据的结束会有个短时间停顿通过这个判断DMA的接收结束)这时将空闲标志位置为1,并进入空闲中断执行取数据以及重启DMA的相应操作。
DMA的接收方式相对于串口中断接收方式比较高效,不占用CPU。用中断接收要频繁的进行出栈入栈的操作,而DMA只需等到一帧数据的结束时才进行出入栈的操作。