你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32G031K LL库的使用 - ADC

[复制链接]
STMCU小助手 发布时间:2021-11-12 23:01
说明:驱动基于STm32G031K6测试,其他型号需自行做改动。

ADC的初始化:

  1. #define ADCIO1_IN_CHANNEL           LL_ADC_CHANNEL_5
  2. #define ADCIO2_IN_CHANNEL           LL_ADC_CHANNEL_7
  3. uint8_t STM32LLADC1Init(void)
  4. {
  5.   LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
  6.   LL_ADC_InitTypeDef ADC_InitStruct = {0};

  7.   LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  8.   /* Peripheral clock enable */
  9.   LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC);                //使能ADC时钟

  10.   LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);                //谁能响应ADCioGpio时钟
  11.   /**ADC1 GPIO Configuration  
  12.   PA5   ------> ADC1_IN5
  13.   PA7   ------> ADC1_IN7
  14.   */
  15.   GPIO_InitStruct.Pin = gpioADCIO1_IN_PIN;                            //ADC检测IO初始化
  16.   GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
  17.   GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  18.   LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  19.   GPIO_InitStruct.Pin = gpioADCIO2_IN_PIN;
  20.   GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
  21.   GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  22.   LL_GPIO_Init(GPIOA, &GPIO_InitStruct);


  23.   /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  24.   */
  25.   ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;                //ADC定时转化触发条件来源,可以为软件触发或硬件(外部中断、定时器)触发。
  26.   ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS;     //ADC顺序采集通道的个数,根据自己需要的通道个数设置
  27.   ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;       //
  28.   ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE;                 //采集方式,单次采集还是连续采集
  29.   ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;         //使能DMA,并使用无限传输,如果DMA保存方式为循环覆盖的话才可以使用无限传输。
  30.   ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_OVERWRITTEN;               //采集的数据循环覆盖模式
  31.   LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
  32.   LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE);                      //失能过采样
  33.   LL_ADC_SetTriggerFrequencyMode(ADC1, LL_ADC_CLOCK_FREQ_MODE_HIGH);          //采样时钟使用高频模式
  34.   LL_ADC_REG_SetSequencerConfigurable(ADC1, LL_ADC_REG_SEQ_CONFIGURABLE);     //adc通道和硬件adc in是否强制对应,因为adc的io使用时不是连续的,所以这里使用可自定义配置
  35.   LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_1,     LL_ADC_SAMPLINGTIME_160CYCLES_5);    //设置通道共用取样时间,根据需要自行选择
  36.   LL_ADC_DisableIT_EOC(ADC1);        //禁用通道采样结束中断
  37.   LL_ADC_DisableIT_EOS(ADC1);        //禁用序列采样结束中断,因为使用的是单次软件触发所以这里关闭这些中断
  38.   ADC_InitStruct.Clock = LL_ADC_CLOCK_SYNC_PCLK_DIV2;        //选择采样时钟来源
  39.   ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;         //采样分辨率
  40.   ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;    //采样数据对齐方式,右对齐高位补0,左对齐低位补0.
  41.   ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;        //低功耗模式,使用DMA的话无法使用,这里关闭
  42.   LL_ADC_Init(ADC1, &ADC_InitStruct);
  43.   /** Configure Regular Channel
  44.   */
  45.   //ADC_RegularChannelConfig
  46.   LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, ADCIO1_IN_CHANNEL);                //将硬件通道ADCIO1_IN_CHANNEL映射到ADC通道1
  47.   LL_ADC_SetChannelSamplingTime(ADC1, ADCIO1_IN_CHANNEL, LL_ADC_SAMPLINGTIME_COMMON_1); //设置通道采样时间
  48.   LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, ADCIO2_IN_CHANNEL);                //将硬件通道ADCIO1_IN_CHANNEL映射到ADC通道2
  49.   LL_ADC_SetChannelSamplingTime(ADC1, ADCIO2_IN_CHANNEL, LL_ADC_SAMPLINGTIME_COMMON_1);  //设置通道采样时间

  50.   /*采样数据转换时需要参考电压,参考电压可能是变化的,所以也有可能需要采集*/
  51.   //LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_VREFINT);
  52.   //LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_VREFINT, LL_ADC_SAMPLINGTIME_COMMON_1);
  53. return 1;
  54. }
复制代码

