Skip to content

第8章:硬件适配层应用——ADC ​

本章导读

前面所有输入(按键)都是"数字"的:按下/松开,两个值。但现实世界的传感器大多输出连续变化的模拟量——光线多亮?压力多大?电压多高?

**ADC(模数转换器)**就是把"连续电压"变成"数字"的桥梁。CC2530 自带 12 位 ADC,HAL 又把它封装成了一个 API。本章先对照原理图看 GEC2530 底板的传感器都接在哪些 ADC 通道,再动手完成"按键 → ADC 采样 → 屏幕显示 + 串口发送"的完整实验。

一、先看电路:GEC2530 底板的传感器(对照原理图) ​

打开原理图 Sheet 5(GPIO_SENSOR),可以看到 4 类传感器:

text
┌────────────────────────────────────────────────┐
│ 光敏传感器:R26(10K 可调) + R28(10K) + 光敏管 CS ── R30(0Ω) ── P0_5 │
│ DHT11 温湿度:J5 接口 ── R29(0Ω) ── P0_4(数字单总线)            │
│ 压力传感器:U6 MPXV5010GC6U(VOUT) ── R34(0Ω) ── P0_0              │
│ 三轴加速度:U7 MMA7455(I2C:SCL/SDI/SDO)─ R33/R35/R36(0Ω) ── P1_4/P1_7/P2_0 │
└────────────────────────────────────────────────┘
传感器型号信号类型接口引脚
光敏传感器光敏二极管 CS模拟电压(ADC)P0_5
温湿度传感器DHT11数字单总线P0_4
压力传感器MPXV5010GC6U(U6)模拟电压(ADC)P0_0
三轴加速度传感器MMA7455(U7)数字 I2CP1_4 / P1_7 / P2_0

重点理解:

  1. 哪些走 ADC? 只有输出"连续电压"的传感器才需要 ADC:光敏(P0_5)和压力(P0_0)。DHT11、MMA7455 是数字接口(单总线/I2C),芯片内部自己完成了转换,直接读数据即可;
  2. 光敏电路怎么工作的? 光敏管 CS 的阻值随光照变化 → 与 R26/R28 分压 → P0_5 上的电压随光照变化 → ADC 把电压变成数字。调节 R26(可调电阻)可以改变采样范围;
  3. 与 TI 原版板子的差异(易错点):原站实验代码用 HAL_ADC_CHANNEL_7(P0_7)读光敏,那是 TI 官方板的接法;GEC2530 底板的光敏在 P0_5(通道 5)——写代码时务必按自己板子的原理图选通道。

二、HAL ADC API 简介 ​

HAL 提供了完善的 ADC 驱动 API,定义在 hal_adc.h / hal_adc.c 中。

① 核心 API:HalAdcRead() ​

c
/*
 * 在指定分辨率下读取指定 ADC 通道的值
 *
 * @param channel    - 通道号 0 ~ 7,分别对应 CC2530 的 P0_0 ~ P0_7 引脚
 * @param resolution - 采样精度(分辨率)
 */
extern uint16 HalAdcRead ( uint8 channel, uint8 resolution );

一次调用,完成"选通道 + 启动采样 + 读结果"三件事——HAL 把寄存器操作全封装了。

② 分辨率参数(resolution) ​

c
#define HAL_ADC_RESOLUTION_8   0x01   // 8 位精度
#define HAL_ADC_RESOLUTION_10  0x02   // 10 位精度
#define HAL_ADC_RESOLUTION_12  0x03   // 12 位精度
#define HAL_ADC_RESOLUTION_14  0x04   // 14 位精度

ADC 分辨率宏定义

分辨率越高,数字越精细(8 位范围 0~255,12 位范围 0~4095),但转换时间略长。普通传感器 8~10 位够用。

③ 通道参数(channel) ​

c
#define HAL_ADC_CHANNEL_0  0x00   // P0_0(GEC2530:压力传感器)
#define HAL_ADC_CHANNEL_1  0x01   // P0_1
#define HAL_ADC_CHANNEL_2  0x02   // P0_2
#define HAL_ADC_CHANNEL_3  0x03   // P0_3
#define HAL_ADC_CHANNEL_4  0x04   // P0_4
#define HAL_ADC_CHANNEL_5  0x05   // P0_5(GEC2530:光敏传感器)
#define HAL_ADC_CHANNEL_6  0x06   // P0_6
#define HAL_ADC_CHANNEL_7  0x07   // P0_7

ADC 通道宏定义

通道号 = 引脚号:HAL_ADC_CHANNEL_5 就是采 P0_5 的电压。对照上面的原理图:GEC2530 底板读光敏用 CHANNEL_5,读压力用 CHANNEL_0。

④ 使用示例 ​

用 8 位精度采光敏传感器(P0_5)的值:

c
uint8 adcVal;
adcVal = HalAdcRead( HAL_ADC_CHANNEL_5, HAL_ADC_RESOLUTION_8 );

三、ADC 实验:按键触发采样并显示 ​

实验目标 ​

结合按键、LED、显示屏、串口、ADC:按下按键 → ADC 采样光敏(P0_5)→ LED 闪烁 → 采样值显示到 LCD + 发送到串口。

