首页 > 编程知识 正文

stm32通过adc采集电压值,stm32多路adc采集

时间:2023-05-06 01:05:01 阅读:194041 作者:1235

STM32L0开发系列——01 ADC采集 前言

使用芯片:STM32L051C8T6
软件平台:KEIL V5、STM32CubeL0
库函数:HAL

一、原理图

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

二、ADC通道与引脚对应关系 通道引脚PA0ADC_IN0PA1ADC_IN1PA2ADC_IN2PA3ADC_IN3PA4ADC_IN4PA5ADC_IN5PA6ADC_IN6PA7ADC_IN7PB0ADC_IN8PB1ADC_IN9PC0ADC_IN10PC1ADC_IN11PC2ADC_IN12PC3ADC_IN13PC4ADC_IN14PC5ADC_IN15PC5ADC_IN15PC5ADC_IN15内部温度传感器 (VSENSE)ADC_IN16内部参考电压 (VREFINT)ADC_IN17监视外部 VLCD 电源针脚ADC_IN18三、ADC相关

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

四、实验步骤

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<times;t++){for(i=0;i<9;i++){temp_val[i]+=GET_ADC(ch[i]); HAL_Delay(5);}}for(i=0;i<9;i++){adcx[i] = temp_val[i]/times;}}

3、main中测试

while(1){BATTER_VALUE = GET_ADC(ADC_CHANNEL_1);temp=(float)BATTER_VALUE*(3.3/4096)*2;printf("temp=%0.2frn",temp);HAL_Delay(100);} 四、实验结果


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

试验成功

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。