激活并校准ADC:

  1. uint8_t STM32ActivateADC1(void)
  2. {
  3.   __IO uint32_t wait_loop_index = 0U;
  4.   __IO uint32_t backup_setting_adc_dma_transfer = 0U;
  5.   uint32_t Timeout = 0U; /* Variable used for timeout management */
  6.   /*## Operation on ADC hierarchical scope: ADC instance #####################*/

  7.   /* Note: Hardware constraint (refer to description of the functions         */
  8.   /*       below):                                                            */
  9.   /*       On this STM32 serie, setting of these features is conditioned to   */
  10.   /*       ADC state:                                                         */
  11.   /*       ADC must be disabled.                                              */
  12.   /* Note: In this example, all these checks are not necessary but are        */
  13.   /*       implemented anyway to show the best practice usages                */
  14.   /*       corresponding to reference manual procedure.                       */
  15.   /*       Software can be optimized by removing some of these checks, if     */
  16.   /*       they are not relevant considering previous settings and actions    */
  17.   /*       in user application.                                               */
  18.   if (LL_ADC_IsEnabled(ADC1) == 0)
  19.   {
  20.     /* Enable ADC internal voltage regulator */
  21.     LL_ADC_EnableInternalRegulator(ADC1);

  22.     /* Delay for ADC internal voltage regulator stabilization.                */
  23.     /* Compute number of CPU cycles to wait for, from delay in us.            */
  24.     /* Note: Variable divided by 2 to compensate partially                    */
  25.     /*       CPU processing cycles (depends on compilation optimization).     */
  26.     /* Note: If system core clock frequency is below 200kHz, wait time        */
  27.     /*       is only a few CPU processing cycles.                             */
  28.     wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);
  29.     while(wait_loop_index != 0)
  30.     {
  31.       wait_loop_index--;
  32.     }

  33.     /* Disable ADC DMA transfer request during calibration */
  34.     /* Note: Specificity of this STM32 serie: Calibration factor is           */
  35.     /*       available in data register and also transfered by DMA.           */
  36.     /*       To not insert ADC calibration factor among ADC conversion data   */
  37.     /*       in DMA destination address, DMA transfer must be disabled during */
  38.     /*       calibration.                                                     */
  39.     backup_setting_adc_dma_transfer = LL_ADC_REG_GetDMATransfer(ADC1);
  40.     LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_NONE);

  41.     /* Run ADC self calibration */
  42.     LL_ADC_StartCalibration(ADC1);

  43.     /* Poll for ADC effectively calibrated */
  44.     Timeout = ADC_CALIBRATION_TIMEOUT_MS;

  45.     while (LL_ADC_IsCalibrationOnGoing(ADC1) != 0)
  46.     {
  47.       /* Check Systick counter flag to decrement the time-out value */
  48.       if (LL_SYSTICK_IsActiveCounterFlag())
  49.       {
  50.         if(Timeout-- == 0)
  51.         {
  52.                 return 0;
  53.         }
  54.       }
  55.     }

  56.     /* Restore ADC DMA transfer request after calibration */
  57.     LL_ADC_REG_SetDMATransfer(ADC1, backup_setting_adc_dma_transfer);

  58.     /* Delay between ADC end of calibration and ADC enable.                   */
  59.     /* Note: Variable divided by 2 to compensate partially                    */
  60.     /*       CPU processing cycles (depends on compilation optimization).     */
  61.     wait_loop_index = (ADC_DELAY_CALIB_ENABLE_CPU_CYCLES >> 1);
  62.     while(wait_loop_index != 0)
  63.     {
  64.       wait_loop_index--;
  65.     }

  66.     /* Enable ADC */
  67.     LL_ADC_Enable(ADC1);

  68.     /* Poll for ADC ready to convert */
  69.     Timeout = ADC_ENABLE_TIMEOUT_MS;

  70.     while (LL_ADC_IsActiveFlag_ADRDY(ADC1) == 0)
  71.     {
  72.       /* Check Systick counter flag to decrement the time-out value */
  73.       if (LL_SYSTICK_IsActiveCounterFlag())
  74.       {
  75.         if(Timeout-- == 0)
  76.         {
  77.                 return 0;
  78.         }
  79.       }
  80.     }
  81.     /* Note: ADC flag ADRDY is not cleared here to be able to check ADC       */
  82.     /*       status afterwards.                                               */
  83.     /*       This flag should be cleared at ADC Deactivation, before a new    */
  84.     /*       ADC activation, using function "LL_ADC_ClearFlag_ADRDY()".       */
  85.   }
  86.   return 1;
  87. }
复制代码

因为ADC配置的是软件触发的单次采样,所以还需要有手动开始和结束采样的函数。

使能ADC采样:

  1. uint8_t STM32ADC1SampleEnable(void)
  2. {
  3.     uint32_t Timeout = ADC_ENABLE_TIMEOUT_MS;
  4.     LL_DMA_EnableChannel(DMA1,LL_DMA_CHANNEL_4);            //先使能dma再使能adc,以防采样数据丢失
  5.     LL_ADC_Enable(ADC1);
  6.     Timeout = ADC_ENABLE_TIMEOUT_MS;
  7.     while(LL_ADC_IsActiveFlag_ADRDY(ADC1) != SET)
  8.     {
  9.           if(Timeout-- == 0)
  10.         {
  11.            LOG(1,"STM32ADC1SampleEnable ERROR!!!");
  12.                 return 0;
  13.         }
  14.     }
  15.     LL_ADC_REG_StartConversion(ADC1);
  16.     return 1;
  17. }
复制代码

失能ADC采样:

  1. uint8_t STM32ADC1SampleDisable(void)
  2. {
  3.     uint32_t Timeout = ADC_DISABLE_TIMEOUT_MS;
  4.     LL_ADC_REG_StopConversion(ADC1);
  5.     while(LL_ADC_REG_IsConversionOngoing(ADC1) != 0)
  6.     {
  7.         if(Timeout-- == 0)
  8.         {
  9.             LOG(1,"STM32ADC1SampleDisenable ERROR!!!");
  10.             return 0;
  11.         }
  12.     }
  13.     LL_ADC_Disable(ADC1);                            //先关闭adc再断开dma,以防采样数据丢失
  14.     LL_DMA_DisableChannel(DMA1,LL_DMA_CHANNEL_4);
  15.     return 1;
  16. }
复制代码

进行ADC数据采集流程(采用多次采样求平均值的方式):

1、当需要开始采样前,调用一次STM32ADC1SampleEnable()函数;

2、在一个定时函数内调用LL_ADC_REG_StartConversion(ADC1)进行数据的转换(因为使用的是单次采样,所以每次进入定时函数时都需要调用),取出DMA数据进行累加;

3、达到需要的采样次数之后,对得到的数据进行运算,并调用STM32ADC1SampleDisable()函数关闭ADC通道。

以上方式适用于需要间隔一段时间获取一次ADC数据时使用,例如需要每隔1分钟获取电池电压时,可以进行1分钟倒计时,然后连续进行十次间隔10ms的ADC采样求平均值。


收藏 评论0 发布时间:2021-11-12 23:01

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版