目录
本系列博客,理论上适用于合宙的Air202、Air268、Air720x、Air720S以及最近发布的Air720U(我还没拿到样机,应该也能支持)。
先不管支不支持,如果你用的是合宙的模块,那都不妨一试,也许会有意外收获
我使用的是Air720SL模块,如果在其他模块上不能用,那就是底层core固件暂时还没有支持,这里的代码是没有问题的。例程仅供参考!
一、前言
GPIO的输入和输出我们已经讲完了,大家只要认真看过我的前几篇博客,相信掌握GPIO是使用方法不是什么难事
上篇博文我们讲到了,数字量输入采集
也就是GPIO输入
,数字量采集只能采集一些开关量,这可以解决绝大部分的问题,但是数字量采集也不是万能的,在遇到某些特殊的传感器时,也会感到无能为力
不是所有的传感器都是数字量输出的,也是有很多传感器是模拟量输出的,那到底什么是模拟量呢
- 模拟量传感器发出的是连续信号,用电压、电流、电阻等表示被测参数的大小。比如
温度传感器、压力传感器、光敏电阻、声敏电阻
等都是常见的模拟量传感器
既然这类模拟量传感器输出的是模拟信号,那么就不能使用常规的数字量输入功能进行采集,需采用新的功能
ADC模数转换
进行采集
- ADC是Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。
- 典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。
在单片机上实现模拟量采集有如下两种方法
- 在某些单片机上没有ADC硬件接口,比如STC89C51就没有硬件ADC接口。如果想要实现模拟量采集就需要用AD采集芯片,ADC0804就是一种逐次比较型的A/D转换器,它可以把模拟量信号转化为数字量信号,被单片机读取,而不需要单片机具有硬件ADC功能。不过这种ADC采用并口通讯,比较占用普通IO口,GPIO不足的情况还可以使用ET2046采集,这款芯片通讯占用IO较少,价格也相对较高。
- 还有一种就是硬件ADC功能,比如我们的合宙AIR720SL就带了两路硬件ADC采集功能,如果两路不够用的话,还可以使用ET2046进扩充,至于怎么扩充这里就不做讲解了,大家自行了解,下面我们开始来重点讲Air720SL的硬件ADC使用功能
二、了解Air720SL硬件设计手册adc部分
打开Air720Sl硬件设计手册找到如下部分
这里要注意的是,Air720SL系列芯片ADC和Air720x系列芯片这两者的电气特性不一样,测量范围也不一样,不要搞错了,否者会烧坏芯片
因为我现在还在老家出不去,没有设备供我具体测试,所以等会我就只测量GND看是否有反应,精度也没法测试,测量结果不具有代表性
具体使用的话,还是需要自己参考设计手册另行测试的
三、编写测试程序
Air720SL拥有两路硬件ADC功能,分别是GPIO62对应ADC0,GPIO63对应ADC1,两者的电气特性完全一致,分辨率也都是12位
首先使用前我们需要包含官方提供的adc驱动库
require "adc"
,然后才可以使用相关库函数ADC0的测试程序如下
local function ADC0_Task()
local adcValue, voltValue = 0, 0
local result = adc.open(0)--打开ADC通道0
while true do
log.info("ADC0_Task", "ADC0_Task_run")
adcValue, voltValue = adc.read(0)--读取通道0的值
--adc.read接口返回的voltval放大了3倍,所以需要除以3还原成原始电压
if adcValue ~= 0xffff then
log.info("ADC 0的原始测量数据和电压值:", adcValue, voltValue)
end
sys.wait(1000)
end
adc.close(0)
end
ADC1的测试程序如下
local function ADC1_Task()
local adcValue, voltValue = 0, 0
local result = adc.open(1)
while true do
log.info("ADC1_Task", "ADC1_Task_run")
adcValue, voltValue = adc.read(1)
if adcValue ~= 0xffff then
log.info("ADC 1的原始测量数据和电压值:", adcValue, voltValue)
end
sys.wait(1000)
end
adc.close(1)
end
可以看出来,官方的库封装的很简洁,只需要三个函数就能实现模拟量采集
ADC0的测试代码和ADC1的测试代码几乎完全一样,没有什么区别,下面我们直接下载完整的测试程序进行测试
# 四、下载完整的代码到Air720Sl开发板
这里我们直接贴出全部代码
--必须在这个位置定义PROJECT和VERSION变量
--PROJECT:ascii string类型,可以随便定义,只要不使用,就行
--VERSION:ascii string类型,如果使用Luat物联云平台固件升级的功能,必须按照"X.X.X"定义,X表示1位数字;否则可随便定义
PROJECT = "LED"
VERSION = "0.0.1"
require "sys"
--加载日志功能模块,并且设置日志输出等级
--如果关闭调用log模块接口输出的日志,等级设置为log.LOG_SILENT即可
require "log"
LOG_LEVEL = log.LOGLEVEL_TRACE
--[[
如果使用UART输出日志,打开这行注释的代码"--log.openTrace(true,1,115200)"即可,根据自己的需求修改此接口的参数
如果要彻底关闭脚本中的输出日志(包括调用log模块接口和Lua标准print接口输出的日志),执行log.openTrace(false,第二个参数跟调用openTrace接口打开日志的第二个参数相同),例如:
1、没有调用过sys.opntrace配置日志输出端口或者最后一次是调用log.openTrace(true,nil,921600)配置日志输出端口,此时要关闭输出日志,直接调用log.openTrace(false)即可
2、最后一次是调用log.openTrace(true,1,115200)配置日志输出端口,此时要关闭输出日志,直接调用log.openTrace(false,1)即可
]]
--log.openTrace(true,1,115200)
require "adc"
local function ADC0_Task()
local adcValue, voltValue = 0, 0
local result = adc.open(0)--打开ADC通道0
while true do
log.info("ADC0_Task", "ADC0_Task_run")
adcValue, voltValue = adc.read(0)--读取通道0的值
--adc.read接口返回的voltval放大了3倍,所以需要除以3还原成原始电压
if adcValue ~= 0xffff then
log.info("ADC 0的原始测量数据和电压值:", adcValue, voltValue)
end
sys.wait(1000)
end
adc.close(0)
end
local function ADC1_Task()
--初始化GPIO 比如GPIO_38
local adcValue, voltValue = 0, 0
local result = adc.open(1)
while true do
log.info("ADC1_Task", "ADC1_Task_run")
adcValue, voltValue = adc.read(1)
if adcValue ~= 0xffff then
log.info("ADC 1的原始测量数据和电压值:", adcValue, voltValue)
end
sys.wait(1000)
end
adc.close(1)
end
local function user_main()
sys.taskInit(ADC0_Task)
sys.taskInit(ADC1_Task)
end
--启动系统框架
sys.taskInit(user_main)
sys.init(0, 0)
sys.run()
下载程序后,我们将ADC0和ADC1的引脚同时接地引脚在这
能够看到ADC1成功检测到了低电平,输出的数据是0。而ADC0却没有任何反应.。
这里我也分开单独测试过均没有测试成功。也许是官方的底层固件出了bug,目前我使用的是v0008版本的固件,下个版本也许会修复这个问题,使用的话建议暂时避开ADC0
四、总结
1、官方的adc库函数
- adc.open(0)–打开ADC通道0
- adcValue, voltValue = adc.read(0)–读取通道0的值,读取之前必须先打开ADC0
- adc.close(0)–关闭ADC通道0
- ADC1的使用方法与ADC0一直,换个参数即可
不会下载的点击这里,进去查看我的第二篇博文
2、Air720SL模块Luat开发:第一个Luat的Hello World
里面讲了怎么下载
这里只是我的学习笔记,拿出来给大家分享,欢迎大家批评指正,本篇教程到此结束