stm32ADC的使用说明

参考:

https://blog.csdn.net/qq237155875/article/details/84618096?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

https://blog.csdn.net/qq_36075612/article/details/102953750?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

 

mcu型号:stm32l0系列,

采样通道:采样ADC_CHANNEL_1和ADC_CHANNEL_VREFINT多个通道,后者在电源电压变化时,比如电池供电,准确测量当前采样通道ADC_CHANNEL_xxx电压时会用到。

1.初始化配置项说明:

ADC_ChannelConfTypeDef sConfig = {0};

以下列代码为例进行说明:
    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
    */
  hadc.Instance = ADC1;                     
  hadc.Init.OversamplingMode = DISABLE;                      
//过采样是否使能
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;   //ADC采用同步时钟PCLK分频系数
  hadc.Init.Resolution = ADC_RESOLUTION_12B;                      //12位转换
  hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;  //采样时间
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; 
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerFrequencyMode = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }

 /** Configure for the selected ADC regular channel to be converted. 
  */
  sConfig.Channel = ADC_CHANNEL_1;   //Ñ¡ÔñͨµÀ
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel to be converted. 
  */
  sConfig.Channel = ADC_CHANNEL_VREFINT;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

这里注意说明几个需要解释的配置:

1)ScanConvMode :对应操作ADC_CFGR1寄存器 SCANDIR位,用于在我们使用多通道采样时,同来配置扫描顺序,比如使用了通道1、通道2、通道4,是用来配置1-2-4的采样顺序还是4-2-1的采样顺序。这里我们举例ADC_SCAN_DIRECTION_FORWARD,即采样顺序由小到大来说明。

2)下面的ContinuousConvMode和DiscontinuousConvMode需要放在一起讲:

ContinuousConvMode :对应操作ADC_CFGR1寄存器 CONT位,使能表示其置1。
DiscontinuousConvMode :对应ADC_CFGR1 寄存器中的 DISCEN 位,使能表示其置1

当CONT =0,DISCEN =0时,当我们调用一次HAL_ADC_Start(&hadc)开启ADC转换后,那么实际上你使用的通道1,2,4都会依次自动进行AD采样,每次AD转换结束会EOC置1。注意你这里只开启了一次ADC,但实际上根据你使用的n个通道,进行了n次AD转换。所有通道AD转换1轮结束后结束。

当CONT =0,DISCEN =1时,那么当我们调用一次HAL_ADC_Start(&hadc)开启ADC转换后,会对通道1进行AD采样,并在AD转换结束会EOC置1。如果你想获得下个信道2的值,需要再开启一次ADC转换(再调用一次HAL_ADC_Start(&hadc))。即每开启一次ADC,执行一次通道转换。开启ADC->转换通道1->开启ADC->转换通道2->开启ADC->转换通道4->开启ADC->转换通道1->开启ADC->转换通道2....顺序执行,这种方式我们如果轮训接收的话,优点是不会错过对应的通道采集数据。

当CONT =1,DISCEN =0时,,当我们调用一次HAL_ADC_Start(&hadc)开启ADC转换后,那么实际上你使用的通道1,2,4都会依次自动进行AD采样,并且所有通道AD转换1轮后会继续下一轮转换。

CONT =1,DISCEN =1参考手册明确说明不支持这么操作。

3)LowPowerAutoWait和LowPowerAutoPowerOff:这两个使能后都是可以实现降低功耗的配置,LowPowerAutoWait配置的是ADC_CFGR1 寄存器中的 WAIT位,置 1,则仅当之前的数据已进行处理、 ADC_DR 寄存器已读取或者 EOC 位已清零后,才会开始新的转换。比如CONT =0或1,DISCEN =0,我们开启ADC转换后不是各个通道会自动转换嘛,我们可以将该位使能,那么只有当我们读取ADC_DR 寄存器即一个通道的数据后,才会自动采样下一个通道,这样,如果我们的代码是轮训,就不怕错过哪个信道采样了我们没来的及读取导致无法确定当前采样到底是哪个通道的数据了。

