1.DMA介紹
DMA,全稱Direct Memory Access,即直接存盤器訪問,
DMA傳輸將資料從一個地址空間復制到另一個地址空間,提供在外設和存盤器之間或者存盤器和存盤器之間的高速資料傳輸,
作用就是解決大量資料轉移過度消耗CPU資源的問題,有了DMA使CPU更專注于更加實用的操作–計算、控制等,
DMA用來提供在外設和存盤器之間或者存盤器和存盤器之間的高速資料傳輸,無須CPU的干預,通過DMA資料可以快速地移動,這就節省了CPU的資源來做其他操作,
2.具體配置
(1)串口2配置


step1 點擊USATR2
step2 設定MODE為異步通信(Asynchronous)
step3 基礎引數:波特率為115200 Bits/s,傳輸資料長度為8 Bit,奇偶檢驗無,停止位1 接收和發送都使能
step4 GPIO引腳自動設定 USART1_RX/USART_TX
step5 NVIC Settings 一欄使能接收中斷
(2) DMA設定
點擊Add進行添加


step1 點擊DMASettings 點擊 Add 添加通道
step2 選擇USART_RX USART_TX 傳輸速率設定為中速
step3 DMA傳輸模式為正常模式
step4 DMA記憶體地址自增,每次增加一個Byte(位元組)
3.代碼撰寫
(1) usart.c 部分修改
volatile uint8_t rx_len = 0; //接收一幀資料的長度
volatile uint8_t recv_end_flag = 0; //一幀資料接收完成標志
uint8_t rx_buffer[100]={0}; //接收資料快取陣列
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
//添加代碼
__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE); //使能IDLE中斷
HAL_UART_Receive_DMA(&huart2,rx_buffer,BUFFER_SIZE);
}
(2) usart.h 部分修改
#define BUFFER_SIZE 100
extern volatile uint8_t rx_len ; //接收一幀資料的長度
extern volatile uint8_t recv_end_flag; //一幀資料接收完成標志
extern uint8_t rx_buffer[100]; //接收資料快取陣列
(3)main.c修改
/*
*********************************************************************************************************
* 函 數 名: DMA_Usart_Send
* 功能說明: 串口發送功能函式
* 形 參: buf,len
* 返 回 值: 無
*********************************************************************************************************
*/
void DMA_Usart_Send(uint8_t *buf,uint8_t len)//串口發送封裝
{
if(HAL_UART_Transmit_DMA(&huart2, buf,len)!= HAL_OK) //判斷是否發送正常,如果出現例外則進入例外中斷函式
{
Error_Handler();
}
}
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/*
HAL_GPIO_TogglePin(GPIOI,GPIO_PIN_6);
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_5);
HAL_Delay(500);
*/
if(recv_end_flag == 1) //接收完成標志
{
DMA_Usart_Send(rx_buffer, rx_len);
rx_len = 0;//清除計數
recv_end_flag = 0;//清除接收結束標志位
memset(rx_buffer,0,rx_len);
}
HAL_UART_Receive_DMA(&huart2,rx_buffer,BUFFER_SIZE);//重新打開DMA接收
}
(3) stm32f4xx_it.c修改
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
uint32_t tmp_flag = 0;
uint32_t temp;
tmp_flag =__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE); //獲取IDLE標志位
if((tmp_flag != RESET))//idle標志被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart2);//清除標志位
HAL_UART_DMAStop(&huart2); //
temp = __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);// 獲取DMA中未傳輸的資料個數
rx_len = BUFFER_SIZE - temp; //總計數減去未傳輸的資料個數,得到已經接收的資料個數
recv_end_flag = 1; // 接受完成標志位置1
}
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
4.測驗結果
發送和接收正常

5.原始碼和工程下載鏈接
https://download.csdn.net/download/qyx635804080/69486446
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/392231.html
標籤:其他
上一篇:ASP.NETWebforms:運行.bat檔案時隱藏控制臺視窗
下一篇:STM32F103ZET6串口使用USAR_TFLAG_IDLE空閑中斷實作UART_DMA接收和發送不定長資料
