利用带隙电压获取新塘单片机N76E003芯片电压VDD

2025-10-22 15:57:20

1、【1】打开集成开发环境Keil并建立好相应C51工程。

【2】在创建工程时Device选择Nuvoton 8051 Devices-->E76E003。前提要安装好Keil插件,否则找不到芯片型号,插件必须安装在Keil的根目录下。

【3】我是将Keil C51和Keil ARM安装在同一个根目录下,所以他们两个的图标相似,最主要是代码的放大缩小很方便。

【4】设置Output生成.hex文件的位置和Listing文件的位置,必须将Create    HEX Files前打勾。

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

2、【1】编写串口驱动驱动程序,设置波特率为9600pbs,8位数据位,1位停止位,无奇偶校验。串口驱动驱动程序可以直接用官方给的Demo。

void InitialUART1_Timer3(u32 u32Baudrate)//Initial UART1 Timer3

【2】编写简单的延时函数,也可以使用官方提供的延时函数,官方给的延时函数使用定时器,提前是你不使用这个定时器,否则这个延时函数不准或出错。

void Timer0_Delay1ms(u32 u32CNT)//Timer0 Delay 1ms

【3】编写获取带隙电压(Band-gap)函数,这个函数在数据数据手册上有,   ADC那一章有讲解。获取带隙电压需要用到IAP功能读取固化到Flash中的内容。

void vGet_BandGap_VoltageValue(void)//xGet Band Gap Voltage Value

【4】编写获取当前芯片的电压值。

double xGet_PowerSource_Voltage(void)//xGet Power Source Voltage

【5】编写printf函数的重定向

char putchar (char c)//UART1 printf

3、【1】串口驱动驱动程序

void InitialUART1_Timer3(u32 u32Baudrate)//Initial UART1 Timer3

{

P02_Quasi_Mode; //Setting UART pin as Quasi mode for transmit

P16_Quasi_Mode; //Setting UART pin as Quasi mode for transmit

SCON_1 = 0x50;    //UART1 Mode1,REN_1=1,TI_1=1

T3CON  = 0x08;    //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1), UART1 in MODE 1

clr_BRCK;

#ifdef FOSC_160000

RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); //16 MHz 

RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1);

#endif

#ifdef FOSC_166000

RH3 = HIBYTE(65536 - (1037500/u32Baudrate)); //16.6 MHz 

RL3 = LOBYTE(65536 - (1037500/u32Baudrate));

#endif

set_TR3;          //Trigger Timer3

TI_1 = 1; //For printf function must setting TI = 1

}

【2】延时函数

void Timer0_Delay1ms(u32 u32CNT)//Timer0 Delay 1ms

{

clr_T0M;                                //T0M=0, Timer0 Clock = Fsys/12

TMOD |= 0x01;                            //Timer0 is 16-bit mode

set_TR0;                                //Start Timer0

while (u32CNT != 0)

{

TL0 = LOBYTE(TIMER_DIV12_VALUE_1ms); //Find  define in "Function_define.h" "TIMER VALUE"

TH0 = HIBYTE(TIMER_DIV12_VALUE_1ms);

while (TF0 != 1);                    //Check Timer0 Time-Out Flag

clr_TF0;

u32CNT --;

}

clr_TR0;                                //Stop Timer0

}

【3】获取带隙电压(Band-gap)函数

BandGapStruct BanGapStruct;

void vGet_BandGap_VoltageValue(void)//xGet Band Gap Voltage Value

{

double bandGapVoltage = 0;

u16    bandGapValue = 0;

u8     bandGapHigh=0, bandGapLow=0, BandgapMark=0;

IAP_ENABLE;

IAPCN = READ_UID;

IAPAL = 0X0D;

IAPAH = 0X00;

IAP_START_PROGRAMEE;

bandGapLow = IAPFD;

BandgapMark = bandGapLow&0XF0;

switch(BandgapMark)

{

case 0X00 : 

{

bandGapLow = bandGapLow&0X0F;

IAPAL = 0X0C;

IAPAH = 0X00;

IAP_START_PROGRAMEE;

bandGapHigh = IAPFD;

bandGapValue = (((u16)bandGapHigh)<<4) + bandGapLow;

bandGapVoltage = (bandGapValue*3)/4;

}

break;

case 0X80 : 

{

bandGapLow = bandGapLow&0X0F;

IAPAL = 0X0C;

IAPAH = 0X00;

IAP_START_PROGRAMEE;

bandGapHigh = IAPFD;

bandGapValue = (((u16)bandGapHigh)<<4) + bandGapLow;

bandGapVoltage = ((bandGapValue*3)/4) - 33;

}

break;

case 0X90 : 

{

IAPAL = 0X0E;

IAPAH = 0X00;

IAP_START_PROGRAMEE;

bandGapHigh = IAPFD;

IAPAL = 0X0F;

IAPAH = 0X00;

IAP_START_PROGRAMEE;

bandGapLow = IAPFD;

bandGapLow = bandGapLow&0X0F;

bandGapValue = (((u16)bandGapHigh)<<4) + bandGapLow;

bandGapVoltage = (bandGapValue*3)/4;

}

break;

default : break;

}

IAP_DISABLE;

BanGapStruct.Voltage = bandGapVoltage;

}

【4】获取当前芯片的电压值

double xGet_PowerSource_Voltage(void)//xGet Power Source Voltage

{

double powerVolatge = 0;

double powerADC = 0;

u16    powerADCH=0, powerADCL=0;

u8     adcDataH[5]={0}, adcDataL[5]={0};

u8    i = 0;

Enable_ADC_BandGap;

CKDIV = 0X02;

for(i=0; i<5; i++)

{

ADC_CLR_FALG;

ADC_START_CONVERT;

while(!ADCF);

adcDataH[i] = ADCRH;

adcDataL[i] = ADCRL;

}

CKDIV = 0X00;

for(i=2; i<5; i++)

{

powerADCH += adcDataH[i];

powerADCL += adcDataL[i];

}

adcDataH[0] = ((u8)(powerADCH/3));

adcDataL[0] = ((u8)(powerADCL/3));

powerADC = (((u16)adcDataH[0])<<4) + adcDataL[0];

powerVolatge = (0X1000/powerADC)*BanGapStruct.Voltage;

return powerVolatge;

}

【5】printf函数的重定向

char putchar (char c)//UART1 printf

{

while (!TI_1);//wait until transmitter ready

TI_1 = 0;

SBUF_1 = c;//output character

return (c);

}

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

4、编写主函数。先要获取获取带隙电压,才能获取当前芯片电压

void main(void)

{

Set_All_GPIO_Quasi_Mode;

InitialUART1_Timer3(9600);

vGet_BandGap_VoltageValue();

while(1)

{

printf("Current Voltage : %f mV", xGet_PowerSource_Voltage());

Timer0_Delay1ms(3000);

}

}

利用带隙电压获取新塘单片机N76E003芯片电压VDD

5、【1】编译并检查错误,直到程序正确为此。

【2】N76E003的时钟默认为16MHZ,宏定义系统时钟,否则串口配置无效,串口配置中有一个条件编译,所以需要宏定义,我这里直接定义在编译器中。

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

6、【1】将程序下载到芯片中,也就是下载.hex到芯片中。

【2】通过串口调试助手参看当前电压值,调节当前电压值再次查看串口调试助手打印的信息,已验证程序的正确性,也可以用万用表直接测量此时芯片的电压,看是否相正确。

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

利用带隙电压获取新塘单片机N76E003芯片电压VDD

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