[IoT技术交流] N76E003 Bandgap 校准后仍不准的原因

[复制链接]
 楼主| 发表于 2020-5-15 16:19 | 显示全部楼层 |阅读模式
N76E003 bandgap  可以通过读取UID后面两位校准,我最近发现通过bandgap反推VDD有时在校准后误差更大了。网上找资料找了一大轮,根本找不到原因说明,只看到一堆人吐槽N76E003 bandgap不准。用了好多块万用表来测量都可以确定是bandgap校准后测量不准。后来,终于在某个例程里发现UID后面的校准数据根本不是数据手册那么简单。校准数据需要分三种情况,
1,(UID[0x0d] & 0xF0) == 0x00 时,  bandgapValue = (UID[0x0c] )<< 4 +  (UID[0x0d] & 0x0F);
2,(UID[0x0d] & 0xF0) == 0x80 时,  bandgapValue = (UID[0x0c] )<< 4 +  (UID[0x0d] & 0x0F)- 44;
3,(UID[0x0d] & 0xF0) == 0x90 时,  bandgapValue = (UID[0x0e] )<< 4 +  (UID[0x0f] & 0x0F;

按这3种情况校准bandgap,测量数据就基本上很准确了。都是数据手册说的不清楚的坑呀!
发表于 2020-5-15 17:38 | 显示全部楼层
谢谢你的总结
发表于 2020-5-15 17:38 | 显示全部楼层
谢谢你的总结
发表于 2020-5-15 17:41 | 显示全部楼层
不是数据手册那么简单。
发表于 2020-5-15 18:00 | 显示全部楼层
很准确?到多少精度?
假定官方内部实测数据完全准确无误差,则实际量化误差按照官方的数据,以典型的中心值1600计算,则精度为1/1600=0.6‰。不知道你这个方法校准后数据是多少?
发表于 2020-5-16 08:56 | 显示全部楼层
官方实例已经写了,手册和实例我感觉还是相信实例吧!实例很准
发表于 2020-5-17 16:30 | 显示全部楼层
谢谢楼主分享,哪天试一下。
发表于 2020-5-17 16:51 | 显示全部楼层
感謝分享
发表于 2020-5-17 21:29 | 显示全部楼层
可以试试实例。
发表于 2020-5-17 22:38 | 显示全部楼层
不校准误差多大?
发表于 2020-5-19 11:27 | 显示全部楼层
在bsp有例子,
https://github.com/OpenNuvoton/N76E003-BSP/blob/master/Sample_Code/ADC_Bandgap_VDD_noDelay/Code/ADC_BG_VDD_avg_new.c
读出bandgap, 并转成vdd
uid里面应该写的是校正值
发表于 2020-5-19 20:47 | 显示全部楼层
没操作对?
发表于 2020-5-19 23:49 | 显示全部楼层
宝贵经验啊,666
发表于 2020-5-19 23:58 | 显示全部楼层
  1. /*---------------------------------------------------------------------------------------------------------*/
  2. /*                                                                                                         */
  3. /* Copyright(c) 2016 Nuvoton Technology Corp. All rights reserved.                                         */
  4. /*                                                                                                         */
  5. /*---------------------------------------------------------------------------------------------------------*/

  6. //***********************************************************************************************************
  7. //  Nuvoton Technoledge Corp.
  8. //  Website: http://www.nuvoton.com
  9. //  E-Mail : MicroC-8bit@nuvoton.com
  10. //  Date   : Apr/21/2016
  11. //***********************************************************************************************************

  12. //***********************************************************************************************************
  13. //  File Function: N76E885 ADC demo code
  14. //***********************************************************************************************************

  15. #include "N76E003.h"
  16. #include "SFR_Macro.h"
  17. #include "Function_define.h"
  18. #include "Common.h"
  19. #include "Delay.h"

  20. //*****************  The Following is in define in Fucntion_define.h  ***************************
  21. //****** Always include Function_define.h call the define you want, detail see main(void) *******
  22. //***********************************************************************************************
  23. #if 0
  24. //#define Enable_ADC_BandGap        ADCCON0|=SET_BIT3;ADCCON0&=0xF8;                                                                                                                                                                                                                                                        //Band-gap 1.22V
  25. #endif

  26. double  Bandgap_Voltage,VDD_Voltage;                        //please always use "double" mode for this
  27. unsigned  char xdata ADCdataH[5], ADCdataL[5];
  28. int ADCsumH=0, ADCsumL=0;
  29. unsigned char ADCavgH,ADCavgL;

  30. void READ_BANDGAP()
  31. {
  32.                 UINT8 BandgapHigh,BandgapLow,BandgapMark;
  33.                 double Bandgap_Value,Bandgap_Voltage_Temp;
  34.        
  35.                 set_IAPEN;
  36.                 IAPCN = READ_UID;
  37.                 IAPAL = 0x0d;
  38.     IAPAH = 0x00;
  39.     set_IAPGO;
  40.                 BandgapLow = IAPFD;
  41.                 BandgapMark = BandgapLow&0xF0;
  42.                        
  43.                 if (BandgapMark==0x80)
  44.                 {
  45.                                 BandgapLow = BandgapLow&0x0F;
  46.                                 IAPAL = 0x0C;
  47.                                 IAPAH = 0x00;
  48.                                 set_IAPGO;
  49.                                 BandgapHigh = IAPFD;
  50.                                 Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
  51.                                 Bandgap_Voltage_Temp = Bandgap_Value*3/4;
  52.                                 Bandgap_Voltage = Bandgap_Voltage_Temp - 33;                        //the actually banggap voltage value is similar this value.
  53.                 }
  54.                 if (BandgapMark==0x00)
  55.                 {
  56.                                 BandgapLow = BandgapLow&0x0F;
  57.                                 IAPAL = 0x0C;
  58.                                 IAPAH = 0x00;
  59.                                 set_IAPGO;
  60.                                 BandgapHigh = IAPFD;
  61.                                 Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
  62.                                 Bandgap_Voltage= Bandgap_Value*3/4;
  63.                 }
  64.                 if (BandgapMark==0x90)
  65.                 {
  66.                                 IAPAL = 0x0E;
  67.                                 IAPAH = 0x00;
  68.                                 set_IAPGO;
  69.                                 BandgapHigh = IAPFD;
  70.                                 IAPAL = 0x0F;
  71.                                 IAPAH = 0x00;
  72.                                 set_IAPGO;
  73.                                 BandgapLow = IAPFD;
  74.                                 BandgapLow = BandgapLow&0x0F;
  75.                                 Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
  76.                                 Bandgap_Voltage= Bandgap_Value*3/4;
  77.                 }
  78.                 clr_IAPEN;
  79. //                        printf ("\n BG High = %bX",BandgapHigh);
  80. //                        printf ("\n BG Low = %bX",BandgapLow);
  81. //                        printf ("\n BG ROMMAP = %e",Bandgap_Voltage);
  82. }
  83.                
  84.                
  85. /******************************************************************************
  86. The main C function.  Program execution starts
  87. here after stack initialization.
  88. ******************************************************************************/
  89. void main (void)
  90. {
  91.                 double bgvalue;
  92.                 unsigned int i;
  93.        
  94.                 InitialUART0_Timer1(115200);
  95.                 READ_BANDGAP();
  96.                 printf ("\n BG ROMMAP = %e",Bandgap_Voltage);
  97.        
  98.                 while (1)
  99.                 {
  100.                                 Enable_ADC_BandGap;                                                                                               
  101.                                 CKDIV = 0x02;                                                                                                                        // IMPORTANT!! Modify system clock to 4MHz ,then add the ADC sampling clock base to add the sampling timing.
  102.                                 for(i=0;i<5;i++)                                                                                                        // All following ADC detect timing is 200uS run under 4MHz.
  103.                                 {
  104.                                                 clr_ADCF;
  105.                                                 set_ADCS;                                                                                                                               
  106.                                                 while(ADCF == 0);
  107.                                                 ADCdataH[i] = ADCRH;
  108.                                                 ADCdataL[i] = ADCRL;
  109.                                 }               
  110.                                 CKDIV = 0x00;                                                                                                                        // After ADC sampling, modify system clock back to 16MHz to run next code.
  111.                                 Disable_ADC;
  112.                                 for(i=2;i<5;i++)                                                                                                        // use the last 3 times data to make average
  113.                                 {
  114.                                         ADCsumH = ADCsumH + ADCdataH[i];
  115.                                         ADCsumL = ADCsumL + ADCdataL[i];
  116.                                 }                               
  117.                                 ADCavgH = ADCsumH/3;
  118.                                 ADCavgL = ADCsumL/3;
  119.                                 bgvalue = (ADCavgH<<4) + ADCavgL;
  120.                                 VDD_Voltage = (0x1000/bgvalue)*Bandgap_Voltage;
  121.                                 printf ("\n VDD voltage = %e", VDD_Voltage);
  122.                                 Timer0_Delay1ms(500);
  123.                                 ADCsumH = 0;
  124.                                 ADCsumL = 0;
  125.                 }
  126. }


发表于 2020-5-19 23:58 | 显示全部楼层
是这个例子吧
发表于 2020-5-29 10:27 | 显示全部楼层
之前用的时候我是直接读bandgap的AD值,发现波动很大,所以一直就没用bandgap值。也不知道是软件问题还是硬件问题
发表于 2020-5-29 21:05 | 显示全部楼层
官方例子讲的有,不过没这么总结。
发表于 2023-2-10 09:43 | 显示全部楼层
Bandgap_Voltage= Bandgap_Value*3/4;这个乘3除4是怎么来的?为何是这个数?请问大家知道吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

16

帖子

1

粉丝
快速回复 返回顶部 返回列表