【STM32平衡小车】通过ADC获取电池电压
【摘要】
一、前言
一般航模电池的电量是和电压相关的, 过放必然导致电池永久过放,所以我们有必要通过监控电池电压的变化, 近似表示电池的电量, 在电池电量比较低的情况下, 提醒我们充电。
3S 满电的时候是 1...
一、前言
一般航模电池的电量是和电压相关的, 过放必然导致电池永久过放,所以我们有必要通过监控电池电压的变化, 近似表示电池的电量, 在电池电量比较低的情况下, 提醒我们充电。
3S 满电的时候是 12.6V, 过放时电压低于 9.6V。
2S 满电的时候是 8.4 V , 过放时电压低于 7.4V。
原理图如下
简单分析可知, 电池电压经过电阻分压, 衰竭为原来的 1/11 之后, 送单片机 ADC 检测, 以 12 位 ADC 的 STM32 举例, Get_Battery 为ADC 采集的变量, 那么很容易计算得到电池的电量为:
Battery_Voltage = Get_Battery * 3.3 * 11 / 4096(单位: V)
二、代码
adc.c
#include "adc.h"
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
//PA4 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
}
u16 Get_Adc(u8 ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}
int Get_battery_volt(void)
{
int Volt;//电池电压
Volt=Get_Adc(Battery_Ch)*3.3*11*100/4096; //电阻分压,具体根据原理图简单分析可以得到
if(Volt>1260)Volt=1260;
return Volt;
}
adc.h
#ifndef _ADC_H
#define _ADC_H
#include "config.h"
#define Battery_Ch 4
void Adc_Init(void);
u16 Get_Adc(u8 ch);
int Get_battery_volt(void);
#endif
文章来源: recclay.blog.csdn.net,作者:ReCclay,版权归原作者所有,如需转载,请联系作者。
原文链接:recclay.blog.csdn.net/article/details/83211431
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)