这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 嵌入式开发» STM32» STM32L0系列之ADC采集

共1条 1/1 1 跳转至

STM32L0系列之ADC采集

院士
2023-05-26 23:23:50 打赏
STM32L0开发系列——01 ADC采集
前言
使用芯片:STM32L051C8T6
软件平台:KEIL V5、STM32CubeL0
库函数:HAL

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

st-img

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

st-img
st-img

三、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. __HAL_RCC_ADC1_CLK_ENABLE();

  16. __HAL_RCC_GPIOB_CLK_ENABLE();


  17. GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;

  18. GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;

  19. GPIO_InitStruct.Pull = GPIO_NOPULL;

  20. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


  21. hadc.Instance = ADC1;

  22. hadc.Init.OversamplingMode = DISABLE;

  23. hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;

  24. hadc.Init.Resolution = ADC_RESOLUTION_12B;

  25. hadc.Init.SamplingTime = ADC_SAMPLETIME_79CYCLES_5;

  26. hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;

  27. hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;

  28. hadc.Init.ContinuousConvMode = DISABLE;

  29. hadc.Init.DiscontinuousConvMode = DISABLE;

  30. hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

  31. hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;

  32. hadc.Init.DMAContinuousRequests = DISABLE;

  33. hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;

  34. hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;

  35. hadc.Init.LowPowerAutoWait = DISABLE;

  36. hadc.Init.LowPowerFrequencyMode = DISABLE;

  37. hadc.Init.LowPowerAutoPowerOff = DISABLE;

  38. HAL_ADC_Init(&hadc) ;


  39. //启动ADC校验功能

  40. HAL_ADCEx_Calibration_Start(&hadc,ADC_SINGLE_ENDED);

  41. //获取校验值

  42. Calibration = HAL_ADC_GetValue(&hadc);


  43. // 清除之前通道

  44. sConfig.Channel = ADC_CHANNEL_1|ADC_CHANNEL_2|ADC_CHANNEL_3;

  45. sConfig.Rank = ADC_RANK_NONE; // 清除通道属性

  46. HAL_ADC_ConfigChannel(&hadc, &sConfig);


  47. }


  48. //******************************************************************************

  49. //name: GET_ADC

  50. //introduce: 单通道采集ADC的值

  51. //parameter: CH:ADC采集通道

  52. //return: ADC采集值


  53. //changetime: 2019.05.21

  54. //******************************************************************************

  55. uint32_t GET_ADC(uint32_t CH)

  56. {

  57. uint32_t adc_conv_var;

  58. sConfig.Channel = CH;

  59. sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; // 设置通道

  60. HAL_ADC_ConfigChannel(&hadc, &sConfig);


  61. // 启动转换

  62. HAL_ADC_Start(&hadc);


  63. // 等待转换结束

  64. HAL_ADC_PollForConversion(&hadc,20);// 超时20ms


  65. // 读取结果

  66. adc_conv_var = HAL_ADC_GetValue(&hadc);


  67. // 清除通道

  68. sConfig.Rank = ADC_RANK_NONE; // 清除通道

  69. HAL_ADC_ConfigChannel(&hadc, &sConfig);


  70. return adc_conv_var;

  71. }


  72. //******************************************************************************

  73. //name: Get_Adc_Average

  74. //introduce: 多次采集求平均值

  75. //parameter: CH:ADC采集通道

  76. //return: ADC采集值


  77. //changetime: 2019.05.21

  78. //******************************************************************************


  79. void Get_Adc_Average(uint32_t *ch,uint32_t *adcx,uint8_t times)

  80. {

  81. uint32_t temp_val[9]={0};

  82. uint8_t t,i;

  83. for(t=0;t

  84. {

  85. for(i=0;i<9;i++)

  86. {

  87. temp_val+=GET_ADC(ch);

  88. HAL_Delay(5);

  89. }


  90. }


  91. for(i=0;i<9;i++)

  92. {

  93. adcx = temp_val/times;

  94. }


  95. }


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. HAL_Delay(100);

  7. }


四、实验结果

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


20190521162423578.png




共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]