STM32L0系列之ADC采集

STM32L0开发系列——01 ADC采集

前言

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

一、原理图

本文介绍在STM32上使用ADC1的第1通道,对电池电量进行采集。
在这里插入图片描述

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

通道引脚
PA0ADC_IN0
PA1ADC_IN1
PA2ADC_IN2
PA3ADC_IN3
PA4ADC_IN4
PA5ADC_IN5
PA6ADC_IN6
PA7ADC_IN7
PB0ADC_IN8
PB1ADC_IN9
PC0ADC_IN10
PC1ADC_IN11
PC2ADC_IN12
PC3ADC_IN13
PC4ADC_IN14
PC5ADC_IN15
PC5ADC_IN15
PC5ADC_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.2f\r\n",temp);
			
	HAL_Delay(100);
}

四、实验结果

在这里插入图片描述
由于ADC的精度是12bit(4096)、参考电压为3.3V,因此实际读出的电量值为BATTER_VALUE3.3/40962.

试验成功

  • 7
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值