stc8g1k08单片机,百分比battery_percent始终是3.3v电压对应的百分比,不是2.8v对应百分比,找了很久都没找到原因,通过串口打印v_bat的值,是正确的,就是百分比计算那一步出现问题。
#define _ADC_C
#include "ADC.h"
#include "config.h"
#include "Uart.h"
#include "string.h"
#include "Battery.h"
#define ADC_RES_MAX 1024 // ADC采样最大值
#define V_REF (3.3) // 参考电压为3.3V
#define V_BAT_MAX (2.8) // 电池最大电压为2.8V
#define V_BAT_MIN (1.8) // 电池最小电压为1.8V
#define V_BAT_WARN (2.1) // 电池电量过低警告阈值为2.1V
unsigned int ADC_Value; // 定义全局变量,用于存储采样结果
unsigned char cnt = 0; //
unsigned int AdcBuff[] = {0,0,0,0,0,0,0,0,0,0}; //实时采集的adc值
unsigned int CpBuff[] = {0,0,0,0,0,0,0,0,0,0};
extern unsigned int cnt5s;
extern unsigned int inserttime;
void ADC_Init()
{
P_SW2 |= 0x80;
ADCTIM = 0x2A; //设置 ADC 内部时序
P_SW2 &= 0x7f;
ADCCFG = 0x20; //设置 ADC 时钟为系统时钟/2,右对齐
ADC_CONTR = 0x80; //使能 ADC 模块
}
void ADC_ISR() interrupt 5
{
ADC_Value = (unsigned int)(ADC_RES << 8) + (unsigned int)ADC_RESL;
if(cnt < 10)
{
AdcBuff[cnt] = ADC_Value;
cnt++;
}
ADC_CONTR &= ~0x20; //中断标志位清0
if(cnt == 10)
{
cnt = 0;
}
}
void Delay1ms(void)
{
unsigned char data i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
void ADC_BATTERY()
{
static float up_percent = 100.0; //用于保存上一次的百分比值
unsigned int i=0,j=0,t=0;
// unsigned char battery_percent = 0; // 定义电量百分比变量
float adc_res,battery_percent,ave;
float v_bat;
ADC_CONTR &= 0xf0; //底四位清零
ADC_CONTR |= 0x0C; //置通道12
ADC_CONTR |= 0x40; // 启动ADC转换
Delay1ms();
for(i=0;i<10;i++) //将AdcBuff值存到CpBuff,防止中断导致buffer值变化
{
CpBuff[i] = AdcBuff[i];
}
i = 0;
for(j=0;j<9;j++) //将数组由小到大排序
for(i=0;i<9-j;i++)
if(CpBuff[i]>CpBuff[i+1])
{
t=CpBuff[i];
CpBuff[i] = CpBuff[i+1];
CpBuff[i+1] = t;
}
ave = ((CpBuff[3] + CpBuff[4] + CpBuff[5] + CpBuff[6]) / 4); //adc范围658-1024
if(ave>600 && ave <= 1024)
{
adc_res = (float)ave * V_REF / ADC_RES_MAX;// 计算ADC被转换通道的输入电压,采集电压范围2.12-3.3
v_bat = adc_res * V_BAT_MAX / V_REF;// 计算电池电压值,电池电压范围1.8-2.8
if(v_bat > 2.8)
v_bat = 2.8;
if(v_bat < 1.8)
v_bat = 1.8;
battery_percent =((v_bat - 1.8) * 100) ;// 计算电池电量百分比
UartSend(battery_percent);