STM32单片机串口中断+DMA使用(含CUBE配置)
最近又要重新用32做点东西,发现一两年没怎么碰的结果就是,曾经熟得不行的东西都变得极度陌生,这种重新学习记忆的过程过于痛苦,果然还是要留下一些记录给之后失忆的自己的。
1.STM32CUBE配置
1.1 pinout设置
找到想要用的串口,配置模式,正常情况是Asyn(异步)和Disable。
关于mode的几个选项:
- Asyn 异步
- Syn同步
- Single Wire单工
- 后面几个没有太多的了解惹
1.2 configuration设置
Parameter Settings可以设置:波特率/字长/奇偶校验/停止位/收发模式
DMA Settings中添加接收DMA的流
NVIC Settings中将global interrupt一项使能
1.3 生成项目
在CUBE中有关于串口的配置就此完成啦,之后生成项目就可以了。
2.中断逻辑和DMA
建立一个bsp_usart.c和bsp_usart.h文件,涉及串口中断和DMA接收的东西放这里。
2.1 几个函数
- DMA接收函数
1 static int UART_Receive_DMA_No_IT(UART_HandleTypeDef* huart, uint8_t* pData, uint32_t Size) 2 { 3 uint32_t tmp1 = 0; 4 tmp1 = huart->State; 5 if((tmp1 == HAL_UART_STATE_READY) || (tmp1 == HAL_UART_STATE_BUSY_TX)) 6 { 7 if((pData == NULL ) || (Size == 0)) //Ö¸ÕëÖ¸µÄÇøÓò²»Îª¿Õ 8 { 9 return HAL_ERROR; 10 } 11 12 /* Process Locked */ 13 __HAL_LOCK(huart); 14 15 huart->pRxBuffPtr = pData; 16 huart->RxXferSize = Size; 17 18 huart->ErrorCode = HAL_UART_ERROR_NONE; 19 /* Check if a transmit process is ongoing or not */ 20 if(huart->State == HAL_UART_STATE_BUSY_TX) 21 { 22 huart->State = HAL_UART_STATE_BUSY_TX_RX; 23 } 24 else 25 { 26 huart->State = HAL_UART_STATE_BUSY_RX; 27 } 28 29 /* Enable the DMA Stream */ 30 HAL_DMA_Start(huart->hdmarx, (uint32_t)&huart->Instance->DR, (uint32_t)pData, Size); 31 32 /* Enable the DMA transfer for the receiver request by setting the DMAR bit 33 in the UART CR3 register */ 34 huart->Instance->CR3 |= USART_CR3_DMAR; 35 36 /* Process Unlocked */ 37 __HAL_UNLOCK(huart); 38 39 return HAL_OK; 40 } 41 else 42 { 43 return HAL_BUSY; 44 } 45 }
- 串口复位重启DMA函数
void uart_reset_idle_rx_callback(UART_HandleTypeDef *huart) { if(__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)) { __HAL_UART_CLEAR_IDLEFLAG(huart); //clear idle it flag //ÖØÆôDMA uint32_t DMA_FLAGS = __HAL_DMA_GET_TC_FLAG_INDEX(huart->hdmarx); __HAL_DMA_DISABLE(huart->hdmarx); __HAL_DMA_CLEAR_FLAG(huart->hdmarx, DMA_FLAGS); //__HAL_DMA_SET_COUNTER(huart->hdmarx, MAX_DMA_COUNT); __HAL_DMA_ENABLE(huart->hdmarx); } }
2.2 串口初始化
在main函数初始化的时候调用哦
void huart_init(void) { __HAL_UART_CLEAR_IDLEFLAG(&huart1); __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); UART_Receive_DMA_No_IT(&huart1, MsgBuff, DMsgBuffSize); }
这个初始化函数其实可以修改修改传参复用的。
2.3 串口处理句柄
void MushroomUARTIRQHandler(UART_HandleTypeDef *huart) { if(huart == &huart1) { //这里放入希望在串口接收中断里处理的事情or函数 } }
3.将中断处理句柄放入中断文件中
打开stm32f1xx_it.c文件,找到选择的串口中断函数,比如void USART1_IRQHandler(void)。在里面放入写好的串口处理句柄。
然后就大功告成啦!