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

【经验分享】STM32L0系列之ADC采集

[复制链接]
STMCU小助手 发布时间:2021-11-15 22:02
STM32L0开发系列——01 ADC采集
前言
使用芯片:STM32L051C8T6
软件平台:KEIL V5、STM32CubeL0
库函数:HAL

一、原理图
本文介绍在STM32上使用ADC1的第1通道,对电池电量进行采集。

20190521154130328.png


二、ADC通道与引脚对应关系

_(KN]~}EBE`QX(}_V8}K%(1.png

}U8X{E0K8E$YC3O(VLM3]QH.png


三、ADC相关
1、 ADC 可由 APB 时钟或 HSI16 时钟提供。
2、 ADC 转换时间: 12 位分辨率对应的转换时间为 0.87 µs (1.14 MHz), 10 位分辨率
对应的转换时间为 0.81 µs,若降低分辨率,可进一步缩短转换时间。

四、实验步骤
1、系统时钟配置

  1. //******************************************************************************            
  2. //name:             SystemClock_Config           
  3. //introduce:               系统时钟配置        
  4. //parameter:        none  
  5. //return:           none         

  6. //changetime:       2019.05.21                     
  7. //******************************************************************************
  8. void SystemClock_Config(void)
  9. {

  10.   RCC_ClkInitTypeDef RCC_ClkInitStruct;
  11.   RCC_PeriphCLKInitTypeDef PeriphClkInit;
  12.   RCC_OscInitTypeDef RCC_OscInitStruct;

  13.   __PWR_CLK_ENABLE();

  14.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  15.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;

  16.         RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  17.   RCC_OscInitStruct.HSIState = RCC_HSI_ON; //ADC的时钟源
  18.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  19.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  20.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8;
  21.   RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
  22.   HAL_RCC_OscConfig(&RCC_OscInitStruct);

  23.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  24.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  25.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  26.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  27.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  28.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  29.   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);

  30.   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
  31.   PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
  32.   HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

  33.   __SYSCFG_CLK_ENABLE();

  34. }
复制代码

注意:一开始程序中没有配置HSI时钟,采集不到电压

2、ADC文件

  1. #include "main.h"

  2. ADC_HandleTypeDef hadc;
  3. GPIO_InitTypeDef GPIO_InitStruct;
  4. ADC_ChannelConfTypeDef sConfig;


  5. //******************************************************************************            
  6. //name:             ADC_Init           
  7. //introduce:               ADC初始化      
  8. //parameter:        none  
  9. //return:           none         

  10. //changetime:       2019.05.21                     
  11. //******************************************************************************
  12. void ADC_Init(void)
  13. {
  14.         uint32_t Calibration=0;
  15.         
  16.         __HAL_RCC_ADC1_CLK_ENABLE();
  17.         __HAL_RCC_GPIOB_CLK_ENABLE();
  18.         
  19.         GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
  20.         GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  21.         GPIO_InitStruct.Pull = GPIO_NOPULL;
  22.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  23.         
  24.         hadc.Instance = ADC1;
  25.   hadc.Init.OversamplingMode = DISABLE;
  26.   hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
  27.   hadc.Init.Resolution = ADC_RESOLUTION_12B;
  28.   hadc.Init.SamplingTime = ADC_SAMPLETIME_79CYCLES_5;
  29.   hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  30.   hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  31.   hadc.Init.ContinuousConvMode = DISABLE;
  32.   hadc.Init.DiscontinuousConvMode = DISABLE;
  33.   hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  34.   hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  35.   hadc.Init.DMAContinuousRequests = DISABLE;
  36.   hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  37.   hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  38.   hadc.Init.LowPowerAutoWait = DISABLE;
  39.   hadc.Init.LowPowerFrequencyMode = DISABLE;
  40.   hadc.Init.LowPowerAutoPowerOff = DISABLE;
  41.   HAL_ADC_Init(&hadc) ;
  42.         
  43.         //启动ADC校验功能
  44.         HAL_ADCEx_Calibration_Start(&hadc,ADC_SINGLE_ENDED);
  45.         //获取校验值
  46.         Calibration = HAL_ADC_GetValue(&hadc);
  47.         
  48.         // 清除之前通道
  49.         sConfig.Channel = ADC_CHANNEL_1|ADC_CHANNEL_2|ADC_CHANNEL_3;
  50.           sConfig.Rank = ADC_RANK_NONE;        // 清除通道属性
  51.         HAL_ADC_ConfigChannel(&hadc, &sConfig);

  52. }

  53. //******************************************************************************            
  54. //name:             GET_ADC           
  55. //introduce:               单通道采集ADC的值      
  56. //parameter:        CH:ADC采集通道
  57. //return:           ADC采集值         

  58. //changetime:       2019.05.21                     
  59. //******************************************************************************
  60. uint32_t GET_ADC(uint32_t CH)
  61. {
  62.         uint32_t adc_conv_var;
  63.         sConfig.Channel = CH;
  64.         sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;        // 设置通道
  65.         HAL_ADC_ConfigChannel(&hadc, &sConfig);

  66.         // 启动转换
  67.         HAL_ADC_Start(&hadc);
  68.         
  69.         // 等待转换结束
  70.         HAL_ADC_PollForConversion(&hadc,20);// 超时20ms
  71.         
  72.         // 读取结果
  73.         adc_conv_var = HAL_ADC_GetValue(&hadc);
  74.         
  75.         // 清除通道
  76.         sConfig.Rank = ADC_RANK_NONE;        // 清除通道
  77.         HAL_ADC_ConfigChannel(&hadc, &sConfig);
  78.         
  79.         return adc_conv_var;
  80. }

  81. //******************************************************************************            
  82. //name:             Get_Adc_Average         
  83. //introduce:               多次采集求平均值      
  84. //parameter:        CH:ADC采集通道
  85. //return:           ADC采集值         

  86. //changetime:       2019.05.21                     
  87. //******************************************************************************

  88. void Get_Adc_Average(uint32_t *ch,uint32_t *adcx,uint8_t times)
  89. {
  90.         uint32_t temp_val[9]={0};
  91.         uint8_t t,i;
  92.         for(t=0;t<times;t++)
  93.         {
  94.                 for(i=0;i<9;i++)
  95.                 {
  96.                         temp_val<i style="font-style: italic;">+=GET_ADC(ch);
  97.                  </i> HAL_Delay(5);
  98.                 }
  99.                
  100.         }
  101.         
  102.         for(i=0;i<9;i++)
  103.                 {
  104.                         adcx = temp_val/times;
  105.                 }

  106. }         
复制代码

3、main中测试
  1. while(1)
  2. {
  3.         BATTER_VALUE = GET_ADC(ADC_CHANNEL_1);
  4.         temp=(float)BATTER_VALUE*(3.3/4096)*2;        
  5.         printf("temp=%0.2f\r\n",temp);
  6.                         
  7.         HAL_Delay(100);
  8. }
复制代码


四、实验结果

由于ADC的精度是12bit(4096)、参考电压为3.3V,因此实际读出的电量值为BATTER_VALUE3.3/40962.
试验成功



20190521162423578.png
收藏 评论0 发布时间:2021-11-15 22:02

举报

0个回答

所属标签

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