Teach you step by step how to implement DMA reading of STM32 ADC through HAL library

Table of contents

1.CUBEMx settings

1.1 New construction

1.2 Chip configuration

1.2.1 Clock configuration

 1.2.2 System debugging configuration

 1.3 ADC configuration

1.3.1 Parameter Settings configuration

 1.3.2DMA Settings configuration

1.4 Project configuration

 2.Procedure improvement

2.1 Improve the main function

 2.2 Debugging

3. Summary


1.CUBEMx settings

1.1 New construction

1.2 Chip configuration

1.2.1 Clock configuration

 Enter 72 at 1 and press Enter, the system will automatically adjust other clocks to the corresponding configuration.

 1.2.2 System debugging configuration

In order to enable the generated program to be debugged online, click Pinout & Configuration at 1 again, click SYS, and click Serial Wire at Debug.

 1.3 ADC configuration

Here we collect and configure AD for all 14 ADCs in 14-channel ADC1. Here we first click ADC1 under Analog, and then click all the √ in front of IN0~IN14, which means we enable the first 14 inputs.

1.3.1 Parameter Settings configuration

Here is the most important configuration part of the ADC. We will explain it in detail one by one:

(1) Data Alignment--->Right alignment This item selects right alignment and remains unchanged.

(2) Scan Conversion Mode--->Enable This item selects scan mode enable, which means scanning the 15 ADC inputs separately. If it is not enabled, it will only read the value of one input.

(3) Continuous Conversion Mode --->Enable This item selects the continuous scanning mode, which means that the ADC value will be continuously converted. If this item is not enabled, it will only collect once and then stop. ADC conversion will not continue until the next time it is enabled.

(4) Discontinuous Conversion Mode--->Disable This item and the third item are duplicated.

(5) Number of Conversion---->15 You can select as many inputs as there are here, and only after selecting a number here will 15 different channels appear below. And this should be the first step that requires operation when entering ADC1, otherwise (2) (3) is gray and cannot be selected to enable.

 (6) Among the 15 Ranks that appear, configure each channel separately. For example, Rank1 is configured as Channel 0, and the sampling time is 55.5Cycles; Rank2 is configured as Channel 1, and the sampling time is also 55.5Cycles. The thing to note here is that if you do not check and configure each channel, there may be many Ranks collecting a Channel at the same time, resulting in errors in AD's data collection.

 1.3.2DMA Settings configuration

Select the DMA Settings tab, click Add, select ADC1, then change the Mode to Circular, increase the Memory address, and select Half Word for Data Width. Configuration completed.

 Other UserConstant GPIO Settings can be left alone.

1.4 Project configuration

Select the Project in the top Project Manager, first name the new project ModbusSlave, change the Application Structure to Basic, and finally change the development tool to your own development tool. I use KEIL here and select MDK here.

 Then select Code Generator and check Generator peripheral initalization as a pair of '.c/.h' files per peripheral on this interface.

 Finally generated code:

 2.Procedure improvement

2.1 Improve the main function

Add the AdcBuf array in the main.c function summary, and then after initializing the ADC, start the ADC correction and HAL_ADC_Start - DMA starts the DMA and you are done.

 The program code is as follows:

int main(void)
{
  /* USER CODE BEGIN 1 */
	uint16_t AdcBuf[15]={0};
  /* 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_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
	HAL_ADCEx_Calibration_Start(&hadc1);
	HAL_ADC_Start_DMA(&hadc1, (uint32_t *)AdcBuf, 15);
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */
}

 2.2 Debugging

After the program is compiled and downloaded, click on the debugging interface, add AdcBuf to the monitoring interface, and you can see the displayed data.​ 

 During debugging, I input a voltage of about 2.5V to the 11th channel. We can see that the data here is 0x0C1E, which is converted into decimal 3102.

\frac{3102}{4096}*3.3=2.499

3. Summary

It is very easy to collect ADC DMA data in the HAL library, but there are some details that need to be paid attention to, especially the places I marked in red, which I made myself.

Guess you like

Origin blog.csdn.net/tangxianyu/article/details/121149981