使用CubeMX进行STM32开发之十:优化ADC配置

        参考《STM32中文参考手册_V10》,研究CubeMX中有关ADC的配置。

一、配置参数

ADC1 Mode and Configuration:

        IN0~IN9:10路12位ADC采样通道,外部模拟量信号输入

        Temperature Sensor Channel:MCU内置温度传感器采样通道,用来测量器件周围的温度。在MCU内部与ADC1_IN16通道相连

        Vrefint Channel:内部参考电压检测通道,ADC 的参考电压都是通过 Vref+ 引脚提供的并作为ADC转换器的基准电压,当Vref+直接取自VDD电压时,易受VDD波动而影响,因此可以该通道对参考电压进行校准,以提升ADC计算精度。在MCU内部与ADC1_IN17通道相连

        EXTI Conversion Trigger:外部触发转换。ADC转换可由外部事件触发,EXTSEL[2:0]和JEXTSEL[2:0]控制位允许应用程序选择8个可能的事件中的某一个,触发规则通道组合注入通道组的采样。这里若选择Disable,则可以在6个来自片上定时器的内部信号中选择一个作为触发源;若选择Injected Trigger/Regular Trigger/Injected and Regular Trigger,表示由外部引脚信号触发相应的通道组。

Parameter Settings:

  • ADCs_Common_Settings
  •         Mode:Independent mode

            独立模式。此模式中,双ADC同步不工作,ADC1和ADC2相互独立工作。对应ADC控制寄存器1(ADC_CR1)中的DUALMOD[3:0]位。

  • ADC_Settings
  •         Data Alignment:Right alignment

            数据右对齐。对应ADC控制寄存器2(ADC_CR2)中的ALIGN位。

            Scan Conversion Mode:Enable

            扫描模式使能。对应ADC控制寄存器1(ADC_CR1)中的SCAN位。

            Continuous Conversion Mode:Disable

            单次转换模式。对应ADC控制寄存器2(ADC_CR2)中的CONT位。

            Discontinuous Conversion Mode:Disable

            禁用间断模式,对应ADC控制寄存器1(ADC_CR1)中的DISCEN位。

  • ADC_Regular_ConversionMode:规则通道组采样设置
  •         Enable Regular Conversions:Enable

            使能规则通道组转换。

            Number of Conversion:3

            规则通道组序列长度为3,即包含3个采样通道。

            External Trigger Conversion Source:Timer 2 Capture 2 event

            选择定时器2的CC2事件作为启动规则通道组的外部事件。

  • Rank:ADC转换通道设置
  • ADC_Injected_ConversionMode:注入通道组采样设置
  • WatchDog:是否开启模拟看门狗
  • 二、生成代码

    void MX_ADC1_Init(void)
    {
    
      /* USER CODE BEGIN ADC1_Init 0 */
    
      /* USER CODE END ADC1_Init 0 */
    
      ADC_ChannelConfTypeDef sConfig = {0};
    
      /* USER CODE BEGIN ADC1_Init 1 */
    
      /* USER CODE END ADC1_Init 1 */
    
      /** Common config
      */
      hadc1.Instance = ADC1;
      hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
      hadc1.Init.ContinuousConvMode = DISABLE;
      hadc1.Init.DiscontinuousConvMode = DISABLE;
      hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_CC2;
      hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
      hadc1.Init.NbrOfConversion = 3;
      if (HAL_ADC_Init(&hadc1) != HAL_OK)
      {
        Error_Handler();
      }
    
      /** Configure Regular Channel
      */
      sConfig.Channel = ADC_CHANNEL_0;
      sConfig.Rank = ADC_REGULAR_RANK_1;
      sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
    
      /** Configure Regular Channel
      */
      sConfig.Channel = ADC_CHANNEL_1;
      sConfig.Rank = ADC_REGULAR_RANK_2;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
    
      /** Configure Regular Channel
      */
      sConfig.Channel = ADC_CHANNEL_2;
      sConfig.Rank = ADC_REGULAR_RANK_3;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN ADC1_Init 2 */
    
      /* USER CODE END ADC1_Init 2 */
    
    }
    
    void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct = {0};
      if(adcHandle->Instance==ADC1)
      {
      /* USER CODE BEGIN ADC1_MspInit 0 */
    
      /* USER CODE END ADC1_MspInit 0 */
        /* ADC1 clock enable */
        __HAL_RCC_ADC1_CLK_ENABLE();
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**ADC1 GPIO Configuration
        PA0-WKUP     ------> ADC1_IN0
        PA1     ------> ADC1_IN1
        PA2     ------> ADC1_IN2
        */
        GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
        /* ADC1 DMA Init */
        /* ADC1 Init */
        hdma_adc1.Instance = DMA1_Channel1;
        hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
        hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
        hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
        hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
        hdma_adc1.Init.Mode = DMA_CIRCULAR;
        hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
        if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
        {
          Error_Handler();
        }
    
        __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
    
      /* USER CODE BEGIN ADC1_MspInit 1 */
    
      /* USER CODE END ADC1_MspInit 1 */
      }
    }

    与标准库函数代码对比:

    	/* GPIO */
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );
    	
    	/*PA0-PA2ÈýÏàµçÁ÷²ÉÑù*/
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//ADC0
    	GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//ADC1
    	GPIO_Init(GPIOA, &GPIO_InitStructure);	
    	
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//ADC2
    	GPIO_Init(GPIOA, &GPIO_InitStructure);	
    	
    	/* ADC */
    
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    
    	ADC_DeInit(ADC1); 
    	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    	ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;
    	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    	ADC_InitStructure.ADC_NbrOfChannel = 3;
    	ADC_Init(ADC1, &ADC_InitStructure);
    //	ADC_TempSensorVrefintCmd(ENABLE);
    
    	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
    
    	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5);
    	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_7Cycles5);
    	ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_7Cycles5);
    //	ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_7Cycles5);
    //	ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_7Cycles5);
    //	ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_7Cycles5);
    //	ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7, ADC_SampleTime_7Cycles5);
    
    	ADC_DMACmd(ADC1, ENABLE); 
    	ADC_Cmd(ADC1, ENABLE);
    
    	/* ADC校准 */
    	ADC_ResetCalibration(ADC1);
    	while(ADC_GetResetCalibrationStatus(ADC1));
    	ADC_StartCalibration(ADC1);
    	while(ADC_GetCalibrationStatus(ADC1));
    
    	ADC_ExternalTrigConvCmd(ADC1, ENABLE);
    

     三、小结

            CubeMX中ADC的配置需要与GPIO的配置、DMA和TIM的配置(根据需求)相结合。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 使用CubeMX进行STM32开发之十:优化ADC配置

    发表评论