STM32 CUBEMX配置ADC采样——电机FOC控制(三)


文章目录

  • 前言
  • 一、设置STM32G431 ADC时钟树
  • 二、设置STM32G431 ADC1和ADC2采样通道。
  • 三、设置STM32G431 ADC采样基本属性:规则采样与注入采样。
  • 四、设置STM32G431 ADC中断源。
  • 五、代码修改。
  • 六、示波器查看波形。
  • 总结

  • 前言

    本文在电机FOC控制(二)STM32 CUBEMX 配置三相PWM互补输出基础上,继续讲述如何STM32 CUBEMX 配置ADC寄存器,使TIMER1 PWM互补输出CC4触发ADC注入采样的过程。


    一、设置STM32G431 ADC时钟树

    打开Clock Configuration界面,将ADC设置为42.5MHz。

    二、设置STM32G431 ADC1和ADC2采样通道。

    设定ADC1通道7和通道8为单端输入:

    设定ADC2通道6和通道7为单端输入:

    三、设置STM32G431 ADC采样基本属性:规则采样与注入采样。

    ADC基本设定
    ADCs_Commmon_Setting
    Mode:选择独立模式,本工程只需要单个ADC采样,不需要多个ADC联合使用。
    ADC_Setting:
    Clock Prescaler:是ADC工作频率,选择Asynchronous clock mode divided by 1(1分频)。
    Resolution :ADC分辨率,配置为12位分辨率。
    Data Alignment:数据对齐方式,配置为左对齐。
    Gain Compensation:由于STMG431内置放大器,由于没有使用,配置放大器增益为0,不需要放大器增益补偿。
    Scan Conversion Mode:规则采样使用连续扫描转换。配置为ENABLE。
    End Of Conversion Selection:结束转换选择,配置为End Of Single Conversion。
    Low Power Auto Wait:低功耗自动等待,配置为Disable。
    Continuous Conversion Mode:连续转换模式,不使能相当于单次转换模式,使能的话,相当于连续转换模式,配置为Disable。
    Discontinuous Conversion Mode:规则组转换序列的不连续方式,启动转换,转换结束后,等待启动信号,配置为Disabled。
    *** Continuous Conversion Mode与Discontinuous Conversion Mode不能同时使能,两者不能共存。
    DMA Continuous Requests:DMA连续请求模式,采集完数据后,是否自动关闭ADC1和DMA。配置为Disabled。
    Overrun behaviour:如果数据没有读取,新的ADC转换结果是否覆盖原来的结果,配置为Overrun data preserved 保留原来的数据。

    ADC规则采样设定:

    ADC Regular ConversionMode:
    Enable Regular Conversion:启用常规转换模式,配置为Enable。
    Enable Regular Oversampling:是否使用过采样模式 ,配置为:Diasble。
    Number Of Conversion:此为规则组通道数量,配置为2个。
    External Trigger Conversion Source:规则组通道采样的触发源,配置为软件触发。
    External Trigger Conversion Edge:规则组通道采样的触发源的触发方式,由于采用软件触发,配置为:None。
    Rank 1 :配置规则组通道的采样顺序和各通道的采样时间。
    Channel:选择Channel 2做为第一通道。
    Sample Time:配置为47.5周期。
    Offset Number:配置为No offset。不设定偏置。
    Rank 2 :配置规则组通道的采样顺序和各通道的采样时间。
    Channel:选择Channel 8做为第一通道。
    Sample Time:配置为47.5周期。
    Offset Number:配置为No offset。不设定偏置。

    ADC注入采样设定

    ADC Injected ConversionMode

    Enable Injected Conversions:是否使能注入转换。注入通道只有在规则通道存在时才会出现。
    Number Of Conversion:ADC转换的注入通道数,配置为2
    External Trigger Source:配置为Timer1触发事件
    External Trigger Conversion Edge:配置为上升沿触发。
    Enable Injected Oversampling:配置为关闭状态。
    Injected Conversion Mode:配置为无。
    Injected Queue:配置为关闭状态。
    Rank 1:通道1。
    Channel : 设定为Channel 1,配置成1通道。
    Sampling Time:设定采样周期为6.5个周期。
    Offset Number:设定为没有偏置。
    Rank 2:通道2。
    Channel : 设定为Channel 7,配置成7通道。
    Sampling Time:设定采样周期为6.5个周期。
    Offset Number:设定为没有偏置。

    ADC2设定:

    Rank 1:通道1。
    Channel : 设定为Channel 1,配置成1通道。
    Sampling Time:设定采样周期为6.5个周期。
    Rank 2:通道2。
    Channel : 设定为Channel 7,配置成7通道。
    Sampling Time:设定采样周期为6.5个周期。

    四、设置STM32G431 ADC中断源。

    允许ADC1和ADC2全局中断,设定ADC1和ADC2中断优先级。


    到此ADC基本配置完毕。

    五、代码修改。

    使用STM32 LL库

    在main.c文件修改:

    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_GPIO_Init();
      MX_TIM1_Init();
      MX_ADC1_Init();
      MX_ADC2_Init();
      
      /* Initialize interrupts */
      MX_NVIC_Init();
      
      /* USER CODE BEGIN 2 */
      LL_TIM_EnableIT_CC4(TIM1);
      LL_TIM_EnableCounter(TIM1);
      
      /* Enable PWM channel */
      LL_TIM_CC_EnableChannel(TIM1, TIMxCCER_MASK_CH123);
    //	LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_OC4REF);
      LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH4);
      /* Main PWM Output Enable */
      TIM1->BDTR |= LL_TIM_OSSI_ENABLE;
      LL_TIM_EnableAllOutputs(TIM1);
    
      /* - Exit from deep-power-down mode */
      LL_ADC_DisableDeepPowerDown(ADC1);
      /* Enable ADC internal voltage regulator */
      LL_ADC_EnableInternalRegulator(ADC1);
      
      LL_ADC_ClearFlag_JEOC(ADC1);
      LL_ADC_EnableIT_JEOC(ADC1);
    
      LL_ADC_StartCalibration(ADC1, LL_ADC_SINGLE_ENDED);
    	
      while (1U == LL_ADC_IsCalibrationOnGoing(ADC1))
      {
        /* Nothing to do */
      }
    	
      LL_ADC_Enable(ADC1);
    	
      /* Clear JSQR from CubeMX setting to avoid not wanting conversion*/
      LL_ADC_INJ_StartConversion(ADC1);
      /* TODO: check if not already done by MX */
    
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
        LED_RUN();
      }
      /* USER CODE END 3 */
    }
    

    在stm32g4xx_it.c文件修改:
    使用GPIOB的PIN12引脚做为波形输出引脚。

    void ADC1_2_IRQHandler(void)
    {
      /* USER CODE BEGIN ADC1_2_IRQn 0 */
      //触发后为低电平
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12,GPIO_PIN_RESET );
    	
    //	HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_12);
    	
    //	ADC_Value = HAL_ADC_GetValue(&hadc1);   //获取AD值
      /* USER CODE END ADC1_2_IRQn 0 */
      HAL_ADC_IRQHandler(&hadc1);
      HAL_ADC_IRQHandler(&hadc2);
      /* USER CODE BEGIN ADC1_2_IRQn 1 */
    
      /* USER CODE END ADC1_2_IRQn 1 */
    }
    

    修改HAL_TIM_IRQHandler函数,使CC4触发时,GPIOB的PIN12为高电平。

    void TIM1_CC_IRQHandler(void)
    {
      /* USER CODE BEGIN TIM1_CC_IRQn 0 */
    
      /* USER CODE END TIM1_CC_IRQn 0 */
      HAL_TIM_IRQHandler(&htim1);
      /* USER CODE BEGIN TIM1_CC_IRQn 1 */
    
      /* USER CODE END TIM1_CC_IRQn 1 */
    }
    
    /* Capture compare 4 event */
      if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
      {
        if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) != RESET)
        {
          __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
          htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
          /* Input capture event */
          if ((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
          {
    #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
            htim->IC_CaptureCallback(htim);
    #else
            HAL_TIM_IC_CaptureCallback(htim);
    #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
          }
          /* Output compare event */
          else
          {
    	  //使GPIOB PIN12高电平
    	  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12,GPIO_PIN_SET );
    				//HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_12);
    #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
            htim->OC_DelayElapsedCallback(htim);
            htim->PWM_PulseFinishedCallback(htim);
    #else
            HAL_TIM_OC_DelayElapsedCallback(htim);
            HAL_TIM_PWM_PulseFinishedCallback(htim);
    #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
          }
          htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
        }
      }
    
    

    六、示波器查看波形。


    可以看到CC4触发ADC采样开始至ADC采样结束的波形。

    总结

    通过以上实验,成功使STM32G431通过高级定时器TIMER1的CC4触发了ADC注入采样,并捕获了CC4触发ADC采样开始至ADC采样结束的波形。

    作者:向上高远

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32 CUBEMX配置ADC采样——电机FOC控制(三)

    发表评论