1. 准備工作
硬件准備
開發板
首先需要准備一個小熊派IoT開發板,並通過USB線與電腦連接。
2.生成MDK工程
選擇芯片型號
打開STM32CubeMX,打開MCU選擇器:
搜索並選中芯片STM32L431RCT6
:
配置時鍾源
- 如果選擇使用外部高速時鍾(HSE),則需要在System Core中配置RCC;
- 如果使用默認內部時鍾(HSI),這一步可以略過;
這里我都使用外部時鍾:
配置串口
小熊派開發板板載ST-Link並且虛擬了一個串口,原理圖如下:
這里我將開關撥到AT-MCU
模式,使PC的串口與USART1之間連接。
接下來開始配置USART1
:
USART DMA配置
知識小卡片 —— DMA
DMA 全稱 Direct Memory Access
(直接存儲器訪問), 是STM32的一個外設,它的特點在於:
在不占用CPU的情況下將數據從存儲器直接搬運到外設,或者從外設直接搬運到存儲器,當然也可以從存儲器直接搬運到存儲器。
比如在需要串口發送大量數據的時候,CPU只需要發起DMA傳輸請求,然后就可以去做別的事情了,DMA會將數據傳輸到串口發送,DMA傳輸完之后會觸發中斷,CPU如果有需要,可以對該中斷進行處理,這樣一來CPU的效率是不是大大提高了?
在STM32L431RCT6中有 2 個 DMA 外設:DMA1 和 DMA2,每個DMA外設有 7 個通道,每個通道都是獨立的,配置DMA的時候有幾個關鍵點:
- 數據從哪里來?
- 數據到哪里去?
- 有多少數據?
知識小卡片結束啦~對STM32的DMA外設有沒有了解呢?
接下來我們配置DMA,將存儲器(SRAM)中的數據直接搬運到串口外設去發送:
配置時鍾樹
STM32L4的最高主頻到80M,所以配置PLL,最后使HCLK = 80Mhz
即可:
生成工程設置
代碼生成設置
最后設置生成獨立的初始化文件:
生成代碼
點擊GENERATE CODE
即可生成MDK-V5工程:
3. 在MDK中編寫、編譯、下載用戶代碼
定義發送數據區域
1 /* Private user code ---------------------------------------------------------*/ 2 /* USER CODE BEGIN 0 */ 3 uint8_t dat[] = "Hello, I am Mculover666.\n"; 4 /* USER CODE END 0 */
在main函數中發起DMA傳輸

1 int main(void) 2 { 3 HAL_Init(); 4 5 SystemClock_Config(); 6 7 MX_GPIO_Init(); 8 MX_USART1_UART_Init(); 9 10 /* USER CODE BEGIN 2 */ 11 HAL_UART_Transmit_DMA(&huart1, (uint8_t*)dat, sizeof(dat)); 12 /* USER CODE END 2 */ 13 14 while (1) 15 { 16 } 17 }
實驗現象
編譯下載運行后,實驗現象如下:
4. 使用DMA接收串口數據
說明
- 使用HAL庫的時候不能同時使用DMA發送和接收數據,會出錯。
- 所有的步驟和發送時一樣,這里我只給出需要修改的部分。
修改串口DMA配置
添加串口接收緩沖區
1 /* Private user code ---------------------------------------------------------*/ 2 /* USER CODE BEGIN 0 */ 3 uint8_t dat[] = "Hello, I am Mculover666.\n"; 4 uint8_t recv_buf[13] = {0}; //串口接收緩沖區 5 /* USER CODE END 0 */
修改main函數

1 int main(void) 2 { 3 HAL_Init(); 4 5 SystemClock_Config(); 6 7 MX_GPIO_Init(); 8 MX_DMA_Init(); 9 MX_USART1_UART_Init(); 10 11 /* USER CODE BEGIN 2 */ 12 HAL_UART_Transmit(&huart1, (uint8_t*)dat, sizeof(dat), 0xFFFF); 13 HAL_UART_Receive_DMA(&huart1, recv_buf, 13); //使能DMA接收 14 /* USER CODE END 2 */ 15 16 while (1) 17 { 18 } 19 }
添加串口接收中斷回調函數
1 /* USER CODE BEGIN 4 */ 2 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 3 { 4 //將接收到的數據再發送 5 HAL_UART_Transmit(&huart1,recv_buf,13, 0xFFFF); 6 } 7 /* USER CODE END 4 */
編譯代碼
點擊如圖所示的按鈕編譯工程
編譯成功
設置下載器
點擊如圖所示按鈕打開設置頁面
進行下載設置,選擇“ST-Link Debugger”,並點擊“Settings”。
在“Flash Download”菜單下勾選“Reset and Run”選項,已達到燒錄程序后單片機自動復位並運行程序的目的。
下載運行
點擊"LOAD"按鈕即可燒錄代碼到單片機中。
燒錄成功
實驗現象
至此,我們已經學會了如何配置USART使用DMA模式發送數據和接收數據,下一節將討論實現printf()函數的多種方法。