按键配合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=0.76v,与直接测量值0.78相比差0.02,也算在误差允许的范围内吧。