找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2123

积分

0

好友

271

主题
发表于 5 小时前 | 查看: 0| 回复: 0

一、按键驱动

1.1 按键引脚

合宙Air780E开发板的按键引脚定义可以参考其原理图。通常,一个用户可用的按键会连接到某个特定的GPIO引脚上。

合宙Air780EGH芯片引脚连接原理图

根据原理图,引脚19对应GPIO22,这个引脚常被用作按键输入。

1.2 测试代码

接下来,我们编写Lua代码来测试这个按键。代码的核心是将GPIO22配置为上拉输入模式,然后循环读取其电平状态。

-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "Key"
VERSION = "1.0.0"
-- 引入必要的库文件(lua编写), 内部库不需要require
sys = require(“sys”)
--=============================================================
log.info(“按键输入,打印引脚电平”)
local key0 = 22
gpio.setup(key0, nil,gpio.PULLUP)
--=============================================================
function KeyFun()
    while 1 do
        local resalt=gpio.get(key0)
        --log.info(“GPIO22的电平=“,resalt)
        if resalt==1 then
            log.info(“key0 是高电平,值=“,resalt)
            --sys.wait(500)
        else
            log.info(“key0 是低电平,值=“,resalt)
            --sys.wait(500)
        end
        sys.wait(1000)
    end   
end
--=============================================================
sys.taskInit(KeyFun)
--=============================================================
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

这段代码逻辑清晰:初始化GPIO后,在一个循环任务中每秒读取一次引脚电平,并通过日志打印出来。按键未按下时,由于上拉电阻的作用,引脚为高电平(1);按下按键连接到地时,引脚变为低电平(0)。在计算机基础知识中,理解这种上拉输入电路是进行嵌入式嵌入式开发的基础。

1.3 测试结果

将代码烧录到Air780E开发板并运行,通过串口工具查看日志输出。

当按键未按下时,输出如下高电平信息:
按键未按下时串口输出高电平信息

当按下按键时,输出变为低电平信息:
按键按下时串口输出低电平信息

二、模数转换(ADC)功能

2.1 引脚原理图和相关说明

模数转换器(ADC)是嵌入式系统中用于采集模拟信号(如电压、温度)的关键模块。在合宙Air780E上,ADC1对应引脚96。

合宙Air780E开发板ADC1引脚原理图

什么是ADC?
模拟到数字转换器(Analog-to-Digital Converter),它是一种电子设备或模块,用于将连续变化的模拟信号转换为离散的数字信号,以便数字系统(如MCU)能够对其进行处理和分析。

ADC关键指标
对于某个确定的模组,其ADC分辨率通常是固定的(合宙主流模组多为12bit),但电压输入范围可能在不同条件下有所调整。这主要涉及两个常量:

  • adc.ADC_RANGE_MIN: 对应量程为0-1.5V
  • adc.ADC_RANGE_MAX: 对应量程为0-3.6V(Air8101为0-2.4V)

ADC相关常量定义说明

量程选择准则
官方文档给出了明确的量程选择建议:

  1. 当被测电压最大值在1.5V以内,使用adc.ADC_RANGE_MIN
  2. 当被测电压大于1.5V但小于3.6V(Air8101小于2.4V),使用adc.ADC_RANGE_MAX,且不添加外部分压电路。
  3. 当被测电压最高值在3.6V以上(Air8101在2.4V以上)时,必须使用adc.ADC_RANGE_MIN,并添加外部分压电路将电压降至1.5V量程内。

特别注意adc.setRange(range)函数必须在adc.open(id)之前调用,否则设置无效。

ADC通道ID映射
不同型号的合宙模组,其外部ADC引脚与通道ID的对应关系如下:

  • Air780E系列/Air8000系列:ADC0对应通道ID 0,ADC1对应ID 1,ADC2对应ID 2,ADC3对应ID 3。
  • Air8101系列:内部具有更多ADC通道,例如ADC1对应通道ID 1,具体映射关系需参考详细手册。

内部专用通道
除了外部引脚,ADC模块还提供了两个内部通道,用于读取芯片内部信息,无需外接电路:

  • adc.CH_CPU: 用于读取CPU内部温度,单位为千分之一摄氏度。
  • adc.CH_VBAT: 用于读取VBAT供电电压,单位为mV。
    读取这两个通道前,不需要调用adc.setRange(range)函数。

2.2 API函数详解

LuatOS为ADC操作提供了一组简洁的Lua API。

ADC核心函数列表

1. adc.open(id)
打开指定的ADC通道。
adc.open(id)函数详细说明

2. adc.setRange(range)
设置ADC的测量范围。必须在adc.open之前调用!
adc.setRange(range)函数详细说明

3. adc.read(id)
读取ADC通道的原始值和计算值。通常我们更关心计算值(data1),单位是mV。
adc.read(id)函数详细说明

4. adc.get(id)
获取ADC通道的计算值。这是adc.read(id)的简化版,只返回计算值。对于adc.CH_CPU通道,返回的是温度值。
adc.get(id)函数详细说明

5. adc.close(id)
关闭ADC通道。如果不需要持续读取,应关闭通道以降低功耗(约400uA)。
adc.close(id)函数详细说明

