2.1. ADC

2.1.1. Overview

本文仅介绍常规ADC,不包括Audio ADC。
AC792N的ADC精度为10bit,其时钟最大不可超过1MHz。有16个IO AD采样通道,ADC还可以直接对芯片内部的部分PMU电源电压进行采样。

示例工程:可在demo_hello工程中的apps/demo/demo_hello/include/app_config.h中打开USE_ADC_TEST_DEMO宏测试。

例程路径:apps/common/example/peripheral/adc/adc_test.c

2.1.2. 采样值与电压转换

ADC采样值与电压的转换公式:

\[V_{io} = \frac{M_{io} * V_{vbg}} {M_{vbg}} = \frac{M_{io} * 800mV} {M_{vbg}}\]

其中,Vio -> AD脚电压;Vvbg -> VBG电压;Mio -> AD脚采样值; Mvbg -> VBG采样值。Vvbg为芯片内部基准参考电压,固定为800mV。Mio和 Mvbg都可以通过ADC采样获得,因此可以求得AD脚的电压值。

ADC采样电压值误差:正常用户拿到的芯片都已经Trim过,Trim过程会将芯片内部参考电压VBG (800mV)的电压误差控制在±7.5mV内。以AD脚输入电压3200mV为例,这时理论上芯片AD采样获得的电压的误差值应在3200/800*7.5=30mV以内,AD脚输入的电压值越高,误差值越大。

满幅电压:VDDIO的电压采样值恒为0x3FF(1024)

如何确定Vvbg电压是否Trim准确?通过前面的原理介绍,我们可以知道VDDIO的电压其实与Vvbg的电压是成比例关系的:

\[\frac{V_{vddio}} {V_{vbg}} = \frac{M_{vddio}} {M_{vbg}}\]

Vvddio可以直接通过仪表直接量得,且Mvddio固定为0x3FF(1024),而Mvbg可通过AD采样获得,从而可以计算出Vvbg。Vvbg与800mV的差值即为实际的Vvbg误差值,该误差值应该在±7.5mV以内。

2.1.3. 可选通道

2.1.3.1. 16个IO采样通道如下(参考adc_api.h):

typedef enum {
    ADC_IO_CH_PD00,
    ADC_IO_CH_PD01,
    ADC_IO_CH_PD06,
    ADC_IO_CH_PD07,
    ADC_IO_CH_PD08,
    ADC_IO_CH_PD09,
    ADC_IO_CH_PD10,
    ADC_IO_CH_PE04,
    ADC_IO_CH_PE05,
    ADC_IO_CH_PE06,
    ADC_IO_CH_PE07,
    ADC_IO_CH_PE08,
    ADC_IO_CH_PE09,
    ADC_IO_CH_PC13,
    ADC_IO_CH_DP,
    ADC_IO_CH_DM,
    ADC_IO_CH_MAX, ///< 无用
} adc_io_ch_t;

2.1.3.2. 支持ADC采样的PMU电源如下(参考adc_api.h):

#define ADC_PMU_CH_VBG      (0x0 | (ADC_PMU_CH << 16))
#define ADC_PMU_CH_VDC14    (0x1 | (ADC_PMU_CH << 16))
#define ADC_PMU_CH_SYSVDD   (0x2 | (ADC_PMU_CH << 16))
#define ADC_PMU_CH_VTEMP    (0x3 | (ADC_PMU_CH << 16))
#define ADC_PMU_CH_WVDD     (0x4 | (ADC_PMU_CH << 16))
#define ADC_PMU_CH_VBAT     (0x5 | (ADC_PMU_CH << 16)) ///< 1/4 vbat电压

注意,选择ADC_PMU_CH_VBAT返回的是四分之一的VBAT电压。

2.1.4. 使用流程

2.1.4.1. 一般使用流程

ADC初始化 -> 配置IO为模拟输入-> 添加扫描通道 -> 获取采样值

初始化:调用adc_init()即可。不过一般SDK工程已经在board_xxx.c中的board_init()已经调用过,这时就无须再重复初始化。adc_init()除了对ADC进初始化,还会添加一个2ms的定时器,对已经添加的扫描通道轮流进行采样(每次中断只采样其中一个通道),也因此对于刚添加的扫描通道,需要一定延时才能正确获取到AD值。

配置IO状态:设置AD脚的IO状态为模拟输入,并可根据需要开启内部上拉/下拉电阻(阻值请参考具体芯片型号的datasheet),不过由于内部上下拉电阻阻值偏差较大,不建议用在精度要求高的场景。

gpio_set_direction(IO_PORTD_00, 1);     //方向设为输入