第 1 步:包含头文件 ​

c
#include "hal_adc.h"

第 2 步:在按键处理函数中添加代码 ​

在应用层的按键处理函数 zclSampleSw_HandleKeys() 中添加:

c
static void zclSampleSw_HandleKeys( byte shift, byte keys ) {
    UI_MainStateMachine(keys);

    if ( keys & HAL_KEY_SW_1 ) {   // 按下 S3
        uint8 adcVal;
        char adcStr[30];

        /* 读取 P0_5 光敏传感器的 ADC 值(GEC2530 底板:通道5) */
        adcVal = HalAdcRead( HAL_ADC_CHANNEL_5, HAL_ADC_RESOLUTION_8 );

        /* 闪烁 LED(红绿蓝三色演示) */
        HalLedBlink(HAL_LED_1, 10, 50, 400);   // LED1
        HalLedBlink(HAL_LED_2, 10, 50, 1000);  // LED2
        HalLedBlink(HAL_LED_3, 10, 50, 2000);  // LED3

        /* 格式化数据到字符串 */
        sprintf(adcStr, "ADC: %d\n", adcVal);

        /* 在 LCD 第 4 行显示 ADC 值 */
        HalLcdWriteString(adcStr, HAL_LCD_LINE_4);

        /* 通过串口发送到串口助手 */
        HalUARTWrite(HAL_UART_PORT_0, (uint8 *)adcStr, osal_strlen(adcStr));
    }
}

代码逐行解析:

代码做了什么
HalAdcRead(HAL_ADC_CHANNEL_5, HAL_ADC_RESOLUTION_8)采 P0_5 光敏电压,8 位精度,得 0~255
HalLedBlink(...)三个 LED 以不同周期闪烁,直观反馈"按键生效了"
sprintf(adcStr, "ADC: %d\n", adcVal)把数值格式化成字符串
HalLcdWriteString(adcStr, HAL_LCD_LINE_4)显示到屏幕第 4 行
HalUARTWrite(...)发给串口助手

⚠️ 注意通道号:这里用 HAL_ADC_CHANNEL_5(P0_5),因为 GEC2530 底板的光敏接在 P0_5(原理图 Sheet 5)。如果照抄 TI 官方例程的 CHANNEL_7,读到的会是红外 LED 相关引脚,数值不对。换板子先查原理图!

第 3 步:编译下载验证 ​

  1. Rebuild All 编译 → 烧录到 GEC2530 开发板;
  2. 串口助手配置:115200 / 8 / None / 1 / None;
  3. 按下按键 S3,观察:
    • LCD 第 4 行显示 ADC: xx;
    • 串口助手收到 ADC: xx(每次按键一条);
    • 三个 LED 依次闪烁。

串口助手收到 ADC 数值

用手遮挡/照亮光敏传感器,再按按键,会发现 ADC 值明显变化——光照越强,光敏管阻值越小,P0_5 电压越低,ADC 值越小(具体方向以实际电路分压为准)。这就是"传感器 → 模拟电压 → 数字"的完整链路。

四、小结 ​

问题答案
GEC2530 哪些传感器走 ADC?光敏(P0_5)、压力(P0_0);DHT11/加速度是数字接口
光敏传感器接在哪个通道?P0_5 = HAL_ADC_CHANNEL_5(注意与 TI 板的 P0_7 不同)
ADC 核心 API?HalAdcRead(channel, resolution) 一次搞定采样
分辨率有哪些?8 / 10 / 12 / 14 位(HAL_ADC_RESOLUTION_8 等)
通道号怎么记?通道号 = 引脚号:CHANNEL_5 ↔ P0_5
实验结果怎么看?LCD 第 4 行 + 串口助手都显示 ADC: xx,随光照变化

一句话总结:ADC 让协议栈"看得见"模拟世界——GEC2530 底板的光敏(P0_5)、压力(P0_0)接在 ADC 通道上,HAL 一个 HalAdcRead() 就把电压变成了数字,再配合 LCD 显示、串口发送,就是完整的"采集 → 处理 → 展示"传感器节点雏形。

课堂练习:ADC ​

依据第8章:GEC2530 传感器电路、HalAdcRead、通道/分辨率作答。点击选项即可作答、即时反馈对错。

传感器电路、HalAdcRead、通道与分辨率

1 GEC2530 底板上,光敏传感器接在哪个 ADC 通道?

2 GEC2530 底板哪些传感器走 ADC?

3 HalAdcRead(HAL_ADC_CHANNEL_5, HAL_ADC_RESOLUTION_8) 中的两个参数分别代表?

4 8 位分辨率下,ADC 转换结果的范围是?

5 关于 ADC 通道号,最方便的记法是?

已完成 0 / 5 题

内容来源:紫甲 IoT《ZigBee 3.0 开发指南》第三部分·第8章,经本站整理优化以便于理解,电路部分已对照 GEC2530 开发板底板原理图核对(光敏通道已由原站 P0_7 更正为 GEC2530 底板的 P0_5);原站链接

aioteer · 物联网专业课程群

💬AI 伴学配置