STM32F103的ADC测试

我使用的芯片为STM32F103C8T6,所以他的ADC有2组。可以从STM32的引脚表中得知,只有ADC的1和2。
其次,手册中有表格来说明接入ADC引脚的电压与电流以及频率的范围
在这里插入图片描述
我所测试的是12V的锂电池,所以需要电阻来分压。我设锂电池充满电的时候为13V(以防万一出现电压过高,损坏电路)。所以,分压出来的电压为:13/36*10= 3.61V。因为到不了13V,所以不会出现高于3.6V的情况。
在这里插入图片描述

V-BAT所接的地方为单片机的PA5的引脚。
话不多说,直接上代码。
ADC.h

#ifndef	_ADCPOWER_H_
#define _ADCPOWER_H_

#include "stm32f10x.h"

#define ADCPWOER GPIO_Pin_5

void ADC_Config(void);			//配置ADC1
u16 ADC1_Read(void);			//得到ADC1测到的值
u16 ADC1_ReadAverage(u8 count);	//得到ADC1测到的平均值

#endif

ADC.c

#include "ADCPower.h"

void ADC_Config(void)
{
	GPIO_InitTypeDef	GPIO_InitStruct;	//设置GPIO口结构体名称
	ADC_InitTypeDef		ADC_InitStruct;		//设置ADC结构体名称
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//使能GPIOA的外设时钟
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;				//设置GPIO_Mode为模拟输入
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;					//设置GPIO_Pin为GPIO_Pin_5
	//GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;		//因为是输入,则不需要设置GPIO_Speed
	GPIO_Init(GPIOA,&GPIO_InitStruct);						//以上面的设置初始化GPIOA口
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);		//使能ADC1的外设时钟
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);						//设置ADC1的时钟为PCLK/6		72M/6=14M	最大为14M
	ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;		//设置ADC模数转换为单次工作模式
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;		//设置ADC数据为右对齐
	ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//设置ADC转换由软件而不是外部触发启动
	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;			//设置ADC工作模式为ADC1 和 ADC2 工作在独立模式
	ADC_InitStruct.ADC_NbrOfChannel = 1;					//设置顺序进行规则转换的 ADC 通道的数目为1
	ADC_InitStruct.ADC_ScanConvMode = DISABLE;				//设置ADC模数转换单次工作	/ENABLE为扫描模式,多次
	ADC_Init(ADC1,&ADC_InitStruct);							//以上面的设置初始化ADC1
	ADC_Cmd(ADC1,ENABLE);									//使能ADC1
	
	ADC_ResetCalibration(ADC1);                  			//重置ADC1的校准寄存器
	while(ADC_GetResetCalibrationStatus(ADC1));  			//等待复位校准结束
	ADC_StartCalibration(ADC1);                  			//开启ADC1校准
	while(ADC_GetCalibrationStatus(ADC1));       			//等待校准结束
}

u16 ADC1_Read(void)											
{
	u16 value;												//定义一个无符号的16位变量
	ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_239Cycles5);
	//设置ADC1的通道5,设置它的转化顺序为1个和采样时间为239.5 周期。
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);					//使能ADC1软件启动注入组转换功能		
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));			//转换结束
	value = ADC_GetConversionValue(ADC1);					//返回得到的值
	return 	value;
}


u16 ADC1_ReadAverage(u8 count)								
{
	u32 Value_Sum = 0;
	u8 i;
	
	//累加读取到的数值	
	for(i = 0; i < count; i++)
	{
 
		Value_Sum += ADC1_Read();
	}
 
	//求出平均值并返回
	return Value_Sum/count;
}	

因为1lsb为VREF/4096,所以,得到的 ADC1_Read()需要乘以VREF再除以4096,所以main函数中,得到的值需要进行运算。
又因为VREF和VDD是接一起的,所以,VREF=VDD=3.3V

	 = ADC1_Read() * 3.3 / 4096/10 * 36
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值