#include <reg52.h>
#include <stdio.h>
#define REF_VOL 3.3 // 参考电压
#define ADC_RES 4096 // ADC分辨率
#define BAT_PIN P1_0 // 电池电压检测引脚
#define LCD_PIN P2 // LCD引脚
sbit RS = P3^5; // LCD命令/数据选择引脚
sbit EN = P3^6; // LCD使能引脚
void delay_ms(unsigned int ms)
{
unsigned int i, j;
for(i=0; i<ms; i++)
for(j=0; j<110; j++);
}
void lcd_write_cmd(unsigned char cmd)
{
RS = 0; // RS为0表示写命令
LCD_PIN = cmd;
EN = 1;
delay_ms(1);
EN = 0;
}
void lcd_write_data(unsigned char dat)
{
RS = 1; // RS为1表示写数据
LCD_PIN = dat;
EN = 1;
delay_ms(1);
EN = 0;
}
void lcd_init()
{
lcd_write_cmd(0x38); // 设置16x2显示,5x7点阵,8位数据接口
lcd_write_cmd(0x0c); // 打开显示,关闭光标
lcd_write_cmd(0x06); // 设置字符输入模式,光标右移不移屏
lcd_write_cmd(0x01); // 清屏
}
void adc_init()
{
P1ASF = 0x01; // P1.0作为模拟输入
ADC_RES = 4096; // 设置ADC分辨率为12位
}
unsigned int adc_read()
{
unsigned int adc_val;
ADC_CONTR = 0x84; // 启动ADC转换,并设置采样时间
while(!(ADC_CONTR & 0x10)); // 等待转换完成
adc_val = ADC_RES;
adc_val |= (unsigned int)ADC_RESL; // 获取转换结果
return adc_val;
}
void main()
{
unsigned int adc_val, bat_vol;
float bat_per;
char buf[16];
adc_init();
lcd_init();
while(1)
{
adc_val = adc_read();
bat_vol = (unsigned int)((float)adc_val / ADC_RES * REF_VOL * 1000);
bat_per = (float)(bat_vol - 3100) / (4200 - 3100) * 100;
if(bat_per > 100) bat_per = 100;
sprintf(buf, "Battery: %.1f%%", bat_per);
lcd_write_cmd(0x80); // 第一行显示
for(i=0; i<16; i++)
lcd_write_data(buf[i]);
delay_ms(1000); // 每隔1秒更新一次显示
}
}
c51电池电量显示
最新推荐文章于 2024-06-27 08:04:55 发布