2.3 测试代码

我们编写两个测试例程,分别演示基础用法和循环读取多种数据。

测试代码1:基础顺序读取
此代码依次读取CPU温度、VBAT电压和外部ADC1引脚电压。

-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = “ADC”
VERSION = “1.0.0”
-- sys库是标配
sys = require(“sys”)
--=============================================================
local adcx = 1
local function MY_ADC()
-- 读取CPU温度, 单位为0.001摄氏度, 是内部温度, 非环境温度
    while 1 do
    sys.wait(1000)
    adc.open(adc.CH_CPU)
    local temp = adc.get(adc.CH_CPU)
    log.info(“CPU温度=“,temp/1000)
--adc.close(adc.CH_CPU)
-- adc.CH_CPU,CPU内部温度的通道id,内部通道,直接获取,不占用ADC 0-3,不外接任何电路
-- 读取VBAT供电电压, 单位为mV
--=============================================================
    sys.wait(1000)
    adc.open(adc.CH_VBAT)
    local vbat = adc.get(adc.CH_VBAT)
    log.info(“VBAT供电电压“,vbat/1000)
    --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)函数
--=============================================================
    sys.wait(1000)
--修改IO电平,都可以通过LuatOS软件设置为1.8V/2.8V/3.0V/3.3V
    pm.ioVol(pm.IOVOL_ALL_GPIO, 3300) 
-- 设置ADC引脚的测量范围0-3.6V,这种方式被测电压不可经过外部电阻分压后再挂在ADC上;
    adc.setRange(adc.ADC_RANGE_MAX)
-- 打开adc通道1,并读取
    adc.open(adcx) 
    local ADC_Value=adc.get(adcx)
    log.info(“adc1=“, ADC_Value,“mV”) -- 返回电压值;
--=============================================================
    end
end
--=============================================================
sys.taskInit(MY_ADC)
--=============================================================
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

测试代码2:状态机循环读取
这个代码使用一个简单的状态机(step变量),循环轮流读取三种数据,结构更紧凑。

-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = “ADC”
VERSION = “1.0.0”
-- sys库是标配
sys = require(“sys”)
--=============================================================
local adcx = 1
local function MY_ADC()
    local step=0
-- adc.CH_CPU,CPU内部温度的通道id,内部通道,直接获取,不占用ADC 0-3,不外接任何电路
-- adc.CH_VBAT,VBAT供电电压的通道id,内部通道,直接获取,不占用ADC 0-3,不外接任何电路
-- adc.CH_CPU 和 adc_CH_VBAT 在做读取动作之前,不需要像 ADC 0-3通道一样先打开adc.setRange(range)函数
    adc.open(adc.CH_CPU)
    adc.open(adc.CH_VBAT)
    pm.ioVol(pm.IOVOL_ALL_GPIO, 3300) -- 设置ADC引脚的测量范围0-3.6V,这种方式被测电压不可经过外部电阻分压后再挂在ADC上;
    adc.setRange(adc.ADC_RANGE_MAX)
    -- 打开adc通道1
    adc.open(adcx) 
    while true do
        sys.wait(1000)
        log.info(“step =“,step)
        if step == 0 then
            local temp = adc.get(adc.CH_CPU)
            log.info(“CPU温度=“,temp/1000)
            step = 1 
        elseif step == 1 then
            local vbat = adc.get(adc.CH_VBAT)
            log.info(“VBAT供电电压“,vbat/1000)
            step = 2
        elseif step == 2 then
            local ADC_Value=adc.get(adcx)
            log.info(“adc1=“, ADC_Value,“mV”) -- 返回电压值;
            step = 0
        else
            step = 0
        end
    end
end
--=============================================================
sys.taskInit(MY_ADC)
--=============================================================
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

2.4 测试结果

将ADC1引脚先后接地(GND)和接3.3V电源,运行上述任一测试代码,通过串口日志可以观察到电压值的变化。

ADC测试结果日志截图

从日志中可以看到:

  • VBAT供电电压在4.017V左右,这是板子的供电电压。
  • 当ADC1接地时,adc1读取值为0 mV。
  • 当ADC1接3.3V时,adc1读取值约为3309 mV,与预期相符(存在微小偏差属于正常现象)。
  • CPU温度稳定在27摄氏度左右。

总结

通过本文的实践,我们掌握了在合宙Air780E开发板上使用LuatOS驱动GPIO按键和ADC模块的基本方法。从引脚识别、代码编写到结果验证,完成了完整的开发流程。GPIO输入是检测数字开关信号的基础,而ADC则为连接各类模拟传感器(如光照、压力、温度传感器)打开了大门,是嵌入式开发中至关重要的技能。希望这篇教程能帮助你快速上手。更多深入的技术讨论和项目分享,欢迎访问云栈社区与广大开发者交流。

参考




上一篇:DeepAudit:如何利用开源多智能体系统实现自动化代码审计与漏洞挖掘?
下一篇:Redis部署模式详解:从单实例到集群架构演进与选型指南
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-24 17:28 , Processed in 0.239014 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表