STM32CubeMX study notes (7)-DMA interface use

1. Introduction to DMA

DMA (Direct Memory Access) is a peripheral of the single chip microcomputer. Its main function is to move data, but it does not need to occupy the CPU. That is, when transferring data, the CPU can do other things. Same as multithreading. Data transmission supports from peripheral to memory or memory to memory, where the memory can be SRAM or FLASH. The DMA controller includes DMA1 and DMA2. Among them, DMA1 has 7 channels and DMA2 has 5 channels. The channels here can be understood as a kind of pipeline for data transmission. It should be noted that DMA2 only exists in large-capacity microcontrollers.

Two, DMA request image

DMA1 request image of each channel DMA2 request image of
DMA1 request image of each channel
each channel
DMA2 request image of each channel
其中 ADC3、SDIO 和 TIM8 的 DMA 请求只在大容量产品中存在,这个在具体项目时 要注意。

3. New construction

1. Open the STM32CubeMX software and click "New Project"

2. Choose MCU and package

3. Configure the clock
RCC settings, select HSE (external high-speed clock),

select Clock Configuration for Crystal/Ceramic Resonator (crystal oscillator/ceramic resonator) , configure the system clock SYSCLK to 72MHz,
modify the value of HCLK to 72, and press Enter. Automatically modify all configurations

4. It
is a very important step to configure the debug mode , otherwise the debugger
SYS setting will not be recognized after the first programming program , select Debug as Serial Wire

Four, DMA1

4.1 Configure the serial port

In the Connectivityselection USART1set, and select the Asynchronousasynchronous communication

baud rate 115200 Bits/s. The length of the transmitted data is 8 Bit. Parity None, stop bit 1, receive and transmit are all 使能.

Enable serial port receive interrupt

4.2 Configure DMA


Click DMA SettingsAdd USART1 TX DMA1 and USART1 RX corresponding to channels 4 and 5 channels.

  • Priority :
    When multiple DMA channel requests occur, it means that there is a sequential response processing order problem, which is also managed by the arbiter. The arbiter manages DMA channel requests in two stages. The first stage belongs to the software stage and can be set in the DMA_CCRx register. There are 4 levels: very high, high, medium and low priority. The second stage belongs to the hardware stage. If two or more DMA channel requests have the same priority setting, their priority depends on the channel number. The lower the number, the higher the priority. For example, channel 0 is higher than channel 1. Among high-capacity products and interconnected products, the DMA1 controller has a higher priority than the DMA2 controller.
  • Mode :
    Normalindicates a single transmission, the transmission is terminated after one transmission.
    CircularIt means cyclic transmission. After the transmission is completed, the transmission will resume again, and the continuous cycle will never stop.
  • Increment Address : Increment the
    Peripheral peripheral address.
    MemoryIndicates that the memory address is incremented.
    The serial port send data is to continuously store data into the serial port send data register (USARTx_TDR). So the external address is not incremented. The internal memory stores the data to be sent, so the address pointer must be incremented to send all the data.
  • Data Width :
    ByteOne byte.
    Half WordHalf a word is equal to two bytes.
    WordOne word is equal to four bytes.
    The serial port data sending register can only store 8 bits, and send one byte at a time, so the data length is Byte.

4.3 Generate code

Path item names and item input

selection of an application development environment IDE MDK-ARM V5

each peripheral generates a separate ’.c/.h’file
not hook: All initialization code is generated in main.c
checked: initialization code file generated in the associated peripheral. For example, the GPIO initialization code is generated in gpio.c.

Click GENERATE CODE to generate code

4.4 USART+DMA data transmission

Create a new variable

uint8_t sendBuff[] = "USART test by DMA\r\n";

Add the following code to the main loop in man.c:

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    
    
    /* USER CODE END WHILE */
    HAL_UART_Transmit_DMA(&huart1, (uint8_t *)sendBuff, sizeof(sendBuff));
    HAL_Delay(1000);
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

Through the serial port assistant, you can see that there are continuous printouts of data in the receiving area.

