4. Matter设备类型与nRF54外设映射

Matter规范把设备能力抽象成“设备类型(Device Type)”和“集群(Cluster)”,而nRF54系列芯片提供的是GPIO、PWM、ADC、I2C、SPI等物理外设。工程实现的核心工作,就是把集群属性/命令映射到具体外设通道,并保证状态可读、可写、可上报。本节以照明、温度传感器、门锁三类典型设备为例,说明映射关系与驱动实现要点。

一、设备类型到外设的映射总览

Matter中常见的设备类型包括:On/Off Light(开关灯)、Dimmable Light(调光灯)、Color Temperature Light(色温灯)、Temperature Sensor(温度传感器)、Door Lock(门锁)等。它们对应的集群与外设关系可以归纳为:

  • On/Off Light:OnOff集群 → GPIO输出(继电器/MOS驱动)。
  • Dimmable Light:LevelControl集群 → PWM占空比(0–254或0–1000映射到PWM比较值)。
  • Color Temperature Light:ColorControl集群 → 双路PWM(冷暖白光通道)或PWM+电流调节。
  • Temperature Sensor:TemperatureMeasurement集群 → ADC采样(NTC/PT1000或外部传感器)。
  • Door Lock:DoorLock集群 → GPIO(电机方向/使能)+ PWM(速度)+ GPIO输入(锁舌到位检测)。

映射不是“一个集群对一个外设”这么简单,而是“集群属性 ↔ 外设状态”的双向关系:命令下行改变外设输出,外设状态(如到位信号、ADC采样值)上行更新集群属性并触发Report。

Matter设备类型 ↔ nRF54外设映射关系 Matter 集群层 OnOff OnOff / Toggle LevelControl CurrentLevel 0–254 ColorControl ColorTempMireds TemperatureMeasurement MeasuredValue (0.01°C) DoorLock LockState / Lock/Unlock Attribute / Command nRF54 外设层 GPIO 输出 P1.00 继电器/MOS PWM PWM0 CH0 调光 PWM 双通道 PWM1 CH0/CH1 冷暖 SAADC AIN0 NTC分压采样 GPIO + PWM + GPIO 方向/速度/到位检测 Zephyr Device Driver API 命令下行 → 写GPIO Level → 占空比 Mireds → 双路PWM ADC → 温度属性上报 Lock/Unlock → 电机 到位信号 → LockState 蓝色箭头:命令/属性下行到外设;绿色箭头:外设状态上行到集群属性

二、照明类设备:GPIO与PWM驱动实现

以Dimmable Light为例,OnOff集群的OnOff属性映射到GPIO输出,LevelControl集群的CurrentLevel(0–254)映射到PWM占空比。nRF54系列使用Zephyr的PWM API,典型配置如下:

/* 设备树片段:nrf54l15dk.overlay */
&pwm0 {
    status = "okay";
    pinctrl-0 = <&pwm0_default>;
    pinctrl-names = "default";
};

&pinctrl {
    pwm0_default: pwm0_default {
        group1 {
            psels = <NRF_PSEL(PWM_OUT0, 1, 4)>;
        };
    };
};

/* 驱动层:CurrentLevel → PWM占空比 */
static int set_level(uint8_t level) {
    uint32_t pulse = (uint32_t)level * PWM_PERIOD_US / 254U;
    return pwm_set_dt(&pwm_led, PWM_USEC(PWM_PERIOD_US), PWM_USEC(pulse));
}

这里PWM_PERIOD_US取1000μs(1kHz),避免可见闪烁。CurrentLevel=0时pulse=0,灯灭;CurrentLevel=254时pulse≈1000μs,全亮。若使用Color Temperature Light,则用PWM0 CH0驱动暖白、CH1驱动冷白,ColorTempMireds(典型153–500)线性映射到两路占空比之和恒定、比例变化。

三、温度传感器:ADC采样与属性上报

TemperatureMeasurement集群的MeasuredValue以0.01°C为单位,例如2350表示23.50°C。nRF54的SAADC采集NTC分压电压后,需要经过“电压→电阻→温度”的换算。示例参数:NTC 10kΩ B=3950,分压上拉10kΩ,参考电压3.0V,12位采样。

/* ADC读取与换算示例 */
int16_t adc_raw;
adc_read(adc_dev, &adc_cfg, &adc_raw);

/* 电压 = raw / 4095 * 3.0V */
float v_ntc = (float)adc_raw / 4095.0f * 3.0f;
/* 电阻 = R_pull * v_ntc / (Vref - v_ntc) */
float r_ntc = 10000.0f * v_ntc / (3.0f - v_ntc);
/* B值公式:1/T = 1/T0 + ln(R/R0)/B */
float ln_r = logf(r_ntc / 10000.0f);
float inv_t = 1.0f/298.15f + ln_r / 3950.0f;
float temp_c = 1.0f / inv_t - 273.15f;
int16_t measured = (int16_t)(temp_c * 100.0f);

换算完成后写入MeasuredValue属性,并设置MinMeasuredValue/MaxMeasuredValue(如-4000~12500)。若温度变化超过ReportableChange(如50,即0.5°C),触发Matter Report上报。ADC采样建议开启过采样与均值滤波,降低噪声导致的属性抖动。

四、门锁类设备:多外设协同

DoorLock集群的LockState有Locked、Unlocked、NotFullyLocked等状态。nRF54上通常用三个外设协同:GPIO输出控制电机方向(正转上锁/反转开锁),PWM控制电机速度或软启动,GPIO输入读取锁舌到位开关。典型时序是:收到Lock命令→拉高方向GPIO→启动PWM→等待到位信号→停止PWM→更新LockState并上报。

到位检测建议使用GPIO中断加去抖(如20ms),避免机械抖动误判。若300ms内未检测到位,应进入NotFullyLocked状态并上报,便于上层App提示用户。门锁类设备对安全要求高,LockState的写入应校验用户权限(如DoorLock集群的OperatingMode与Credential),不能仅凭GPIO状态直接翻转。

五、映射实现中的关键检查点

  • 单位一致性:Matter属性单位与驱动物理量必须显式换算,如CurrentLevel 0–254、MeasuredValue 0.01°C、Mireds。
  • 方向定义:GPIO高电平对应“开”还是“关”,需在设备树和驱动中统一约定,并在文档中写明。
  • 状态回读:输出类外设(GPIO/PWM)应保留影子变量,避免只写不读导致属性与物理状态不一致。
  • 上报节流:ADC类属性应设置ReportableChange与最小上报间隔,防止频繁Report占用Thread带宽。
  • 异常处理:PWM启动失败、ADC超时、到位信号缺失都应映射到Matter的相应状态或事件,而不是静默忽略。
建议在项目初期先画一张“集群属性 ↔ 外设通道 ↔ 物理器件”的三列表格,作为设备树配置和驱动实现的对照依据,可显著减少后期联调时的映射错误。

把设备类型映射到外设,本质上是建立一条从Matter属性到物理世界的双向通道。照明类偏重输出精度与响应速度,传感器类偏重采样换算与上报策略,门锁类偏重多外设时序与安全校验。理解这三类差异后,再扩展到窗帘、风扇、温控器等设备类型时,映射方法是一致的:先确定集群属性,再选择外设通道,最后定义换算与状态回读逻辑。