STM32L0开发系列——01 ADC采集
前言
一、原理图
二、ADC通道与引脚对应关系
| 通道 | 引脚 |
|---|---|
| PA0 | ADC_IN0 |
| PA1 | ADC_IN1 |
| PA2 | ADC_IN2 |
| PA3 | ADC_IN3 |
| PA4 | ADC_IN4 |
| PA5 | ADC_IN5 |
| PA6 | ADC_IN6 |
| PA7 | ADC_IN7 |
| PB0 | ADC_IN8 |
| PB1 | ADC_IN9 |
| PC0 | ADC_IN10 |
| PC1 | ADC_IN11 |
| PC2 | ADC_IN12 |
| PC3 | ADC_IN13 |
| PC4 | ADC_IN14 |
| PC5 | ADC_IN15 |
| PC5 | ADC_IN15 |
| PC5 | ADC_IN15 |
| 内部温度传感器 (VSENSE) | ADC_IN16 |
| 内部参考电压 (VREFINT) | ADC_IN17 |
| 监视外部 VLCD 电源针脚 | ADC_IN18 |
三、ADC相关
四、实验步骤
1、系统时钟配置
// //name: SystemClock_Config //introduce: 系统时钟配置 //parameter: none //return: none //changetime: 2019.05.21 // void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInit; RCC_OscInitTypeDef RCC_OscInitStruct; __PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSIState = RCC_HSI_ON; //ADC的时钟源 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1; PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); __SYSCFG_CLK_ENABLE(); }
注意:一开始程序中没有配置HSI时钟,采集不到电压
2、ADC文件
#include "main.h" ADC_HandleTypeDef hadc; GPIO_InitTypeDef GPIO_InitStruct; ADC_ChannelConfTypeDef sConfig; // //name: ADC_Init //introduce: ADC初始化 //parameter: none //return: none //changetime: 2019.05.21 // void ADC_Init(void) { uint32_t Calibration=0; __HAL_RCC_ADC1_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); hadc.Instance = ADC1; hadc.Init.OversamplingMode = DISABLE; hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_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; 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_SEQ_CONV; hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED; hadc.Init.LowPowerAutoWait = DISABLE; hadc.Init.LowPowerFrequencyMode = DISABLE; hadc.Init.LowPowerAutoPowerOff = DISABLE; HAL_ADC_Init(&hadc) ; //启动ADC校验功能 HAL_ADCEx_Calibration_Start(&hadc,ADC_SINGLE_ENDED); //获取校验值 Calibration = HAL_ADC_GetValue(&hadc); // 清除之前通道 sConfig.Channel = ADC_CHANNEL_1|ADC_CHANNEL_2|ADC_CHANNEL_3; sConfig.Rank = ADC_RANK_NONE; // 清除通道属性 HAL_ADC_ConfigChannel(&hadc, &sConfig); } // //name: GET_ADC //introduce: 单通道采集ADC的值 //parameter: CH:ADC采集通道 //return: ADC采集值 //changetime: 2019.05.21 // uint32_t GET_ADC(uint32_t CH) { uint32_t adc_conv_var; sConfig.Channel = CH; sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; // 设置通道 HAL_ADC_ConfigChannel(&hadc, &sConfig); // 启动转换 HAL_ADC_Start(&hadc); // 等待转换结束 HAL_ADC_PollForConversion(&hadc,20);// 超时20ms // 读取结果 adc_conv_var = HAL_ADC_GetValue(&hadc); // 清除通道 sConfig.Rank = ADC_RANK_NONE; // 清除通道 HAL_ADC_ConfigChannel(&hadc, &sConfig); return adc_conv_var; } // //name: Get_Adc_Average //introduce: 多次采集求平均值 //parameter: CH:ADC采集通道 //return: ADC采集值 //changetime: 2019.05.21 // void Get_Adc_Average(uint32_t *ch,uint32_t *adcx,uint8_t times) { uint32_t temp_val[9]={0}; uint8_t t,i; for(t=0;t
3、main中测试
while(1) { BATTER_VALUE = GET_ADC(ADC_CHANNEL_1); temp=(float)BATTER_VALUE*(3.3/4096)*2; printf("temp=%0.2f\r\n",temp); HAL_Delay(100); }
四、实验结果

由于ADC的精度是12bit(4096)、参考电压为3.3V,因此实际读出的电量值为BATTER_VALUE3.3/40962.
试验成功
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216989.html原文链接:https://javaforall.net
