[牛人杂谈] N76E003 ADC使用方法

[复制链接]
1234|9
 楼主| 734774645 发表于 2019-4-20 07:29 | 显示全部楼层 |阅读模式
主要特点:
1、12位ADC。

2、8通道单端输入模式。(一次只能测一个通道电压,值都存在ACCRH、ACCRL)

3、内部带隙电压(band-gap voltage)为1.22V,可作为内部参考电压

4、启动方式:软件启动、硬件触发方式启动
ADC模块结构图
610235cba59e166735.png


 楼主| 734774645 发表于 2019-4-20 07:30 | 显示全部楼层
实例
不多说了,直接贴代码,实现的功能为使用内部参考电压测VCC电压值。
  1. void main(void)
  2. {
  3.     uint16_t BandGap_H, BandGap_L, AIN3_H, AIN3_L;
  4.     uint16_t BandGap_v;
  5.     uint32_t AIN3_v = 0;
  6.         uint16_t voltage = 0;
  7.        
  8.     while(1)
  9.     {
  10.         Enable_ADC_BandGap;               
  11.             clr_ADCF;
  12.             set_ADCS;                                // Each time ADC start trig signal
  13.             while(ADCF == 0);
  14.         clr_ADCF;
  15.             set_ADCS;                                // Each time ADC start trig signal
  16.             while(ADCF == 0);
  17.         clr_ADCF;
  18.             set_ADCS;                                // Each time ADC start trig signal
  19.             while(ADCF == 0);
  20.             BandGap_H = ADCRH;
  21.             BandGap_L = ADCRL;
  22.             BandGap_v = BandGap_H << 4 | BandGap_L;
  23.             //printf ("\n Value = 0x%bx",ADCRH);
  24.             //printf ("\n Value = 0x%bx",ADCRL);
  25.        
  26.             Enable_ADC_AIN3;
  27.             clr_ADCF;
  28.             set_ADCS;                                // Each         time ADC start trig signal
  29.             while(ADCF == 0);
  30.             AIN3_H = ADCRH;
  31.             AIN3_L = ADCRL;
  32.             AIN3_v = AIN3_H << 4 | AIN3_L;
  33.             //printf ("\n AIN3 Value = 0x%bx",ADCRH);
  34.             //printf ("\n AIN3 Value = 0x%bx",ADCRL);
  35.             voltage = (uint16_t)((uint32_t)AIN3_v * 1220 / BandGap_v );

  36.         Timer0_Delay1ms(1000);
  37.     }
  38. }


 楼主| 734774645 发表于 2019-4-20 07:31 | 显示全部楼层
注意事项:
这里多次测内部产考电压的原因是:

连续(不延时)多次读取band-gap voltage的值 与 单次读取然后延时再次读取到的值不同,而且延时时间不同,读取到的值也不同(相当无语)

例如下面两段代码:
  1. Enable_ADC_BandGap;                        //Find in "Function_define.h" - "ADC INIT"
  2. while(1)
  3. {
  4.     clr_ADCF;
  5.     set_ADCS;                                        // Each time ADC start trig signal
  6.     while(ADCF == 0);
  7.     BandGap_H = ADCRH;
  8.     BandGap_L = ADCRL;
  9.     Timer0_Delay1ms(1000);
  10. }
  1. Enable_ADC_BandGap;                                                //Find in "Function_define.h" - "ADC INIT"
  2. while(1)
  3. {
  4.     clr_ADCF;
  5.     set_ADCS;                                                        // Each time ADC start trig signal
  6.     while(ADCF == 0);
  7.     BandGap_H = ADCRH;
  8.     BandGap_L = ADCRL;
  9.     //Timer0_Delay1ms(1000);
  10. }
加延时和不加延时读出来的值是不一样的,实测不加延时读出来的比较准确。所以实例中使用的小技巧是连续读3次内部参考电压后再测vcc,当然具体多少次自己定义。

 楼主| 734774645 发表于 2019-4-20 07:32 | 显示全部楼层
实验结果
vcc万用表测得的电压为3.3v,adc测得的电压为3.27v左右,误差30mv左右。

最后说一句,假如vcc不固定的,想用内部参考电压,但要求精度高的方案,慎用这款mcu。因此,你最好有一个靠谱的电源输入。
 楼主| 734774645 发表于 2019-4-20 07:32 | 显示全部楼层
单片机是非常好的,但是要会用,了解它的性格,摸准它的脾气。
bayga456 发表于 2019-4-20 10:48 | 显示全部楼层
感谢分享,网上这单片机的资料不多。
zhuotuzi 发表于 2019-4-21 11:12 来自手机 | 显示全部楼层
这个作为电压测量非常好用
jasontu 发表于 2019-4-22 08:10 | 显示全部楼层
734774645 发表于 2019-4-20 07:30
实例
不多说了,直接贴代码,实现的功能为使用内部参考电压测VCC电压值。

在切ADC通道時,我記得要ADC關閉。
可以參考BSP之中,ADC_multi_channel這一隻
https://github.com/OpenNuvoton/N76E003-BSP/blob/master/Sample_Code/ADC_multi_channel/Code/ADC.C
whtwhtw 发表于 2019-4-22 14:52 | 显示全部楼层
734774645 发表于 2019-4-20 07:32
单片机是非常好的,但是要会用,了解它的性格,摸准它的脾气。

看来兄弟还没有摸清楚该ic的脾气啊,虽然我也是新手,但是我知道N76E003这款芯片如果要用好ADC功能,除了通行的注意事项外,还有一点需要注意,就是ADC有专门一个通道测带隙电压,并且UID寄存器中存储有该带隙电压的校准数据!该数据可以反过来测量VCC,校准其它通道数据。
liangcha 发表于 2019-4-22 18:00 | 显示全部楼层
734774645 发表于 2019-4-20 07:31
注意事项:
这里多次测内部产考电压的原因是:

手册写得很明白了,每块MCU都有自己的BandGap需要读取UID确定,你直接用1.22那当然是不准确
您需要登录后才可以回帖 登录 | 注册

本版积分规则

211

主题

3588

帖子

15

粉丝
快速回复 在线客服 返回列表 返回顶部