標題: 利用新增的ADC第九通道測量內(nèi)部固定的測試內(nèi)部BandGap參考電壓來計算工作電壓 [打印本頁]

作者: lzj23642008    時間: 2018-12-19 14:43
標題: 利用新增的ADC第九通道測量內(nèi)部固定的測試內(nèi)部BandGap參考電壓來計算工作電壓


   本示例在Keil開發(fā)環(huán)境下請選擇Intel的8058芯片型號進行編譯,若無特別說明,工作頻率一般為11.0592MHz


      ADC的第9通道是用來測試內(nèi)部BandGap參考電壓的,由于內(nèi)部BandGap參考電壓很穩(wěn)定,不會隨芯片的工作電壓的改變而變化,所以可以通過測量內(nèi)部BandGap參考電壓,然后通過ADC的值便可反推出VCC的電壓,從而用戶可以實現(xiàn)自己的低壓檢測功能.  
      ADC的第9通道的測量方法:首先將P1ASF初始化為0,即關閉所有P1口的模擬功能然后通過正常的ADC轉換的方法讀取第0通道的值,即可通過ADC的第9通道讀取當前內(nèi)部BandGap參考電壓值.
     用戶實現(xiàn)自己的低壓檢測功能的實現(xiàn)方法:首先用戶需要在VCC很精準的情況下(比如5.0V),測量出內(nèi)部BandGap參考電壓的ADC轉換值(比如為BGV5),并這個值保存到EEPROM中,然后在低壓檢測的代碼中,在實際VCC變化后,所測量出的內(nèi)部BandGap參考電壓的ADC轉換值(比如為BGVx),通過計算公式: 實際VCC = 5.0V * BGV5 / BGVx,即可計算出實際的VCC電壓值,需要注意的是,第一步的BGV5的基準測量一定要精確.

實現(xiàn)的源程序如下:

#include "reg51.h"
#include "intrins.h"

#define FOSC    11059200L
#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 P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;

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()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;

    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--);
    }
}



作者: admin    時間: 2018-12-19 16:42
補全原理圖或者詳細說明一下電路連接即可獲得100+黑幣
作者: m182892    時間: 2019-7-13 16:18
測量出內(nèi)部BandGap參考電壓的ADC轉換值,這個轉換值是ADC值還是電壓值?
作者: ty417502873    時間: 2019-8-31 18:00
這就是STC程序,你給搬這里了




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1