說明:
????ADC的第9通道是用來測試內部的帶隙電壓的,由于內部帶隙電壓很穩(wěn)定,不會隨芯片的工作電壓的改變而變化,所以可以通過測量帶隙電壓,然后通過ADC的值便可反推出VCC的電壓,從而用戶可以實現(xiàn)自己的低壓檢測功能。
????ADC的第9通道的測量方法:首先將P1ASF初始化為0,即關閉所有P1口的模擬功能然后通過正常的ADC轉換的方法讀取第0通道的值,即可通過ADC的第9通道讀取當前帶隙電壓值。
????用戶實現(xiàn)自己的低壓檢測功能的實現(xiàn)方法:首先用戶需要在VCC很精準的情況下(比如5.0V),測量出帶隙電壓的ADC轉換值(比如為BGV5),并這個值保存到EEPROM中,然后在低壓檢測的代碼中,在實際VCC變化后,所測量出的帶隙電壓的ADC轉換值(比如為BGVx),通過計算公式:?實際VCC?=?5.0V?*?BGV5?/?BGVx?,即可計算出實際的VCC電壓值,需要注意的是,第一步的BGV5的基準測量一定要精確。
(例如:美國Analog Devices公司的【AD780】是一款獨立的超高精度帶隙基準電壓源,可以利用4.0 V至36 V的輸入提供2.5 V或3.0 V輸出。它具有低初始誤差、低溫度漂移和低輸出噪聲。)
百度百科關于《帶隙》解釋:
帶隙基本概況
帶隙:導帶的最低點和價帶的最高點的能量之差。也稱能隙。
帶隙越大,電子由價帶被激發(fā)到導帶越難,本征載流子濃度就越低,電導率也就越低。
帶隙主要作為帶隙基準的簡稱,帶隙基準是所有基準電壓中最受歡迎的一種,由于其具有與電源電壓、工藝、溫度變化幾乎無關的突出優(yōu)點,所以被廣泛地應用于高精度的比較器、A/D或D/A轉換器、LDO穩(wěn)壓器以及其他許多模擬集成電路中。
帶隙的主要作用是在集成電路中提供穩(wěn)定的參考電壓或參考電流,這就要求基準對電源電壓的變化和溫度的變化不敏感。
Bandgap voltage
reference,常常有人簡單地稱它為Bandgap。是利用一個與溫度成正比的電壓與二極管壓降之和,二者溫度系數(shù)相互抵消,實現(xiàn)與溫度無關的電壓基準。因為其基準電壓與硅的帶隙電壓差不多,因而稱為帶隙基準。實際上利用的不是帶隙電壓?,F(xiàn)在有些Bandgap結構輸出電壓與帶隙電壓也不一致。
同時可見:STC-ISP軟件中的【重要說明】
固件版本在7.1.2及以上版本的STC15系列芯片(STC15F104E和STC15F204EA除外)
的RAM和ROM空間中都包含有一些附加信息,地址分配如下:
ROM信息:
內部BandGap電壓值(毫伏,高字節(jié)在前)(2字節(jié))
例如: STC15F104W 4K程序空間 地址為0FF7H-0FF8H
STC15F2K60S2 60K程序空間 地址為EFF7H-EFF8H
RAM信息:
內部BandGap電壓值(毫伏,高字節(jié)在前)(2字節(jié))
例如: STC15F104W 128字節(jié)RAM 地址為06FH-070H
STC15F2K60S2 256字節(jié)RAM 地址為0EFH-0F0H
/*---------------------------------------------------------------------*/
/*?---?STC?MCU?Limited?------------------------------------------------*/
/*?---?STC15F4K60S4?系列?ADC第9通道應用舉例----------------------------*/
/*?---?Mobile:?(86)13922805190?----------------------------------------*/
/*?---?Fax:?86-755-82905966?-------------------------------------------*/
/*?---?Tel:?86-755-82948412?-------------------------------------------*/
/*?---?Web:?www.STCMCU.com?--------------------------------------------*/
/*?如果要在程序中使用此代碼,請在程序中注明使用了宏晶科技的資料及程序???*/
/*?如果要在文章中應用此代碼,請在文章中注明使用了宏晶科技的資料及程序???*/
/*---------------------------------------------------------------------*/
//本示例在Keil開發(fā)環(huán)境下請選擇Intel的8052芯片型號進行編譯
//假定測試芯片的工作頻率為18.432MHz
#include?"reg51.h"
#include?"intrins.h"
#define?FOSC????18432000L
#define?BAUD????115200
typedef?unsigned?char?BYTE;
typedef?unsigned?int?WORD;
#define?????URMD????0???????????????//0:使用定時器2作為波特率發(fā)生器
????????????????????????????????????//1:使用定時器1的模式0(16位自動重載模式)作為波特率發(fā)生器
????????????????????????????????????//2:使用定時器1的模式2(8位自動重載模式)作為波特率發(fā)生器
sfr?T2H???=?0xd6;???????????????????//定時器2高8位
sfr?T2L???=?0xd7;???????????????????//定時器2低8位
sfr??AUXR???????=???0x8e;???????????//輔助寄存器
sfr?ADC_CONTR???=???0xBC;???????????//ADC控制寄存器
sfr?ADC_RES?????=???0xBD;???????????//ADC高8位結果
sfr?ADC_LOW2????=???0xBE;???????????//ADC低2位結果
sfr?P1ASF???????=???0x9D;???????????//P1口第2功能控制寄存器
#define?ADC_POWER???0x80????????????//ADC電源控制位
#define?ADC_FLAG????0x10????????????//ADC完成標志
#define?ADC_START???0x08????????????//ADC起始控制位
#define?ADC_SPEEDLL?0x00????????????//540個時鐘
#define?ADC_SPEEDL??0x20????????????//360個時鐘
#define?ADC_SPEEDH??0x40????????????//180個時鐘
#define?ADC_SPEEDHH?0x60????????????//90個時鐘
void?InitUart();
void?InitADC();
void?SendData(BYTE?dat);
BYTE?GetADCResult();
void?Delay(WORD?n);
void?ShowResult();
void?main()
{
????InitUart();?????????????????????//初始化串口
????InitADC();??????????????????????//初始化ADC
????while?(1)
????{
????????ShowResult();???????????????//顯示ADC結果
????}
}
/*----------------------------
發(fā)送ADC結果到PC
----------------------------*/
void?ShowResult()
{
????SendData(GetADCResult());???????//顯示ADC高8位結果
//????SendData(ADC_LOW2);???????????//顯示低2位結果
}
/*----------------------------
讀取ADC結果
----------------------------*/
BYTE?GetADCResult()
{
????ADC_CONTR?=?ADC_POWER?|?ADC_SPEEDLL?|?0?|?ADC_START;
????_nop_();????????????????????????//等待4個NOP
????_nop_();
????_nop_();
????_nop_();
????while?(!(ADC_CONTR?&?ADC_FLAG));//等待ADC轉換完成
????ADC_CONTR?&=?~ADC_FLAG;?????????//Close?ADC
????P2?=?ADC_RES;
????return?ADC_RES;?????????????????//返回ADC結果
}
/*----------------------------
初始化串口
----------------------------*/
void?InitUart()
{
????SCON?=?0x5a;????????????????????//設置串口為8位可變波特率
#if?URMD?==?0
????T2L?=?0xd8;?????????????????????//設置波特率重裝值
????T2H?=?0xff;?????????????????????//115200?bps(65536-18432000/4/115200)
????AUXR?=?0x14;????????????????????//T2為1T模式,?并啟動定時器2
????AUXR?|=?0x01;???????????????????//選擇定時器2為串口1的波特率發(fā)生器
#elif?URMD?==?1
????AUXR?=?0x40;????????????????????//定時器1為1T模式
????TMOD?=?0x00;????????????????????//定時器1為模式0(16位自動重載)
????TL1?=?0xd8;?????????????????????//設置波特率重裝值
????TH1?=?0xff;?????????????????????//115200?bps(65536-18432000/4/115200)
????TR1?=?1;????????????????????????//定時器1開始啟動
#else
????TMOD?=?0x20;????????????????????//設置定時器1為8位自動重裝載模式
????AUXR?=?0x40;????????????????????//定時器1為1T模式
????TH1?=?TL1?=?0xfb;???????????????//115200?bps(256?-?18432000/32/115200)
????TR1?=?1;
#endif
}
/*----------------------------
初始化ADC
----------------------------*/
void?InitADC()
{
????P1ASF?=?0x00;???????????????????//不設置P1口為模擬口
????ADC_RES?=?0;????????????????????//清除結果寄存器
????ADC_CONTR?=?ADC_POWER?|?ADC_SPEEDLL;
????Delay(2);???????????????????????//ADC上電并延時
}
/*----------------------------
發(fā)送串口數(shù)據(jù)
----------------------------*/
void?SendData(BYTE?dat)
{
????while?(!TI);????????????????????//等待前一個數(shù)據(jù)發(fā)送完成
????TI?=?0;?????????????????????????//清除發(fā)送標志
????SBUF?=?dat;?????????????????????//發(fā)送當前數(shù)據(jù)
}
/*----------------------------
軟件延時
----------------------------*/
void?Delay(WORD?n)
{
????WORD?x;
????while?(n--)
????{
????????x?=?5000;
????????while?(x--);
????}
}
評論
查看更多