#include "reg51.h"
#include "intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
//WORD idata Vbg_RAM _at_ 0xef; //对于只有256字节RAM的MCU存放地址为0EFH
//WORD idata Vbg_RAM _at_ 0x6f; //对于只有128字节RAM的MCU存放地址为06FH
//注意:需要在下载代码时选择"在ID号前添加重要测试参数"选项,才可在程序中获取此参数
WORD code Vbg_ROM _at_ 0x03f7; //1K程序空间的MCU
//#define Vbg_ROM 0x03f7 //1K程序空间的MCU
//-----------------------------------------
sfr ADC_CONTR = 0xBC; //ADC控制寄存器
sfr ADC_RES = 0xBD; //ADC高8位结果
sfr ADC_LOW2 = 0xBE; //ADC低2位结果
sfr P1ASF = 0x9D; //P1口第2功能控制寄存器
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr T2H = 0xd6; //定时器2高8位
sfr T2L = 0xd7; //定时器2低8位
sfr AUXR = 0x8e; //辅助寄存器
sfr WKTCL = 0xaa; //掉电唤醒定时器计时低字节
sfr WKTCH = 0xab; //掉电唤醒定时器计时高字节
#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 UartInit();
void SendUart(BYTE dat);
/*----------------------------
初始化串口
----------------------------*/
void UartInit() //9600bps@5.5296MHz
{
SCON = 0x5a; //8位数据,可变波特率
AUXR |= 0x04; //定时器2时钟为Fosc,即1T
T2L = 0x70; //设定定时初值
T2H = 0xFF; //设定定时初值
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x10; //启动定时器2
}
/*----------------------------
发送串口数据
----------------------------*/
void SendUart(BYTE dat)
{
while (!TI); //等待前面的数据发送完成
TI = 0; //清除发送完成标志
SBUF = dat; //发送串口数据
}
void Delay(WORD n)
{
WORD x;
while (n--)
{
x = 5000;
while (x--);
}
}
void main()
{
BYTE ADCbg;
BYTE code *pVbg_ROM;
WORD VCC;
BYTE *pVCC; //这2个指针的数据类型用哪个正确?BYTE WORD
BYTE i;
UartInit();
while (1)
{
pVbg_ROM = &Vbg_ROM; //从程序区读取BandGap电压值(单位:毫伏mV)
for (i=0; i<2; i++) //读2个字节(高字节在前)
{
SendUart(*pVbg_ROM++); //串口发送ROM中的标准电压 出04 DD 1245毫伏mV
}
ADC_RES = 0; //清除结果寄存器
P1ASF = 0x00; //不设置P1ASF,即可从ADC的第9通道读取内部Bandgap电压的ADC测量值
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
Delay(2); //ADC上电并延时
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; //清除ADC标志
ADCbg = ADC_RES;
SendUart(ADCbg); //串口发送对标准电压的ADC值
VCC = 256 * (Vbg_ROM/ADCbg); //必须先相除 不然超过WORD的范围
pVCC = &VCC;
for (i=0; i<2; i++) //读2个字节
{
SendUart(*pVCC++); //串口出来的电源电压为什么就不对了?0F 00换电源电压低位还是00
}
}
}
|