应广单片机有很实用的功能,就是可以用内部的分压电阻,内部1.2v参考电压,和比较器一起,测试单片机VDD电压.厉害吧,不使用任何外部器件,测试供电的电源电压.!当电池低压的时候可以做相应的动作.比如休眠,进入低功耗等.不多说,上代码! 记得有问题可以联系我!
这个代码结构结构不是很好,布置一个作业,理解之后自己修改去.哈哈!仿真之后查看ucVolt就可以知道电源电压是多少.虽然不精确,但够用.
#include "extern.h"
#define f_Com !p_Com_Out
BIT p_Com_Out : gpcc.6;
BIT f_getBat;
BYTE ucVolt;
WORD usTmp;
bit FLAG_NMS;
byte count;
word T16COUNTER;
/* 子程序 */
void Tmr16InterInit ( void )
{
/*计数值清零*/
T16COUNTER =488;
/*ms标记reset*/
FLAG_NMS =0;
/*使能定时器*/
$ INTEN T16;
/*关中断*/
INTRQ = 0;
/*停止定时器*/
T16M.5 =0;
STT16 T16COUNTER;
/*计算方法16M/*/
$ T16M IHRC,/1,BIT11; /*全局中断开启*/
}
/*比较器初始化*/
void InitCompare ( void )
{
/*b7@1=开启比较器
b6@0=负输入大于正输入
b5@0=比较器不用tm2_ck采样
b4@0=比较结果没有极性相反
b3:1@ 010=内部Band-gap电压
b0@1=PA4输入0=内部电阻输入*/
gpcc=0b1_0_0_0_010_0;
//$ padier 0b111_0_100_1;
/*
b7@0=不输出到PA0
b6@0保留
b5@0=高R
b4@0=低R
b3:0@0000-1111内部r值
*/
gpcs=0B0_0_0_0_0000;
}
void GetBat ( void )
{
/*设置模式 2-6,检测3.2V*/
gpcs=0B0_0_10_0110;
.delay 10;
if ( f_Com )
{
/*电压低于3.2V,执行关机*/
ucVolt=10;
f_getBat=0;
PA=0B0001_0000;
}
else
{
f_getBat=1;
PA=0B0010_0000;
}
}
#if 1
/*取得结果*/
void GetComRes ( void )
{
if (f_getBat)
{
f_getBat=0;
/*设置模式 1-10,检测2.6V*/
gpcs=0B0001_1010;
.delay 10;
if ( f_Com )
{
/*电压低于2.6V*/
ucVolt=25;
}
else
{
/*设置模式 2-8,检测2.8V*/
gpcs=0B0_0_10_1000;
.delay 10;
if ( f_Com )
{
/*电压低于2.8V*/
ucVolt=27;
}
else
{
/*设置模式 2-7,检测3.0V*/
gpcs=0B0_0_10_0111;
.delay 10;
if ( f_Com )
{
/*电压低于3.0V*/
ucVolt=29;
}
else
{
/*设置模式 2-6,检测3.2V*/
gpcs=0B0_0_10_0110;
.delay 10;
if ( f_Com )
{
/*电压低于3.2V*/
ucVolt=31;
}
else
{
/*设置模式 2-5,检测3.4V*/
gpcs=0B0_0_10_0101;
.delay 10;
if ( f_Com )
{
/*电压低于3.4V*/
ucVolt=33;
}
else
{
/*设置模式 1-7,检测3.6V*/
gpcs=0B0_0_01_0111;
.delay 10;
if ( f_Com )
{
/*电压低于3.6V*/
ucVolt=35;
}
else
{
/*设置模式 3-9,检测3.8V*/
gpcs=0B0_0_11_1001;
.delay 10;
if ( f_Com )
{
/*电压低于3.8V*/
ucVolt=37;
}
else
{
/*设置模式 2-3,检测4.0V*/
gpcs=0B0_0_10_0011;
.delay 10;
if ( f_Com )
{
/*电压低于4.0V*/
ucVolt=39;
}
else
{
/*设置模式 3-8,检测4.2V*/
gpcs=0B0_0_11_1000;
.delay 10;
if ( f_Com )
{
/*电压低于4.2V*/
ucVolt=41;
}
else
{
/*设置模式 2-2,检测4.4V*/
gpcs=0B0_0_10_0010;
.delay 10;
if ( f_Com )
{
/*电压低于4.4V*/
ucVolt=43;
}
else
{
/*设置模式 2-1,检测4.8V*/
gpcs=0B0_0_10_0001;
.delay 10;
if ( f_Com )
{
/*电压低于4.8V*/
ucVolt=47;
}
else
{
/*电压高于4.8V*/
ucVolt=50;
}
}
}
}
}
}
}
}
}
}
}
}
}
#endif
void FPPA0 ( void )
{
/*使用这一行就可以看到测试出来电压ucVolt为33*/
// .ADJUST_IC SYSCLK=IHRC/8, IHRC=16MHz, VDD=3.3v;
/*使用这一行就可以看到测试出来电压ucVolt为41*/
.ADJUST_IC SYSCLK=IHRC/8, IHRC=16MHz, VDD=4.0v;
Tmr16InterInit();
InitCompare();
/* delay 200x2000x0.5us=0.2s */
usTmp=200;
while(usTmp--)
{
.delay 2000;
wdreset; //复位看门狗定时器
}
GetBat ();
engint;
while ( 1 )
{
GetComRes();
}
}
void Interrupt ( void )
{
pushaf;
if ( Intrq.T16 )
{
Intrq.T16 = 0;
STT16 T16COUNTER;
if ( count>0 )
{
count--;
}
else
{
count = 9;
/*1ms*/
//FLAG_NMS= 1;
f_getBat=1;
}
}
popaf;
}
/*QQ:85547259*/