跳转至

adc - 模数转换

Air780EPM的ADC能力介绍

Air780EPM共有4路外部ADC硬件通道,其通常的作用是用来测试电压数值;

ADC 管脚号 说明
ADC0 9 通道ID:0,分辨率12 bits
ADC1 96 通道ID:1,分辨率12 bits
ADC2 77 通道ID:2,分辨率12 bits
ADC3 76 通道ID:3,分辨率12 bits

ADC硬件连接被测电压的方式有两个:

  1. 当被测电压低于3.6V时,被测电压可以直连ADC;

  2. 当被测电压大于3.6V时,被测电压需先经过外部电阻分压,且经过分压后接在ADC的电压值需小于1.5V;

以上ADC的两种硬件连接方式,对应不同的软件设置,在下面会提到;

除4路外部ADC通道外,Air780EPM还有2路内部ADC通道

一路是CH_CPU,用来测量Air780EPM的CPU温度;

一路是CH_VBAT, 用来测量 Air780EPM 的 vbat 电压(vbat,或者写为VBAT,也就是Air780EPM工作时的供电电压,对应Air780EPM的PIN42/PIN43);


Air780EPM的ADC核心库的常量

常量,顾名思义是由合宙LuatOS底层固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

常量 类型 解释
ADC_RANGE_MAX number ADC引脚的测量范围0-3.6V,这种方式被测电压不可经过外部电阻分压后再挂在ADC上;
ADC_RANGE_MIN number ADC引脚的测量范围0-1.5V,这种方式被测电压可以经过外部电阻分压后再挂在ADC上;
adc.CH_CPU number CPU内部温度的通道id,内部通道,直接获取,不占用ADC 0-3,不外接任何电路
adc.CH_VBAT number VBAT供电电压的通道id,内部通道,直接获取,不占用ADC 0-3,不外接任何电路

与外部ADC有关的常量有两个,请务必注意二者的区别:

ADC_RANGE_MAX,ADC引脚的测量范围0-3.6V,这种方式被测电压不可经过外部电阻分压后再挂在ADC上;

ADC_RANGE_MIN,ADC引脚的测量范围0-1.5V,这种方式被测电压可以经过外部电阻分压后再挂在ADC上;

当被测量电压最高值在1.5v以内时, 推荐使用ADC_RANGE_MIN,且不添加外部分压电路

当被测量电压最高值在3.6v以内时, 推荐使用ADC_RANGE_MAX,且不添加外部分压电路

当被测量电压最高值在3.6v以上时, 推荐使用ADC_RANGE_MIN,且必须添加外部分压电路


Air780EPM的ADC核心库函数详解

adc.setRange(range)

设置ADC的测量范围,使用 ADC_RANGE_MAX 和 ADC_RANGE_MIN 两个常量,根据实际被测电压进行选择 ;

参数

传入值类型 解释
int ADC_RANGE_MAX 和 ADC_RANGE_MIN 两个常量,根据实际被测电压进行选择
return nil

返回值

例子

-- !!!本函数要在调用adc.open之前就调用, 之后调用无效!!!


-- 设置ADC引脚的测量范围0-3.6V,这种方式被测电压不可经过外部电阻分压后再挂在ADC上;
adc.setRange(adc.ADC_RANGE_MAX)


-- 设置ADC引脚的测量范围0-1.5V,这种方式被测电压可以经过外部电阻分压后再挂在ADC上;
adc.setRange(adc.ADC_RANGE_MIN)

-- 说明:
-- 当被测量电压最高值在1.5v以内时, 推荐使用ADC_RANGE_MIN,且不添加外部分压电路;
-- 当被测量电压最高值在3.6v以内时, 推荐使用ADC_RANGE_MAX,且不添加外部分压电路;
-- 当被测量电压最高值在3.6v以上时, 推荐使用ADC_RANGE_MIN,且必须添加外部分压电路;

adc.open(id)

打开adc通道

参数

传入值类型 解释
int 通道id,从0开始,共0-3四个硬件通道,ADC0通道ID为0,ADC1通道ID为1,ADC2通道ID为2,ADC3通道ID为3

返回值

返回值类型 解释
boolean 打开结果

例子

-- 设置ADC引脚的测量范围0-3.6V,这种方式被测电压不可经过外部电阻分压后再挂在ADC上;
adc.setRange(adc.ADC_RANGE_MAX)
-- 打开adc通道2,并读取
if adc.open(2) then
log.info("adc", adc.get(2)) -- 返回电压值;
end
adc.close(2) -- 若需要持续读取, 则不需要close, 功耗会高一点.

adc.get(id)

获取adc计算值

参数

传入值类型 解释
int 通道id,从0开始,共0-3四个硬件通道,ADC0通道ID为0,ADC1通道ID为1,ADC2通道ID为2,ADC3通道ID为3

返回值

返回值类型 解释
int 单位是mV, 若读取失败,会返回-1

例子

-- 设置adc.setRange(adc.ADC_RANGE_MAX)方式,打开adc通道2,并读取电压值
adc.setRange(adc.ADC_RANGE_MAX)

adc.open(2)
local data = adc.get(2)
adc.close(2)

log.info("adc读出值", data)
-- 此时读取的data值即为ADC电压值,也为被测电压的实际值;
-- 设置adc.setRange(adc.ADC_RANGE_MIN)方式,打开adc通道2,并读取电压值
adc.setRange(adc.ADC_RANGE_MIN)

adc.open(2)
local data = adc.get(2)
adc.close(2)

log.info("adc读出值", data)
-- 此时读取的data值即为ADC电压值,但不是外部被测电压的实际值,外部电压的实际值需要再根据外部电压的分压比例进行换算;

-- 由于外部分压电阻的精度客观上存在误差,因此经外部电压的分压比换算而来的外部电压值可能与实际值存在一定的误差;

adc.close(id)

关闭adc通道

若需要持续读取, 则不需要close, ADC工作时的功耗大概是400uA左右;

若不需要持续读取,则需要close,否则ADC通道将浪费至少400uA左右;

参数

传入值类型 解释
int 通道id,,从0开始,共0-3四个硬件通道,ADC0通道ID为0,ADC1通道ID为1,ADC2通道ID为2,ADC3通道ID为3

返回值

例子

-- 设置adc.setRange(adc.ADC_RANGE_MIN)方式,打开adc通道2,并读取电压值
adc.setRange(adc.ADC_RANGE_MIN)
if adc.open(2) then
    log.info("adc", adc.read(2))
end
adc.close(2)
-- 若需要持续读取, 则不需要close, ADC工作时的功耗大概是400uA左右.

测量CPU温度和VBAT电压的完整示例

VBAT,或者写为vbat,也就是Air780EPM工作时的供电电压,对应Air780EPM的PIN42/PIN43;

adc.CH_VBATadc.CH_CPU不需要设置Range,在Air780EPM正常工作的 3.3V-4.3V 电压之间都可以正常测量;

-- 读取CPU温度, 单位为0.001摄氏度, 是内部温度, 非环境温度
adc.open(adc.CH_CPU)
local temp = adc.get(adc.CH_CPU)
adc.close(adc.CH_CPU)
-- adc.CH_CPU,CPU内部温度的通道id,内部通道,直接获取,不占用ADC 0-3,不外接任何电路

-- 读取VBAT供电电压, 单位为mV
adc.open(adc.CH_VBAT)
local vbat = adc.get(adc.CH_VBAT)
adc.close(adc.CH_VBAT)
-- adc.CH_VBAT,VBAT供电电压的通道id,内部通道,直接获取,不占用ADC 0-3,不外接任何电路

-- adc.CH_CPU 和 adc_CH_VBAT 在做读取动作之前,不需要像 ADC 0-3通道一样先打开adc.setRange(range)函数