模数转换,ADC

1、功能说明;
-
虽然我们习惯在沟通和交流中习惯称为ADC,但更为准确的称呼应该是AUXADC,AUXADC是芯片内部的辅助ADC通道,主要用于温度监测、电池电量检测等;
-
模组共有4个AUXADC通道,包含以下三个主要功能:
a. 外接模拟电压信号检测通路;
选择内部分压电路,适用于外接信号电压范围为0~3.3V;
选择直通AUXADC输入端的通路, 适用于电压范围0-1.6V,或经外部分压后在1.6V,分压后电压范围需控制在0~1.6V;
b. VBAT电压检测通路;
- VBAT电压经过分压电路到达AUXADC输入口;
c. 温度传感器检测通路
- 模组芯片内部温度检测:芯片温度发生变化时,片内Thermal Sensor的电压信号也会随之变化,将THM_VBE信号送至AUXADC测试;
- ADC内部框图;

注意!
a. 图中用AIO表示从外部输入到模组内部AUXADC的部分,可以理解为直接连接到模组ADC管脚的电平;
b. 片内电阻绝对偏差 MAX= ±8.5%(-40~85 ℃),片内电阻的相对偏差,阻值比误差MAX=+/-0.15%(-40~85 ℃);
c. AUXADC可以选择内部分压,也可以选择外部分压,不管选择外部分压还是内部分压,都需要调整合适的分压比,保证AUXADC输入端电压在0~1.6V范围;
d. 当被测电压低于1.6V时,外部无需分压,内部也无需分压,LuatOS ADC函数对应选择 adc.ADC_RANGE_MIN 常量;
e. 当被测电压低于3.3V时,外部无需分压,内部需要分压至1.6V以内,LuatOS已将该部分在底层做好,ADC函数对应选择 adc.ADC_RANGE_MAX 常量即可;
f. 当被测电压大于3.3V时,内部无需分压,外部需要分压至1.6V以内,LuatOS已将该部分在底层做好,ADC函数对应选择 adc.ADC_RANGE_MIN 常量即可;
g. 读取模组芯片温度的常量为 adc.CH_CPU ,可检测温度范围为 -40 °C ~ 85 °C ,外部硬件电路上无需任何操作;
h. 读取VBAT电压的常量为 adc.CH_VBAT ,电压范围为 2.2V-4.8V,在VBAT输入电压范围 3.3V-4.35V之内,外部硬件电路上无需任何操作;
i. 关于以上说明,汇总表格如下:
| Channel | Application | Input Range | 外部分压 | 内部分压 | ADC函数常量 |
|---|---|---|---|---|---|
| AIO1~4 | 模组外部不需要分压电路,模组内部也不需要分压操作(adc.ADC_RANGE_MIN) | 0V ~ 1.6V | 不需要 | 不需要 | adc.ADC_RANGE_MIN |
| AIO1~4 | 模组外部需要分压电路,模组内部不需要分压操作(adc.ADC_RANGE_MIN) | 0V ~ 3.3V以上 | 需要分压至1.6V以内 | 不需要 | adc.ADC_RANGE_MIN |
| AIO1~4 | 模组外部需要分压电路,,模组内部也需要分压操作(adc.ADC_RANGE_MAX) | 0V ~ 3.3V | 不需要 | 需要,LuatOS底层操作 | adc.ADC_RANGE_MAX |
| 温度 | 模组内部自行处理,外部无需任何操作 | -40 °C ~ 85 °C | 无需任何操作 | 无需任何操作 | adc.CH_CPU |
| VBAT | VBAT直连模组,模组内部自行处理 | 2.2V ~ 4.5V | 不需要 | 需要,LuatOS底层操作 | adc.CH_VBAT |
j. 关于LuatOS中ADC的介绍,详见:1 adc - 合宙模组资料中心 ;
2、ADC的详细参数介绍,如下表;

3、特别注意事项;
- AUXADC的有效输入范围为0.1V~1.5V,在0~0.1V和1.5V~1.6V范围可能存在较大误差,不建议使用;
- 外部分压时,如果AUXADC输入电压无法满足低于1.6V,以NTC电阻为例,可使用如下图右侧所示电路进行分压设计;

- 如果不希望ADC变化太快,可以通过软件算法处理,过滤掉变化较大的数值,也可以在硬件电路上增加滤波电路;
比如,外部分压时,可以增加滤波电容增加ADC输入稳定性,但缺点是ADC的细微变化会被过滤掉,请根据实际需要谨慎选择;
说明:R300可以增加ESD能力,阻值建议为510Ω,不建议使用K级阻值的电阻;

4、关于LuatOS中ADC的介绍,详见:1 adc - 合宙模组资料中心 ;
特别说明:
-
所有ADC共用一个通道,同时只能调用一路ADC采样,包括芯片温度、VBAT电压;
-
ADC打开( adc.open() )后,会产生约500uA的功耗,如需低功耗控制,请将ADC关闭( adc.close() );
local function adc_all_task()
while true do
sys.wait(1000)--延时1S
adc.setRange(adc.ADC_RANGE_MIN)--设置ADC引脚的测量范围0-1.5V,这种方式被测电压可以经过外部电阻分压后再挂在ADC上;
adc.open(0)--打开ADC通道0
local data0 = adc.get(0)--获取adc计算值,将获取到的值赋给data0
adc.close(0)--关闭ADC通道0
log.info("adc通道0", data0)--打印adc计算值
adc.open(1)--打开ADC通道1
local data1 = adc.get(1)--获取adc计算值,将获取到的值赋给data1
adc.close(1)--关闭ADC通道1
log.info("adc通道1", data1)--打印adc计算值
adc.open(2)--打开ADC通道2
local data2 = adc.get(2)--获取adc计算值,将获取到的值赋给data2
adc.close(2)--关闭ADC通道2
log.info("adc通道2", data2)--打印adc计算值
adc.open(3)--打开ADC通道3
local data3 = adc.get(3)--获取adc计算值,将获取到的值赋给data3
adc.close(3)--关闭ADC通道3
log.info("adc通道3", data3)--打印adc计算值
adc.open(adc.CH_CPU)--打开adc.CH_CPU通道
local data5 = adc.get(adc.CH_CPU)--获取adc.CH_CPU计算值,将获取到的值赋给data5
adc.close(adc.CH_CPU)--关闭adc.CH_CPU通道
log.info("CPU TEMP", data5)--打印adc.CH_CPU计算值
adc.open(adc.CH_VBAT)--打开adc.CH_VBAT通道
local data6 = adc.get(adc.CH_VBAT)--获取adc.CH_VBAT计算值,将获取到的值赋给data6
adc.close(adc.CH_VBAT)--关闭adc.CH_VBAT通道
log.info("VBAT", data6)--打印adc.CH_VBAT计算值
end
end
sys.taskInit(adc_all_task)