打印
[牛人杂谈]

新唐N76E003AT20和MS51FB9AE内部带隙电压Band-Gap voltage读取

[复制链接]
610|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
概要
在实际项目中测试时,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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

176

主题

4210

帖子

5

粉丝