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)。在里面放入寫好的串口處理句柄。

 

然后就大功告成啦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM