CubeIDE中使用HAL_UART_DMA空闲中断实现printf收发

dma如下设置

 

定义串口收发需要用到的变量 in usart.c

/* USER CODE BEGIN 0 */
#include "stdio.h"    //用于printf
#include "dma.h"    //用于dma MemtoMem

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)    //用于printf
#define RX_BUF_SIZE 200    //接收buff大小

volatile uint8_t usart_dma_tx_over = 1;    //dma传输结束标志
uint8_t RxBuff[RX_BUF_SIZE];    //接收buff
uint8_t receive_num;    //接收字节数

/* USER CODE END 0 */

 

初始化串口

 1 void MX_USART1_UART_Init(void)
 2 {
 3 
 4   /* USER CODE BEGIN USART1_Init 0 */
 5 
 6   /* USER CODE END USART1_Init 0 */
 7 
 8   /* USER CODE BEGIN USART1_Init 1 */
 9 
10   /* USER CODE END USART1_Init 1 */
11   huart1.Instance = USART1;
12   huart1.Init.BaudRate = 115200;
13   huart1.Init.WordLength = UART_WORDLENGTH_8B;
14   huart1.Init.StopBits = UART_STOPBITS_1;
15   huart1.Init.Parity = UART_PARITY_NONE;
16   huart1.Init.Mode = UART_MODE_TX_RX;
17   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
18   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
19   if (HAL_UART_Init(&huart1) != HAL_OK)
20   {
21     Error_Handler();
22   }
23   /* USER CODE BEGIN USART1_Init 2 */
24   __HAL_UART_ENABLE_IT((UART_HandleTypeDef *)&huart1, UART_IT_IDLE);                    //打开空闲中断
25   HAL_UART_Receive_DMA((UART_HandleTypeDef *)&huart1, (uint8_t *)RxBuff, (uint16_t) RX_BUF_SIZE);   //开启DMA接收
26   /* USER CODE END USART1_Init 2 */
27 
28 }

 

发送功能实现

重写 __io_putchar

#ifdef __GNUC__
PUTCHAR_PROTOTYPE
{
  while(!usart_dma_tx_over);
  HAL_UART_Transmit_DMA(&huart1,(uint8_t *)&ch,1);
  usart_dma_tx_over = 0;
  return ch;
}
#endif

 

发送完成中断

1 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
2 {
3     if(huart->Instance==USART1)
4     {
5         usart_dma_tx_over = 1;  //发送完成后置1
6     }
7 }

 

接收功能实现,此处直接将接收到的数据转移到别处内存,之后进行回显。此处不可直接回显,会卡死在中断。

void USER_UARTx_IRQHandler(UART_HandleTypeDef *huart){
    if(USART1 == huart->Instance){
        if(__HAL_UART_GET_FLAG((UART_HandleTypeDef *)&huart1, UART_FLAG_IDLE) == SET)
          {
            __HAL_UART_CLEAR_IDLEFLAG((UART_HandleTypeDef *)&huart1);
            HAL_UART_DMAStop((UART_HandleTypeDef *)&huart1);
            receive_num = RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
            DMA_M2M_Start(RxBuff, DMABuff, receive_num);  //定义在dma.c中  用于实现uart回显
            receive_num = 0;
            HAL_UART_Receive_DMA((UART_HandleTypeDef *)&huart1, (uint8_t *)RxBuff, (uint16_t) RX_BUF_SIZE);
          }
    }
}

 

在系统中断中添加用户中断服务函数 in stm32f1xx_it.c  //总中断,不通平台会不一样

 1 void USART1_IRQHandler(void)
 2 {
 3   /* USER CODE BEGIN USART1_IRQn 0 */
 4   USER_UART_IRQHandler(&huart1);
 5   /* USER CODE END USART1_IRQn 0 */
 6   HAL_UART_IRQHandler(&huart1);
 7   /* USER CODE BEGIN USART1_IRQn 1 */
 8 
 9   /* USER CODE END USART1_IRQn 1 */
10 }

 

接收中转

dma 接收中转 in dma.c

定义中转buff

/* USER CODE BEGIN 1 */
uint8_t DMABuff[DMA_BUF_SIZE];
/* USER CODE END 1 */

注册dma回调

//传输成功回调,成功后回显到串口
static void TransferComplete(DMA_HandleTypeDef *DmaHandle){
    if(DMA1_Channel1 == DmaHandle->Instance)
    {
        printf("%s",DMABuff);
        memset(DMABuff,0,sizeof(DMABuff));
    }
}

static void TransferError(DMA_HandleTypeDef *DmaHandle){
    if(DMA1_Channel1 == DmaHandle->Instance)
    {
        printf("DMATransferErrorByDMA1_Channel1\r\n");
    }
}

//dma传输api
void DMA_M2M_Start(uint8_t *srcAddr,uint8_t *dstAddr,uint16_t bufsz){
    if(HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel1,(uint32_t)srcAddr,(uint32_t)dstAddr,bufsz)!=HAL_OK){
        Error_Handler();
    }
}

void RegisterCallbackFunctionForUart(void)    //注册dam回调
{
    HAL_DMA_RegisterCallback(&hdma_memtomem_dma1_channel1,HAL_DMA_XFER_CPLT_CB_ID,TransferComplete);
    HAL_DMA_RegisterCallback(&hdma_memtomem_dma1_channel1,HAL_DMA_XFER_ERROR_CB_ID,TransferError);
}

此处贴出完整代码:

main.c

  1 /* USER CODE BEGIN Header */
  2 /**
  3   ******************************************************************************
  4   * @file           : main.c
  5   * @brief          : Main program body
  6   ******************************************************************************
  7   * @attention
  8   *
  9   * Copyright (c) 2022 STMicroelectronics.
 10   * All rights reserved.
 11   *
 12   * This software is licensed under terms that can be found in the LICENSE file
 13   * in the root directory of this software component.
 14   * If no LICENSE file comes with this software, it is provided AS-IS.
 15   *
 16   ******************************************************************************
 17   */
 18 /* USER CODE END Header */
 19 /* Includes ------------------------------------------------------------------*/
 20 #include "main.h"
 21 #include "dma.h"
 22 #include "rtc.h"
 23 #include "spi.h"
 24 #include "tim.h"
 25 #include "usart.h"
 26 #include "gpio.h"
 27 
 28 /* Private includes ----------------------------------------------------------*/
 29 /* USER CODE BEGIN Includes */
 30 #include "stdio.h"
 31 /* USER CODE END Includes */
 32 
 33 /* Private typedef -----------------------------------------------------------*/
 34 /* USER CODE BEGIN PTD */
 35 
 36 /* USER CODE END PTD */
 37 
 38 /* Private define ------------------------------------------------------------*/
 39 /* USER CODE BEGIN PD */
 40 /* USER CODE END PD */
 41 
 42 /* Private macro -------------------------------------------------------------*/
 43 /* USER CODE BEGIN PM */
 44 
 45 /* USER CODE END PM */
 46 
 47 /* Private variables ---------------------------------------------------------*/
 48 
 49 /* USER CODE BEGIN PV */
 50 
 51 /* USER CODE END PV */
 52 
 53 /* Private function prototypes -----------------------------------------------*/
 54 void SystemClock_Config(void);
 55 /* USER CODE BEGIN PFP */
 56 
 57 /* USER CODE END PFP */
 58 
 59 /* Private user code ---------------------------------------------------------*/
 60 /* USER CODE BEGIN 0 */
 61 
 62 /* USER CODE END 0 */
 63 
 64 /**
 65   * @brief  The application entry point.
 66   * @retval int
 67   */
 68 int main(void)
 69 {
 70   /* USER CODE BEGIN 1 */
 71 
 72   /* USER CODE END 1 */
 73 
 74   /* MCU Configuration--------------------------------------------------------*/
 75 
 76   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 77   HAL_Init();
 78 
 79   /* USER CODE BEGIN Init */
 80 
 81   /* USER CODE END Init */
 82 
 83   /* Configure the system clock */
 84   SystemClock_Config();
 85 
 86   /* USER CODE BEGIN SysInit */
 87 
 88   /* USER CODE END SysInit */
 89 
 90   /* Initialize all configured peripherals */
 91   MX_DMA_Init();
 92   MX_USART1_UART_Init();
 93   /* USER CODE BEGIN 2 */
 94   RegisterCallbackFunctionForUart();
 95   /* USER CODE END 2 */
 96 
 97   /* Infinite loop */
 98   /* USER CODE BEGIN WHILE */
 99   while (1)
100   {
101     HAL_Delay(1000);
102     printf("hello\r\n");
103     /* USER CODE END WHILE */
104 
105     /* USER CODE BEGIN 3 */
106   }
107   /* USER CODE END 3 */
108 }
109 
110 /**
111   * @brief System Clock Configuration
112   * @retval None
113   */
114 void SystemClock_Config(void)
115 {
116   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
117   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
118   RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
119 
120   /** Initializes the RCC Oscillators according to the specified parameters
121   * in the RCC_OscInitTypeDef structure.
122   */
123   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE;
124   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
125   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
126   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
127   RCC_OscInitStruct.LSIState = RCC_LSI_ON;
128   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
129   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
130   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
131   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
132   {
133     Error_Handler();
134   }
135 
136   /** Initializes the CPU, AHB and APB buses clocks
137   */
138   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
139                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
140   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
141   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
142   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
143   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
144 
145   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
146   {
147     Error_Handler();
148   }
149   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
150   PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
151   if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
152   {
153     Error_Handler();
154   }
155 }
156 
157 /* USER CODE BEGIN 4 */
158 
159 /* USER CODE END 4 */
160 
161 /**
162   * @brief  This function is executed in case of error occurrence.
163   * @retval None
164   */
165 void Error_Handler(void)
166 {
167   /* USER CODE BEGIN Error_Handler_Debug */
168   /* User can add his own implementation to report the HAL error return state */
169   __disable_irq();
170   while (1)
171   {
172   }
173   /* USER CODE END Error_Handler_Debug */
174 }
175 
176 #ifdef  USE_FULL_ASSERT
177 /**
178   * @brief  Reports the name of the source file and the source line number
179   *         where the assert_param error has occurred.
180   * @param  file: pointer to the source file name
181   * @param  line: assert_param error line source number
182   * @retval None
183   */
184 void assert_failed(uint8_t *file, uint32_t line)
185 {
186   /* USER CODE BEGIN 6 */
187   /* User can add his own implementation to report the file name and line number,
188      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
189   /* USER CODE END 6 */
190 }
191 #endif /* USE_FULL_ASSERT */

 

usart.c

  1 /* USER CODE BEGIN Header */
  2 /**
  3   ******************************************************************************
  4   * @file    usart.c
  5   * @brief   This file provides code for the configuration
  6   *          of the USART instances.
  7   ******************************************************************************
  8   * @attention
  9   *
 10   * Copyright (c) 2022 STMicroelectronics.
 11   * All rights reserved.
 12   *
 13   * This software is licensed under terms that can be found in the LICENSE file
 14   * in the root directory of this software component.
 15   * If no LICENSE file comes with this software, it is provided AS-IS.
 16   *
 17   ******************************************************************************
 18   */
 19 /* USER CODE END Header */
 20 /* Includes ------------------------------------------------------------------*/
 21 #include "usart.h"
 22 
 23 /* USER CODE BEGIN 0 */
 24 #include "stdio.h"
 25 #include "dma.h"
 26 
 27 #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
 28 #define RX_BUF_SIZE 200
 29 
 30 volatile uint8_t usart_dma_tx_over = 1;
 31 uint8_t RxBuff[RX_BUF_SIZE];
 32 uint8_t receive_num;
 33 
 34 /* USER CODE END 0 */
 35 
 36 UART_HandleTypeDef huart1;
 37 DMA_HandleTypeDef hdma_usart1_rx;
 38 DMA_HandleTypeDef hdma_usart1_tx;
 39 
 40 /* USART1 init function */
 41 
 42 void MX_USART1_UART_Init(void)
 43 {
 44 
 45   /* USER CODE BEGIN USART1_Init 0 */
 46 
 47   /* USER CODE END USART1_Init 0 */
 48 
 49   /* USER CODE BEGIN USART1_Init 1 */
 50 
 51   /* USER CODE END USART1_Init 1 */
 52   huart1.Instance = USART1;
 53   huart1.Init.BaudRate = 115200;
 54   huart1.Init.WordLength = UART_WORDLENGTH_8B;
 55   huart1.Init.StopBits = UART_STOPBITS_1;
 56   huart1.Init.Parity = UART_PARITY_NONE;
 57   huart1.Init.Mode = UART_MODE_TX_RX;
 58   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 59   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 60   if (HAL_UART_Init(&huart1) != HAL_OK)
 61   {
 62     Error_Handler();
 63   }
 64   /* USER CODE BEGIN USART1_Init 2 */
 65   __HAL_UART_ENABLE_IT((UART_HandleTypeDef *)&huart1, UART_IT_IDLE);
 66   HAL_UART_Receive_DMA((UART_HandleTypeDef *)&huart1, (uint8_t *)RxBuff, (uint16_t) RX_BUF_SIZE);
 67   /* USER CODE END USART1_Init 2 */
 68 
 69 }
 70 
 71 void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
 72 {
 73 
 74   GPIO_InitTypeDef GPIO_InitStruct = {0};
 75   if(uartHandle->Instance==USART1)
 76   {
 77   /* USER CODE BEGIN USART1_MspInit 0 */
 78 
 79   /* USER CODE END USART1_MspInit 0 */
 80     /* USART1 clock enable */
 81     __HAL_RCC_USART1_CLK_ENABLE();
 82 
 83     __HAL_RCC_GPIOA_CLK_ENABLE();
 84     /**USART1 GPIO Configuration
 85     PA9     ------> USART1_TX
 86     PA10     ------> USART1_RX
 87     */
 88     GPIO_InitStruct.Pin = GPIO_PIN_9;
 89     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 90     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 91     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 92 
 93     GPIO_InitStruct.Pin = GPIO_PIN_10;
 94     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 95     GPIO_InitStruct.Pull = GPIO_NOPULL;
 96     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 97 
 98     /* USART1 DMA Init */
 99     /* USART1_RX Init */
100     hdma_usart1_rx.Instance = DMA1_Channel5;
101     hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
102     hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
103     hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
104     hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
105     hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
106     hdma_usart1_rx.Init.Mode = DMA_NORMAL;
107     hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
108     if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
109     {
110       Error_Handler();
111     }
112 
113     __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
114 
115     /* USART1_TX Init */
116     hdma_usart1_tx.Instance = DMA1_Channel4;
117     hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
118     hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
119     hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
120     hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
121     hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
122     hdma_usart1_tx.Init.Mode = DMA_NORMAL;
123     hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
124     if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
125     {
126       Error_Handler();
127     }
128 
129     __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);
130 
131     /* USART1 interrupt Init */
132     HAL_NVIC_SetPriority(USART1_IRQn, 3, 0);
133     HAL_NVIC_EnableIRQ(USART1_IRQn);
134   /* USER CODE BEGIN USART1_MspInit 1 */
135 
136   /* USER CODE END USART1_MspInit 1 */
137   }
138 }
139 
140 void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
141 {
142 
143   if(uartHandle->Instance==USART1)
144   {
145   /* USER CODE BEGIN USART1_MspDeInit 0 */
146 
147   /* USER CODE END USART1_MspDeInit 0 */
148     /* Peripheral clock disable */
149     __HAL_RCC_USART1_CLK_DISABLE();
150 
151     /**USART1 GPIO Configuration
152     PA9     ------> USART1_TX
153     PA10     ------> USART1_RX
154     */
155     HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
156 
157     /* USART1 DMA DeInit */
158     HAL_DMA_DeInit(uartHandle->hdmarx);
159     HAL_DMA_DeInit(uartHandle->hdmatx);
160 
161     /* USART1 interrupt Deinit */
162     HAL_NVIC_DisableIRQ(USART1_IRQn);
163   /* USER CODE BEGIN USART1_MspDeInit 1 */
164 
165   /* USER CODE END USART1_MspDeInit 1 */
166   }
167 }
168 
169 /* USER CODE BEGIN 1 */
170 
171 #ifdef __GNUC__
172 PUTCHAR_PROTOTYPE
173 {
174   while(!usart_dma_tx_over);
175   HAL_UART_Transmit_DMA(&huart1,(uint8_t *)&ch,1);
176   usart_dma_tx_over = 0;
177   return ch;
178 }
179 #endif
180 
181 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
182 {
183     if(huart->Instance==USART1)
184     {
185         usart_dma_tx_over = 1;
186     }
187 }
188 
189 void USER_UARTx_IRQHandler(UART_HandleTypeDef *huart){
190     if(USART1 == huart->Instance){
191         if(__HAL_UART_GET_FLAG((UART_HandleTypeDef *)&huart1, UART_FLAG_IDLE) == SET)
192           {
193             __HAL_UART_CLEAR_IDLEFLAG((UART_HandleTypeDef *)&huart1);
194             HAL_UART_DMAStop((UART_HandleTypeDef *)&huart1);
195             receive_num = RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
196             DMA_M2M_Start(RxBuff, DMABuff, receive_num);
197             receive_num = 0;
198             HAL_UART_Receive_DMA((UART_HandleTypeDef *)&huart1, (uint8_t *)RxBuff, (uint16_t) RX_BUF_SIZE);
199           }
200     }
201 }
202 /* USER CODE END 1 */

 

dma.c

  1 /* USER CODE BEGIN Header */
  2 /**
  3   ******************************************************************************
  4   * @file    dma.c
  5   * @brief   This file provides code for the configuration
  6   *          of all the requested memory to memory DMA transfers.
  7   ******************************************************************************
  8   * @attention
  9   *
 10   * Copyright (c) 2022 STMicroelectronics.
 11   * All rights reserved.
 12   *
 13   * This software is licensed under terms that can be found in the LICENSE file
 14   * in the root directory of this software component.
 15   * If no LICENSE file comes with this software, it is provided AS-IS.
 16   *
 17   ******************************************************************************
 18   */
 19 /* USER CODE END Header */
 20 
 21 /* Includes ------------------------------------------------------------------*/
 22 #include "dma.h"
 23 
 24 /* USER CODE BEGIN 0 */
 25 #include "stdio.h"
 26 /* USER CODE END 0 */
 27 
 28 /*----------------------------------------------------------------------------*/
 29 /* Configure DMA                                                              */
 30 /*----------------------------------------------------------------------------*/
 31 
 32 /* USER CODE BEGIN 1 */
 33 uint8_t DMABuff[DMA_BUF_SIZE];
 34 /* USER CODE END 1 */
 35 DMA_HandleTypeDef hdma_memtomem_dma1_channel1;
 36 
 37 /**
 38   * Enable DMA controller clock
 39   * Configure DMA for memory to memory transfers
 40   *   hdma_memtomem_dma1_channel1
 41   */
 42 void MX_DMA_Init(void)
 43 {
 44 
 45   /* DMA controller clock enable */
 46   __HAL_RCC_DMA1_CLK_ENABLE();
 47 
 48   /* Configure DMA request hdma_memtomem_dma1_channel1 on DMA1_Channel1 */
 49   hdma_memtomem_dma1_channel1.Instance = DMA1_Channel1;
 50   hdma_memtomem_dma1_channel1.Init.Direction = DMA_MEMORY_TO_MEMORY;
 51   hdma_memtomem_dma1_channel1.Init.PeriphInc = DMA_PINC_ENABLE;
 52   hdma_memtomem_dma1_channel1.Init.MemInc = DMA_MINC_ENABLE;
 53   hdma_memtomem_dma1_channel1.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 54   hdma_memtomem_dma1_channel1.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 55   hdma_memtomem_dma1_channel1.Init.Mode = DMA_NORMAL;
 56   hdma_memtomem_dma1_channel1.Init.Priority = DMA_PRIORITY_LOW;
 57   if (HAL_DMA_Init(&hdma_memtomem_dma1_channel1) != HAL_OK)
 58   {
 59     Error_Handler();
 60   }
 61 
 62   /* DMA interrupt init */
 63   /* DMA1_Channel1_IRQn interrupt configuration */
 64   HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 5, 0);
 65   HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
 66   /* DMA1_Channel4_IRQn interrupt configuration */
 67   HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 4, 0);
 68   HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
 69   /* DMA1_Channel5_IRQn interrupt configuration */
 70   HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 4, 0);
 71   HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
 72 
 73 }
 74 
 75 /* USER CODE BEGIN 2 */
 76 static void TransferComplete(DMA_HandleTypeDef *DmaHandle){
 77     if(DMA1_Channel1 == DmaHandle->Instance)
 78     {
 79         printf("%s",DMABuff);
 80         memset(DMABuff,0,sizeof(DMABuff));
 81     }
 82 }
 83 
 84 static void TransferError(DMA_HandleTypeDef *DmaHandle){
 85     if(DMA1_Channel1 == DmaHandle->Instance)
 86     {
 87         printf("DMATransferErrorByDMA1_Channel1\r\n");
 88     }
 89 }
 90 
 91 
 92 void DMA_M2M_Start(uint8_t *srcAddr,uint8_t *dstAddr,uint16_t bufsz){
 93     if(HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel1,(uint32_t)srcAddr,(uint32_t)dstAddr,bufsz)!=HAL_OK){
 94         Error_Handler();
 95     }
 96 }
 97 
 98 void RegisterCallbackFunctionForUart(void)
 99 {
100     HAL_DMA_RegisterCallback(&hdma_memtomem_dma1_channel1,HAL_DMA_XFER_CPLT_CB_ID,TransferComplete);
101     HAL_DMA_RegisterCallback(&hdma_memtomem_dma1_channel1,HAL_DMA_XFER_ERROR_CB_ID,TransferError);
102 }
103 /* USER CODE END 2 */

stm32f1xx_it.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    stm32f1xx_it.c
  * @brief   Interrupt Service Routines.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f1xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usart.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */

/* USER CODE END TD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_memtomem_dma1_channel1;
extern RTC_HandleTypeDef hrtc;
extern SPI_HandleTypeDef hspi1;
extern TIM_HandleTypeDef htim2;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx;
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN EV */

/* USER CODE END EV */

/******************************************************************************/
/*           Cortex-M3 Processor Interruption and Exception Handlers          */
/******************************************************************************/
/**
  * @brief This function handles Non maskable interrupt.
  */
void NMI_Handler(void)
{
  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */

  /* USER CODE END NonMaskableInt_IRQn 0 */
  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
  while (1)
  {
  }
  /* USER CODE END NonMaskableInt_IRQn 1 */
}

/**
  * @brief This function handles Hard fault interrupt.
  */
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Memory management fault.
  */
void MemManage_Handler(void)
{
  /* USER CODE BEGIN MemoryManagement_IRQn 0 */

  /* USER CODE END MemoryManagement_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
    /* USER CODE END W1_MemoryManagement_IRQn 0 */
  }
}

/**
  * @brief This function handles Prefetch fault, memory access fault.
  */
void BusFault_Handler(void)
{
  /* USER CODE BEGIN BusFault_IRQn 0 */

  /* USER CODE END BusFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_BusFault_IRQn 0 */
    /* USER CODE END W1_BusFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Undefined instruction or illegal state.
  */
void UsageFault_Handler(void)
{
  /* USER CODE BEGIN UsageFault_IRQn 0 */

  /* USER CODE END UsageFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
    /* USER CODE END W1_UsageFault_IRQn 0 */
  }
}

/**
  * @brief This function handles System service call via SWI instruction.
  */
void SVC_Handler(void)
{
  /* USER CODE BEGIN SVCall_IRQn 0 */

  /* USER CODE END SVCall_IRQn 0 */
  /* USER CODE BEGIN SVCall_IRQn 1 */

  /* USER CODE END SVCall_IRQn 1 */
}

/**
  * @brief This function handles Debug monitor.
  */
void DebugMon_Handler(void)
{
  /* USER CODE BEGIN DebugMonitor_IRQn 0 */

  /* USER CODE END DebugMonitor_IRQn 0 */
  /* USER CODE BEGIN DebugMonitor_IRQn 1 */

  /* USER CODE END DebugMonitor_IRQn 1 */
}

/**
  * @brief This function handles Pendable request for system service.
  */
void PendSV_Handler(void)
{
  /* USER CODE BEGIN PendSV_IRQn 0 */

  /* USER CODE END PendSV_IRQn 0 */
  /* USER CODE BEGIN PendSV_IRQn 1 */

  /* USER CODE END PendSV_IRQn 1 */
}

/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

/******************************************************************************/
/* STM32F1xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32f1xx.s).                    */
/******************************************************************************/

/**
  * @brief This function handles RTC global interrupt.
  */
void RTC_IRQHandler(void)
{
  /* USER CODE BEGIN RTC_IRQn 0 */

  /* USER CODE END RTC_IRQn 0 */
  HAL_RTCEx_RTCIRQHandler(&hrtc);
  /* USER CODE BEGIN RTC_IRQn 1 */

  /* USER CODE END RTC_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel1 global interrupt.
  */
void DMA1_Channel1_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */

  /* USER CODE END DMA1_Channel1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_memtomem_dma1_channel1);
  /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */

  /* USER CODE END DMA1_Channel1_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel4 global interrupt.
  */
void DMA1_Channel4_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel4_IRQn 0 */

  /* USER CODE END DMA1_Channel4_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart1_tx);
  /* USER CODE BEGIN DMA1_Channel4_IRQn 1 */

  /* USER CODE END DMA1_Channel4_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel5 global interrupt.
  */
void DMA1_Channel5_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel5_IRQn 0 */

  /* USER CODE END DMA1_Channel5_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart1_rx);
  /* USER CODE BEGIN DMA1_Channel5_IRQn 1 */

  /* USER CODE END DMA1_Channel5_IRQn 1 */
}

/**
  * @brief This function handles TIM2 global interrupt.
  */
void TIM2_IRQHandler(void)
{
  /* USER CODE BEGIN TIM2_IRQn 0 */

  /* USER CODE END TIM2_IRQn 0 */
  HAL_TIM_IRQHandler(&htim2);
  /* USER CODE BEGIN TIM2_IRQn 1 */

  /* USER CODE END TIM2_IRQn 1 */
}

/**
  * @brief This function handles SPI1 global interrupt.
  */
void SPI1_IRQHandler(void)
{
  /* USER CODE BEGIN SPI1_IRQn 0 */

  /* USER CODE END SPI1_IRQn 0 */
  HAL_SPI_IRQHandler(&hspi1);
  /* USER CODE BEGIN SPI1_IRQn 1 */

  /* USER CODE END SPI1_IRQn 1 */
}

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  USER_UARTx_IRQHandler(&huart1);
  /* USER CODE END USART1_IRQn 1 */
}

/**
  * @brief This function handles RTC alarm interrupt through EXTI line 17.
  */
void RTC_Alarm_IRQHandler(void)
{
  /* USER CODE BEGIN RTC_Alarm_IRQn 0 */

  /* USER CODE END RTC_Alarm_IRQn 0 */
  HAL_RTC_AlarmIRQHandler(&hrtc);
  /* USER CODE BEGIN RTC_Alarm_IRQn 1 */

  /* USER CODE END RTC_Alarm_IRQn 1 */
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

 

usart.h

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    usart.h
  * @brief   This file contains all the function prototypes for
  *          the usart.c file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_H__
#define __USART_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

extern UART_HandleTypeDef huart1;

/* USER CODE BEGIN Private defines */

/* USER CODE END Private defines */

void MX_USART1_UART_Init(void);

/* USER CODE BEGIN Prototypes */
void USER_UARTx_IRQHandler(UART_HandleTypeDef *huart);
/* USER CODE END Prototypes */

#ifdef __cplusplus
}
#endif

#endif /* __USART_H__ */

 

dma.h

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    dma.h
  * @brief   This file contains all the function prototypes for
  *          the dma.c file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DMA_H__
#define __DMA_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* DMA memory to memory transfer handles -------------------------------------*/
extern DMA_HandleTypeDef hdma_memtomem_dma1_channel1;

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* USER CODE BEGIN Private defines */
#define DMA_BUF_SIZE 200

extern uint8_t DMABuff[DMA_BUF_SIZE];
/* USER CODE END Private defines */

void MX_DMA_Init(void);

/* USER CODE BEGIN Prototypes */
void RegisterCallbackFunctionForUart(void);
void DMA_M2M_Start(uint8_t *srcAddr,uint8_t *dstAddr,uint16_t bufsz);
/* USER CODE END Prototypes */

#ifdef __cplusplus
}
#endif

#endif /* __DMA_H__ */

 

参考连接:

STM32CubeIDE 添加printf打印输出、添加自定义的文件夹_Ch_champion的博客-CSDN博客

STM32MP157实验(六)——DMA(Memory To Memory)_Jacky~~的博客-CSDN博客

STM32 HAL库学习(四):DMA之串口空闲中断_la_fe_的博客-CSDN博客_hal库dma中断

 

posted @ 2022-04-16 16:04  Ragnaros  阅读(1112)  评论(0)    收藏  举报