2.1. ADC
2.1.1. Overview
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采样值与电压的转换公式:
其中,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的电压是成比例关系的:
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.4.2. 立即获取AD值
如果不想常规方式延时等待定时器获取AD值,需要ADC立即对指定通道进行采样,可调用下面的接口:
/**
* @brief adc_get_value_blocking, 阻塞式采集一个指定通道的adc原始值
* @param ch : ADC通道号
* @return 当前通道的AD值
*/
u32 adc_get_value_blocking(u32 ch);
/**
* @brief adc_get_voltage_blocking, 阻塞式采集一个指定通道的电压值(经过均值滤波处理)
* @param ch : ADC通道号
* @return 转换后的电压值,单位mv
*/
u32 adc_get_voltage_blocking(u32 ch);
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
-
enumerator ADC_IO_CH_PD00
-
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