MOS管搭配ADC实现电池电量的粗略估计

​​​​​​​按键配合LDO实现开关功能-CSDN博客 ​​​​​​

硬件回顾

上面这一期我给大家介绍了按键开关,这一期讲解一下这个简单的电池管理电路。

注意看我绿色画笔框住的地方,其中VBAT是电池的直接供电,3.3V是LDO的输出电源,AD_BAT连接单片机的ADC采集管脚。MOS管在这两个电压的作用下饱和导通,按照R34与R35的线性比例关系分压后将电压线性传递给ADC。此时用万用表实测0.78V。

软件介绍

下面开始介绍软件构思,计划用ADC的轮询方式采集电池余量。

步骤一:勾选对应的ADC管脚,其余保持默认(大家也可以根据实际情况调整ADC设置)后生成代码(注意分配给ADC的时钟频率尽量不要超频//32M)

步骤二:初始化使能ADC,编写采集函数

在生成的adc.c文件中编写采集函数

/* USER CODE BEGIN 1 */
//获得ADC值
//ch: 通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
//返回值:转换结果
uint16_t Get_AdcValue(ADC_HandleTypeDef* adcHandle,uint32_t ch)
{
  if(adcHandle->Instance==ADC1)                            //检查一下是否是ADC1
	{
	ADC_ChannelConfTypeDef ADC1_ChanConf;   
    ADC1_ChanConf.Channel=ch;                              //通道              
    ADC1_ChanConf.Rank=1;                                  //第1个序列,序列1    
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_1CYCLE_5;    //采样时间                 
    HAL_ADC_ConfigChannel(&hadc1,&ADC1_ChanConf);          //通道配置

    HAL_ADC_Start(&hadc1);	                               //开启ADC

    HAL_ADC_PollForConversion(&hadc1,10);	                 //轮询转换
	}
	 return (uint16_t)HAL_ADC_GetValue(&hadc1);              //返回最近一次ADC1规则组的转换结果
}

//获取指定通道的转换值,取times次,然后平均 
//times:获取次数
//返回值:通道ch的times次转换结果平均值
uint16_t Get_Adc_Average(uint32_t ch,uint8_t times)
{
	uint32_t temp_val=0;
	uint8_t t;
	for(t=0;t<times;t++)
	{
		temp_val+=Get_AdcValue(&hadc1,ch);
		delay_ms(5);
	}
	return temp_val/times;
} 
/* USER CODE END 1 */

在合适的地方选择初始化ADC,我放在了电源模块初始化那一层里面

void Power_Init()
{
	//开关IO管脚初始化
    GPIO_InitTypeDef GPIO_InitStruct;
	
	__HAL_RCC_GPIOC_CLK_ENABLE();
	
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET);
	
	GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
	
	//电池余量采集端ADC初始化
	HAL_ADC_MspInit(&hadc1);
}

步骤三:编写电量采集函数

uint16_t Battery_Check(void)
{
  static uint16_t adcx=0;
  static uint16_t Battery_Capacity=0;
  adcx=Get_Adc_Average(ADC_CHANNEL_2,5);
  if(adcx<800)
	{
		MODE3_ON;
		delay_ms(250);
	    MODE3_OFF;
		Battery_Capacity=0;   //电量不足LED灯自动频闪
	}else if(adcx>800)
	{
		MODE3_ON;
		Battery_Capacity=1;
	}
	return Battery_Capacity;
}

步骤四:打断点调试查看ADCX的值(前期开发可以引一路串口出来,我这边的板子同事画PCB的时候CH340的RX、TX接反了用不了,推荐大家看这篇博文学习使用Keil的Debug方式Keil软件仿真调试常用功能以及变量查询、引脚波形查询_如何用keil调试程序-CSDN博客

鼠标悬停在上面就能读出数值,有时候Keil会抽风,重新按Debug就好。加入窗口查看的变量必须是全局变量,这里我就不演示了。

读取数值adcx=0x03AF,换算为十进制是943,根据公式求出读取到的电压值,设该电压值为V。

stm32的十二位ADC最大模拟值4095,最大参考电压3.3V。

列式计算:V/943=3.3/4095

求出V=0.76v,与直接测量值0.78相比差0.02,也算在误差允许的范围内吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值