LowPowerAutoPowerOff:也称为自动关闭模式,将 ADC_CFGR1 寄存器中的 AUTOFF位置 1 可使能此模式。使能后,当ADC未进行转换时,会自动关闭ADC,实现降低功耗的目的。并且,当我们重新开始采集时,并不会将采集通道的顺序进行复位。比如说我们通道1-2-4,刚采集了1通道,再次开启后,会从2采集,再次开启,会采集4.而不是复位到1重新开始。
 

下面两种示例均可实现依次获取AD通道的数据。

代码:CONT =0,DISCEN =1时代码示例如下:

初始化:

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC_Init 1 */

  /* USER CODE END ADC_Init 1 */
  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
  */
  hadc.Instance = ADC1;
  hadc.Init.OversamplingMode = DISABLE;
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.SamplingTime = ADC_SAMPLETIME_79CYCLES_5;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;            
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ContinuousConvMode = DISABLE;//DISABLE;              
  hadc.Init.DiscontinuousConvMode = ENABLE;//ENABLE;// DISABLE;//        
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc.Init.LowPowerAutoWait = ENABLE;//DISABLE; 
  hadc.Init.LowPowerFrequencyMode = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = ENABLE;  
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel to be converted. 
  */
  sConfig.Channel = ADC_CHANNEL_1;   //Ñ¡ÔñͨµÀ
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel to be converted. 
  */
  sConfig.Channel = ADC_CHANNEL_VREFINT;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

轮询:

u8 data[10] ={1,2,6,0,0,0,7};

 HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED);  //校准
  while (1)
  {
//    /* USER CODE END WHILE */
    HAL_ADC_Start(&hadc);
    u8 ret = HAL_ADC_PollForConversion(&hadc, 100);   //等待转换完毕
    if(HAL_OK == ret){
        u16 num = HAL_ADC_GetValue(&hadc);   //依次获得通道1和参考电压通道的值
        data[3] = num>>8&0xff;
        data[4] = num&0xff;
        data[5] = tmp++;
        HAL_UART_Transmit(&huart2, data, 6, 2000);
    }
}

代码:

CONT =1,DISCEN =0时,示例代码:

  hadc.Init.LowPowerAutoWait = ENABLE;
  hadc.Init.LowPowerFrequencyMode = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = ENABLE;  

轮询:

  HAL_ADC_Start(&hadc);   //只需要开启一次
  while (1)
  {
   /* USER CODE END WHILE */
    u8 ret = HAL_ADC_PollForConversion(&hadc, 100);
    if(HAL_OK == ret){
        u16 num = HAL_ADC_GetValue(&hadc);  //自动等待使能,只有读取后才会开启下一通道采集
        data[3] = num>>8&0xff;
        data[4] = num&0xff;
        data[5] = tmp++;
        HAL_UART_Transmit(&huart2, data, 6, 2000);
    }

}

 

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32ADC校准是指对STM32系列中的模数转换器(ADC)进行校准操作。校准操作是为了确保ADC的准确性和稳定性,在使用ADC进行数据采集时,可以得到更准确的结果。 根据引用中提到的内容,STM32系列中的一些MCU支持额外的校准模式,如共模校准和差分共模校准。这些模式可以在使用校准函数HAL_ADCEx_Calibration_Start时通过额外的参数进行选择。 根据引用中的说明ADC校准是指通过对ADC的某些参数进行调整,来消除ADC的误差。ADC校准可以提高ADC的准确性和稳定性,特别是在精密测量和控制应用中非常重要。 在STM32中,使用HAL库的校准函数可以进行ADC的校准操作。根据引用中的描述,调用HAL ADC校准函数可能会遇到问题。为了解决这个问题,需要参考相关文档和资料,查找正确的调用方法和参数设置。 综上所述,STM32ADC校准是对STM32系列中的ADC进行准确性校正的操作,可以通过HAL库提供的校准函数进行调用。具体的校准方法和参数设置,可以根据具体的芯片型号和应用需求来选择和配置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [STM32L0 ADC使用HAL库关于校准问题的说明](https://blog.csdn.net/weixin_42328389/article/details/129518720)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值