// gpio_set_pull_up(IO_PORTD_00, 1);    //设置内部上拉10K
// gpio_set_pull_down(IO_PORTD_00, 1);  //设置内部下拉10K

添加扫描通道:支持的采样通道参考前面<可选通道>章节。

adc_add_sample_ch(ADC_IO_CH_PD00);

获取采样值:

unsigned int adc_val = adc_get_value(ADC_IO_CH_PD00);  //获取AD采样值
unsigned int io_vol = adc_get_voltage(ADC_IO_CH_PD00); //获取AD采样电压

2.1.5. 常见问题说明

  • 添加测量通道之后,不能马上去读取ADC值,需要延时一段时间(原因参考 初始化 的描述)。

  • 电压测量范围是0 ~ VDDIO,对应AD值为0x000 ~ 0x3FF

  • 由于误差累积是线性的,VBG电压存在误差,比如误差值5mv,那么每800mV电压,会增加5mV误差,用户可以据此自行估计所测的误差范围。

2.1.6. API参考


AD channel define

ADC_PMU_CH_VBG
ADC_PMU_CH_VDC14
ADC_PMU_CH_SYSVDD
ADC_PMU_CH_VTEMP
ADC_PMU_CH_WVDD
ADC_PMU_CH_VBAT
ADC_PMU_CH_LDO5V
AD_AUDIO_CH_VCM
AD_AUDIO_CH_VOUTL
AD_AUDIO_CH_VOUTR
AD_AUDIO_CH_DACVDD
enum adc_io_ch_t

Values:

enumerator ADC_IO_CH_PD00
enumerator ADC_IO_CH_PD01
enumerator ADC_IO_CH_PD06
enumerator ADC_IO_CH_PD07
enumerator ADC_IO_CH_PD08
enumerator ADC_IO_CH_PD09
enumerator ADC_IO_CH_PD10
enumerator ADC_IO_CH_PE04
enumerator ADC_IO_CH_PE05
enumerator ADC_IO_CH_PE06
enumerator ADC_IO_CH_PE07
enumerator ADC_IO_CH_PE08
enumerator ADC_IO_CH_PE09
enumerator ADC_IO_CH_PC13
enumerator ADC_IO_CH_DP
enumerator ADC_IO_CH_DM
enumerator ADC_IO_CH_MAX
void adc_init(void)

adc_init, adc初始化

void adc_suspend(void)

adc_suspend, adc检测挂起

void adc_resume(void)

adc_resume, adc检测恢复

u32 adc_get_value(u32 ch)

adc_get_value, 从队列中获取adc通道测得的数值

Parameters

ch – : ADC通道号

Returns

当前通道的AD值

u32 adc_add_sample_ch(u32 ch)

adc_add_sample_ch, 添加adc采样通道到采样队列中

Parameters

ch – : ADC通道号

Returns

当前通道值

u32 adc_remove_sample_ch(u32 ch)

adc_remove_sample_ch, 从采样队列中移除adc采样通道

Parameters

ch – : ADC通道号

Returns

当前通道值

u32 adc_get_voltage(u32 ch)

adc_get_voltage, 换算电压的公式函数, 获取adc通道电压值,如果测得与实际不符,则需留意芯片是否trim过,trim值是否正确。

Parameters

ch – : ADC通道号

Returns

当前通道的电压值,单位mv

u32 adc_value_to_voltage(u32 adc_vbg, u32 adc_ch_val)

adc_value_to_voltage, 采样值换算电压,如果换算后与实际不符,则需留意芯片是否trim过,trim值是否正确。

Parameters
  • adc_vbg – : 基准电压采样值

  • adc_ch_val – : 需要转换的通道的AD值

Returns

转换后的电压值,单位mv

u32 adc_get_value_blocking(u32 ch)

adc_get_value_blocking, 阻塞式采集一个指定通道的adc原始值

Parameters

ch – : ADC通道号

Returns

当前通道的AD值

u32 adc_get_voltage_blocking(u32 ch)

adc_get_voltage_blocking, 阻塞式采集一个指定通道的电压值(经过均值滤波处理)

Parameters

ch – : ADC通道号

Returns

转换后的电压值,单位mv

u32 adc_sample(u32 ch, u8 block)

adc_sample, 启动采样一次

Note

内部接口,用户请勿直接使用该接口

Parameters
  • ch – : ADC通道号

  • block – : 是否堵塞

Returns

堵塞时返回当前通道的AD值,非堵塞时返回上一次测量的AD值

adc_io_ch_t adc_io2ch(int gpio)

adc_io2ch, adc io转换成对应adc通道序号

Parameters

gpio – : adc io

Returns

对应通道序号

Defines

ADC_MAX_CH