概要
在实际项目中测试时,3个产品中发现有1个在获取芯片vdd时数值疯狂跳动,以为是芯片或者是电路(电源)不稳定的原因。为了进一步验证问题实际原因,通过获取其他通道值时,可以获得稳定的采样值,推断电路是稳定没有问题的,就是获取带隙电压处理程序的问题。后面根据网上资料查找,得知此芯片根据不同的情况,实际带隙电压值获取方法有区别,从而找到了一个稳定的方法来获取带隙电压,可以准确获得vdd。
新唐N76E003AT20和MS51FB9AE芯片,内部带隙电压(band-gap voltage)为1.22V,两个型号芯片是通用的,可以参考后面的方式稳定读取带隙电压,从而推断出芯片供电电压VDD。(目前已实测MS51FB9AE)
此贴中均为MS51FB9AE资料和代码,N76E003AT20兼容MS51FB9AE,基本可以不修改代码直接移植测试。
内部ADC结构
Band-Gap说明
测试代码
void get_bandGap_voltage(void)用于获取芯片内部UID校准过后的实际带隙电压值,在获取芯片实际的带隙电压后,读取ADC的带隙电压通道采样值。
根据公式:
bandGapVoltage / vdd = adcVal / 4096
得到最终转换公式:
vdd = 0x1000 / adcVal * bandGapVoltage
可以计算出实际的vdd供电电压(单位:mV)。
double bandGapVoltage;
uint16_t u16vdd;
void get_bandGap_voltage(void)
{
uint16_t bandGapValue;
uint8_t bandGapHigh, bandGapLow, BandgapMark;
set_CHPCON_IAPEN;
IAPCN = READ_UID;
IAPAL = 0x0D;
IAPAH = 0x00;
set_IAPTRG_IAPGO;
bandGapLow = IAPFD;
BandgapMark = bandGapLow & 0xF0;
switch (BandgapMark)
{
case 0x00:
bandGapLow = bandGapLow & 0x0F;
IAPAL = 0x0C;
IAPAH = 0x00;
set_IAPTRG_IAPGO;
bandGapHigh = IAPFD;
bandGapValue = (((uint16_t )bandGapHigh) << 4) + bandGapLow;
bandGapVoltage = (bandGapValue * 3) / 4;
break;
case 0x80:
bandGapLow = bandGapLow & 0x0F;
IAPAL = 0x0C;
IAPAH = 0x00;
set_IAPTRG_IAPGO;
bandGapHigh = IAPFD;
bandGapValue = (((uint16_t )bandGapHigh) << 4) + bandGapLow;
bandGapVoltage = ((bandGapValue * 3) / 4) - 33;
break;
case 0x90:
IAPAL = 0x0E;
IAPAH = 0x00;
set_IAPTRG_IAPGO;
bandGapHigh = IAPFD;
IAPAL = 0x0F;
IAPAH = 0x00;
set_IAPTRG_IAPGO;
bandGapLow = IAPFD;
bandGapLow = bandGapLow & 0x0F;
bandGapValue = (((uint16_t )bandGapHigh) << 4) + bandGapLow;
bandGapVoltage = (bandGapValue * 3) / 4;
break;
default:
break;
}
clr_CHPCON_IAPEN;
}
void get_device_vdd(void)
{
uint16_t adcVal, tempBuf[5],
uint8_t i = 0;
Enable_ADC_BandGap;
// CKDIV = 0x02;
for (i = 0; i < 5; i++)
{
clr_ADCCON0_ADCF;
set_ADCCON0_ADCS;
while (!ADCF)
;
tempBuf = (ADCRH << 4) + ADCRL;;
}
// CKDIV = 0x00;
adcVal = (tempBuf[2] + tempBuf[3] + tempBuf[4]) / 3;
/* Calculate vdd value. */
u16vdd = (uint16_t)((0x1000 / adcVal) * bandGapVoltage);
}
void main(void)
{
get_bandGap_voltage_value();
while(1);
{
get_device_vdd();
}
}
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/youseeme/article/details/139313806
|