Note: If the serial port interrupt is not turned on, the program can only send data once, and the program cannot determine whether the DMA transfer is complete, and the USART is always in the busy state.

4.5 USART+DMA data reception

Add global variables to the head of main.c Buffer

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
uint8_t Buffer[1];
/* USER CODE END PV */

Declare global variables at the head of stm32f1xx_it.c Buffer

/* External variables --------------------------------------------------------*/
extern UART_HandleTypeDef huart1;

/* USER CODE BEGIN EV */
extern uint8_t Buffer[1];
/* USER CODE END EV */

In main.c, before the while loop and after the serial port is initialized, add the receive interrupt enable function so that the interrupt will be triggered when data is received for the first time.

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    
    
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_DMA_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_DMA(&huart1, (uint8_t *)Buffer, 1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    
    
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

In stm32f1xx_it.cadding the bottom of this documentHAL_UART_RxCpltCallback()

/* USER CODE BEGIN 1 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    
    
    if(huart->Instance == USART1)
    {
    
    
        HAL_UART_Receive_DMA(&huart1, (uint8_t *)Buffer, 1);
        HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Buffer, 1);
    }
}
/* USER CODE END 1 */

Send OK through the serial port assistant and you can see that O is received. This is because the received data set is one character. If you want to receive more characters, please increase the buffer.

4.6 Serial port IDLE idle interrupt + DMA data reception

Features:

  • Can receive and output any character string.
  • When the serial port has no data reception, it will not be generated. After the IDLE flag is cleared, the trigger must be started after the first data is received. Once the received data is interrupted and no data is received, IDLE is generated. Interrupted.
    Add the following variables in main.c:
uint8_t recvBuff[BUFFER_SIZE];  //接收数据缓存数组
volatile uint8_t recvLength = 0;  //接收一帧数据的长度
volatile uint8_t recvDndFlag = 0; //一帧数据接收完成标志

Add the following macro definitions and variables in main.h:

#define BUFFER_SIZE 256
extern uint8_t recvBuff[BUFFER_SIZE];  //接收数据缓存
extern volatile uint8_t recvLength;  //接收一帧数据的长度
extern volatile uint8_t recvDndFlag; //一帧数据接收完成标志

In main.c, before the while loop and after the serial port is initialized, add idle interrupt and DMA reception enable functions, so that the interrupt is triggered when data is received for the first time.

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    
    
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_DMA_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断
  HAL_UART_Receive_DMA(&huart1, recvBuff, BUFFER_SIZE);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    
    
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

In stm32f1xx_it.cmodifying the bottom of this documentUSART1_IRQHandler()

void USART1_IRQHandler(void)
{
    
    
  /* USER CODE BEGIN USART1_IRQn 0 */
	uint32_t tmpFlag = 0;
	uint32_t temp;
	tmpFlag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
	if((tmpFlag != RESET))//idle标志被置位
	{
    
     
		__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
		
		HAL_UART_DMAStop(&huart1); //
		temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数   
		recvLength  =  BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
		recvDndFlag  = 1;	// 接受完成标志位置1	
		HAL_UART_Transmit_DMA(&huart1, recvBuff, recvLength);
		recvLength = 0;//清除计数
		recvDndFlag = 0;//清除接收结束标志位

		memset(recvBuff,0,recvLength);
		HAL_UART_Receive_DMA(&huart1, recvBuff, BUFFER_SIZE);//重新打开DMA接收,不然只能接收一次数据
	 }
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

Send variable length data through serial port assistant

Five, matters needing attention

User code to be added to USER CODE BEGIN Nand USER CODE END Nbetween, otherwise the next use after STM32CubeMX regenerate the code, it will be deleted.


Written by Leung on January 18, 2021

• Reference: STM32CubeMX Series Tutorial 6: Direct Memory Access (DMA)
    "Embedded-STM32 Development Guide" Part Two Basics-Chapter 7 DMA (HAL Library)

Guess you like

Origin blog.csdn.net/qq_36347513/article/details/112787605