22 极物科技 | DALI协议栈 - 特殊命令与设备发现机制

极物科技 | DALI协议栈 - 特殊命令与设备发现机制

前言

在智能控制领域,"协议壁垒"与"系统稳定性"始终是绕不开的难题。极物科技(Zeewo)以 "重构空间交互体验" 为使命,通过自研的 极物 OS,实现了 KNX、DALI、CAN、RS485 等多种总线协议在单一主机上的深度融合。

我们认为,一个真正优秀的智能系统,不仅要实现灯光、遮阳、温控、音乐、安防等全生态设备的无界融合 ,更要确保本地运行、断网可用 ,并具备WEB 远程调试OTA 固件升级的能力。基于此底层架构,我们推出了诸如带双路 DALI 的 KNX 主机、HomeKit 网桥等核心硬件,并将极物 OS 成功接入了 Apple HomeKit、小度、纯血鸿蒙及 HomeAssistant 等主流生态系统。

一句话概述:本文深入解析极物 DALI 协议栈特殊命令与设备发现机制的完整实现。

本文聚焦于 DALI 特殊命令集(0xA1-0xC9)与设备发现流程,涵盖 INITIALISE 初始化窗口、RANDOMISE 随机地址生成、COMPARE 地址比较、WITHDRAW 退出竞争、PROGRAM_SHORT_ADDRESS 短地址编程等核心命令,展示 DALI 总线如何为多个从设备自动分配唯一短地址。


1. 特殊命令总览

1.1 命令列表

命令地址 命令名称 功能说明
0xA1 TERMINATE 终止初始化窗口
0xA3 DATA_TRANSFER_REGISTER 设置 DTR0
0xA5 INITIALISE 启动初始化窗口(15分钟)
0xA7 RANDOMISE 生成随机地址
0xA9 COMPARE 比较随机地址
0xAB WITHDRAW 匹配设备退出竞争
0xAD PING 忽略(主设备存在指示)
0xB1 SEARCHADDRH 设置搜索地址高字节
0xB3 SEARCHADDRM 设置搜索地址中字节
0xB5 SEARCHADDRL 设置搜索地址低字节
0xB7 PROGRAM_SHORT_ADDRESS 编程短地址
0xB9 VERIFY_SHORT_ADDRESS 验证短地址
0xBB QUERY_SHORT_ADDRESS 查询短地址
0xC1 ENABLE_DEVICE_TYPE 启用设备类型
0xC3 DATA_TRANSFER_REGISTER_1 设置 DTR1
0xC5 DATA_TRANSFER_REGISTER_2 设置 DTR2
0xC7 WRITE_MEMORY_LOCATION 写入内存位置(应答)
0xC9 WRITE_MEMORY_LOCATION_NO_REPLY 写入内存位置(不应答)

1.2 特殊命令特征

  • 使用地址字节传输:S 位为 0,命令值在地址字节中
  • 地址范围:0xA1 ~ 0xC9
  • 需要重复帧:部分命令需要两帧相同数据才生效
  • 依赖初始化窗口:部分命令仅在 15 分钟窗口内有效

2. 特殊命令处理入口

c 复制代码
uint16_t dali_cmd_process_special(dali_slave_service_info_t *slave_info, uint8_t repeat_flag) {
    uint16_t ret = ANSWER_NO;
    uint8_t temp_short_addr;
    uint8_t temp = 0;
    uint8_t enable_device_cmd = 0;
    uint32_t temp_random_addr, temp_search_addr;
    bool reply_flag = false;
    
    // 部分命令仅在初始化窗口内有效
    if ((slave_info->rec_addr >= RANDOMISE) && (slave_info->rec_addr <= QUERY_SHORT_ADDRESS)) {
        if (w15min_waiting_time == 0) {
            return ret;  // 窗口已关闭,不响应
        }
    }
    
    // 特殊命令处理
    switch (slave_info->rec_addr) {
        // ... 各命令处理
    }
    
    return ret;
}

3. 初始化窗口管理

3.1 INITIALISE 命令 (0xA5)

功能:启动 15 分钟初始化窗口。

c 复制代码
case INITIALISE:
    if (repeat_flag == false) {
        return RECEIVE_FIRST;  // 需要重复帧
    }
    
    if (slave_info->rec_data == 0) {
        temp = 1;  // 广播初始化,所有设备响应
    } else if (slave_info->rec_data == ADDR_MASK) {
        // 仅未编址设备响应
        if (dali_ram.variable.short_address == ADDR_MASK) {
            temp = 1;
        }
    } else if ((slave_info->rec_data & 0x81) == 0x01) {
        // 指定短地址的设备响应
        if (temp_short_addr == dali_ram.variable.short_address) {
            temp = 1;
        }
    }
    
    if (temp) {
        w15min_waiting_time = W15MIN;  // 启动 15 分钟窗口
    } else {
        w15min_waiting_time = 0;
    }
    break;

三种初始化模式

rec_data 值 模式 响应设备
0 广播初始化 所有设备
0xFF (ADDR_MASK) 未编址初始化 仅未编址设备
0AAA AAA1 指定地址初始化 仅指定地址设备

3.2 TERMINATE 命令 (0xA1)

功能:立即终止初始化窗口。

c 复制代码
case TERMINATE:
    w15min_waiting_time = 0;  // 关闭窗口
    break;

3.3 窗口超时

c 复制代码
#define W15MIN ((uint32_t)15 * (uint32_t)60 * (uint32_t)1000 * ONE_MS_TICK)

// 主循环中递减
if (w15min_waiting_time > 0) {
    w15min_waiting_time -= tick_ms;
}

4. 设备发现流程

4.1 发现流程概览

复制代码
1. TERMINATE          → 终止之前的初始化
2. INITIALISE (0)     → 启动 15 分钟窗口(所有设备)
3. RANDOMISE          → 所有设备生成随机地址
4. 循环二分查找:
   a. SEARCHADDRH/M/L → 设置搜索地址
   b. COMPARE         → 随机地址 ≤ 搜索地址的设备应答
   c. 主设备调整搜索地址(二分法)
   d. WITHDRAW        → 匹配的设备退出竞争
   e. PROGRAM_SHORT_ADDRESS → 分配短地址
5. 重复直到所有设备编址完成

4.2 RANDOMISE 命令 (0xA7)

功能:生成 24 bit 随机地址。

c 复制代码
case RANDOMISE:
    if (repeat_flag == false) {
        return RECEIVE_FIRST;
    }
    
    // 使用定时器值作为随机种子
    srand(dali_hal_get_seed0_value());
    dali_ram.variable.random_address.high = rand();
    dali_ram.variable.random_address.mid = rand();
    srand(dali_hal_get_seed1_value());
    dali_ram.variable.random_address.low = rand();
    
    update_flag |= VAR_UPDATE;
    break;

随机地址用途:每个设备生成唯一的 24 bit 随机数,用于寻址竞争。

4.3 SEARCHADDR 命令 (0xB1/0xB3/0xB5)

功能:设置搜索地址(主设备二分查找用)。

c 复制代码
case SEARCHADDRH:
    search_address.high = slave_info->rec_data;
    break;

case SEARCHADDRM:
    search_address.mid = slave_info->rec_data;
    break;

case SEARCHADDRL:
    search_address.low = slave_info->rec_data;
    break;

4.4 COMPARE 命令 (0xA9)

功能:比较随机地址与搜索地址。

c 复制代码
case COMPARE:
    if (withdraw == 0) {  // 未退出的设备才比较
        if (temp_random_addr <= temp_search_addr) {
            ret = ANSWER_YES;  // 应答
        }
    }
    break;

二分查找原理

复制代码
搜索地址 = 0x800000 (中间值)
  → 随机地址 ≤ 0x800000 的设备应答
  → 主设备检测到应答,缩小范围到 0x000000~0x800000
  → 继续二分,直到找到最小随机地址的设备

4.5 WITHDRAW 命令 (0xAB)

功能:匹配的设备退出竞争。

c 复制代码
case WITHDRAW:
    if (temp_random_addr == temp_search_addr) {
        withdraw = 1;  // 设置退出标志
    }
    break;

退出状态管理

c 复制代码
if (withdraw == 1) {
    if (w15min_waiting_time == 0) {  // 超时或终止
        withdraw = 0;  // 重置退出标志
    }
}

4.6 PROGRAM_SHORT_ADDRESS 命令 (0xB7)

功能:为匹配的设备分配短地址。

c 复制代码
case PROGRAM_SHORT_ADDRESS:
    if (slave_info->rec_data == ADDR_MASK) {
        // 删除短地址
        dali_ram.variable.short_address = ADDR_MASK;
        update_flag |= VAR_UPDATE;
        status_information |= MISSING_SHORT_ADDR;
    } else if (temp_random_addr == temp_search_addr) {
        // 匹配的设备
        if ((slave_info->rec_data & 0x01) == 0x01) {
            // 格式正确 (0AAA AAA1)
            dali_ram.variable.short_address = temp_short_addr;
            update_flag |= VAR_UPDATE;
            status_information &= ~MISSING_SHORT_ADDR;
        }
    }
    break;

4.7 VERIFY_SHORT_ADDRESS 命令 (0xB9)

功能:验证短地址是否正确。

c 复制代码
case VERIFY_SHORT_ADDRESS:
    if ((slave_info->rec_data & 0x81) == 0x01) {
        if (dali_ram.variable.short_address == temp_short_addr) {
            ret = ANSWER_YES;  // 验证通过
        }
    }
    break;

4.8 QUERY_SHORT_ADDRESS 命令 (0xBB)

功能:查询已分配的短地址。

c 复制代码
case QUERY_SHORT_ADDRESS:
    if (temp_random_addr == temp_search_addr) {
        ret = (dali_ram.variable.short_address << 1) | 0x01;
    }
    break;

返回格式0AAA AAA1 (短地址左移 1 位,最低位置 1)


5. 设备类型启用

5.1 ENABLE_DEVICE_TYPE 命令 (0xC1)

功能:启用后续扩展命令处理。

c 复制代码
case ENABLE_DEVICE_TYPE:
    if (slave_info->rec_data == dali_ram.variable.led_type || 
        slave_info->rec_data == dali_ram.variable.version_number) {
        device_enabled = true;
    }
    enable_device_cmd = 1;
    break;

重要性 :扩展应用命令 (224-255) 仅在 device_enabled = true 时才处理。

5.2 设备类型定义

c 复制代码
#define DEVICE_TYPE 255  // LED 模块
#define LIGHT_SOURCE LED_MODULES  // 6

6. DTR 寄存器设置

6.1 DATA_TRANSFER_REGISTER (0xA3)

c 复制代码
case DATA_TRANSFER_REGISTER:
    dtr0 = slave_info->rec_data;
    break;

6.2 DATA_TRANSFER_REGISTER_1 (0xC3)

c 复制代码
case DATA_TRANSFER_REGISTER_1:
    dtr1 = slave_info->rec_data;
    break;

6.3 DATA_TRANSFER_REGISTER_2 (0xC5)

c 复制代码
case DATA_TRANSFER_REGISTER_2:
    dtr2 = slave_info->rec_data;
    break;

7. 内存写入命令

7.1 WRITE_MEMORY_LOCATION (0xC7)

c 复制代码
case WRITE_MEMORY_LOCATION:
    reply_flag = true;  // 需要应答

case WRITE_MEMORY_LOCATION_NO_REPLY:
    if (write_memory_enabled == false) {
        break;  // 未启用写入
    }
    
    temp = 0;
    if (dtr1 == BANK1) {
        if (dtr0 < 0x02) {
            temp = 1;  // 只读内存
        } else if (dtr0 == 0x02) {
            temp = 2;  // 读/写内存(锁定字节)
        } else if ((dtr0 > 0x02) && (dtr0 <= 0x10)) {
            if (dali_ram.memory.bank1[2] == NOT_LOCK) {
                temp = 2;  // 可锁定内存
            }
        }
        
        if (temp > 0) {
            if (temp == 2) {
                dali_ram.memory.bank1[dtr0] = slave_info->rec_data;
                if (reply_flag) {
                    ret = slave_info->rec_data;  // 应答写入的值
                }
                update_flag |= BANK1_UPDATE;
            }
        }
        if (dtr0 < 0xFF) {
            dtr0++;  // 自动递增
        }
    }
    break;

7.2 写入权限控制

c 复制代码
// 必须先启用 WRITE_MEMORY
case ENABLE_WRITE_MEMORY:
    write_memory_enabled = true;
    break;

// 非 DTR/写入命令后自动禁用
if (write_memory_enabled == true) {
    if ((slave_info->rec_addr != DATA_TRANSFER_REGISTER) && 
        (slave_info->rec_addr != DATA_TRANSFER_REGISTER_1) && 
        (slave_info->rec_addr != DATA_TRANSFER_REGISTER_2) && 
        (slave_info->rec_addr != WRITE_MEMORY_LOCATION) && 
        (slave_info->rec_addr != WRITE_MEMORY_LOCATION_NO_REPLY)) {
        write_memory_enabled = false;
    }
}

7.3 Bank1 锁定机制

c 复制代码
#define NOT_LOCK 0x55
#define BANK1_LOCK_BYTE 0xFF

// 锁定字节在 bank1[2]
// 0x55 = 未锁定,可写入
// 0xFF = 已锁定,只读

8. 设备识别机制

8.1 IDENTIFY_DEVICE 命令 (37)

c 复制代码
case IDENTIFY_DEVICE:
    identify_flag = true;
    w10s_identify_time = W10S;  // 10 秒识别
    if (status_information & FADE_RUNNING) {
        fade_direction = FADE_DIRECT;  // 停止渐变
    }
    break;

8.2 识别闪烁

c 复制代码
void dali_hal_identify_device(void) {
    if (identify_delay-- == 0) {
        identify_delay = 10;
    } else {
        return;
    }
    
    // PWM 值在 0~0xFFF 之间循环
    if (identify_count == 0XFFF) {
        identify_count_flag = 0;
    } else if (identify_count == 0) {
        identify_count_flag = 1;
    }
    
    if (identify_count_flag) {
        identify_count++;
    } else {
        identify_count--;
    }
    
    dali_hal_update_pwm_output(identify_count);
    dali_hal_update_pwm_output_tc(identify_count);
}

效果:灯具亮度在 0~最大之间循环变化,持续 10 秒,便于现场识别设备。

8.3 识别中断条件

c 复制代码
if (identify_flag == true) {
    if ((slave_info->rec_data != RECALL_MIN_LEVEL) && 
        (slave_info->rec_data != RECALL_MAX_LEVEL) && 
        (slave_info->rec_data != IDENTIFY_DEVICE)) {
        identify_flag = false;  // 其他命令中断识别
        w10s_identify_time = 0;
    }
}

9. 完整设备发现示例

9.1 单设备发现

复制代码
主设备发送:
  1. TERMINATE
  2. INITIALISE (0)          → 设备启动 15 分钟窗口
  3. RANDOMISE               → 设备生成随机地址 0x123456
  4. SEARCHADDRH (0x80)
     SEARCHADDRM (0x00)
     SEARCHADDRL (0x00)      → 搜索地址 = 0x800000
  5. COMPARE                 → 0x123456 ≤ 0x800000 → 应答 YES
  6. 主设备缩小范围...
     最终搜索地址 = 0x123456
  7. WITHDRAW                → 设备匹配,设置 withdraw=1
  8. PROGRAM_SHORT_ADDRESS (0x0B)  → 分配短地址 5
  9. VERIFY_SHORT_ADDRESS (0x0B)   → 验证通过,应答 YES

9.2 多设备发现

复制代码
主设备发送:
  1. TERMINATE
  2. INITIALISE (0)          → 所有设备启动窗口
  3. RANDOMISE               → 设备 A: 0x123456, 设备 B: 0x789ABC
  
  第一轮:
  4. SEARCHADDRH/M/L (0x400000)
  5. COMPARE                 → A (0x123456 ≤ 0x400000) 应答
                               B (0x789ABC > 0x400000) 不应答
  6. 主设备检测到应答,继续二分查找 A
  7. ... 找到 A 的随机地址
  8. WITHDRAW                → A 退出竞争
  9. PROGRAM_SHORT_ADDRESS   → A 获得短地址 0
  
  第二轮:
  10. SEARCHADDRH/M/L (0x400000)
  11. COMPARE                → B (0x789ABC > 0x400000) 不应答
  12. 主设备调整搜索地址到 0x789ABC
  13. ... 找到 B 的随机地址
  14. WITHDRAW               → B 退出竞争
  15. PROGRAM_SHORT_ADDRESS  → B 获得短地址 1

10. 注意事项

  1. 初始化窗口:15 分钟窗口超时后,设备发现命令无效
  2. 重复帧要求:INITIALISE、RANDOMISE 需要两帧相同数据
  3. 随机地址唯一性:24 bit 随机地址冲突概率极低
  4. 二分查找效率:最多 24 次比较即可定位一个设备
  5. 短地址格式 :DTR0 中为 0AAA AAA1 格式,需右移 1 位
  6. device_enabled:扩展命令前必须先 ENABLE_DEVICE_TYPE
  7. 内存写入:必须先 ENABLE_WRITE_MEMORY,且 Bank1 需解锁
  8. 识别中断:除 RECALL MAX/MIN 和 IDENTIFY 外的命令会中断识别

11. 相关文档

  • 《极物科技 | DALI协议栈 - 架构总览与模块设计》
  • 《极物科技 | DALI协议栈 - 物理层位编解码详解》
  • 《极物科技 | DALI协议栈 - 帧传输状态机与地址解析》
  • 《极物科技 | DALI协议栈 - 标准命令集解析》
  • 《极物科技 | DALI协议栈 - 配置命令详解》
  • 《极物科技 | DALI协议栈 - 查询命令全解》
  • 《极物科技 | DALI协议栈 - DT8双色温扩展与PWM映射》
  • 《极物科技 | DALI调光灯 - 快速接入指南》
  • 《极物科技 | DALI调光灯 - 设备发现与地址分配机制》

关于极物科技(ZEEWO)

极物科技(Zeewo)致力于为用户提供智能控制系统及硬件产品。我们以总线系统为技术底座,以**"稳定、可靠、快速响应"**为产品底线,是国内少有的拥有 KNX、DALI 全套软硬件自主研发能力的厂商之一。

我们的核心能力:

  • 系统架构:自研极物 OS,支持多协议无界融合(KNX/DALI/CAN/RS485/IP)。
  • 核心硬件:带双路 DALI 的 KNX 主机、超薄全金属定制面板、各类智选传感器及网关。
  • 生态互联:深度融入 Apple HomeKit、Matter、小度、HomeAssistant 及纯血鸿蒙生态。
  • 调试交付:独家支持 ETS 导出 XML 直接导入进行 APP 免编程调试,支持远程 WEB 运维。

我们的市场覆盖:

服务网点已覆盖全国核心城市(含长三角、珠三角、成渝等),并以高品质的方案深耕家居生活、酒店民宿、企业办公、疗愈康养、餐馆会所等多个细分领域。

(如果您在开发或落地中遇到技术问题,欢迎通过官网或后台私信与我交流探讨)

相关推荐
阿钱真强道19 小时前
19 极物科技 | DALI协议栈 - 标准命令集解析
极物·极物智能·极物科技·iec 62386·调光控制·dali协议栈·标准命令
阿钱真强道21 小时前
17 极物科技 | DALI协议栈 - 物理层位编解码详解
曼彻斯特编码·极物·极物智能·极物科技·iec 62386·dali协议栈
阿钱真强道2 天前
16 极物科技 | DALI协议栈 - 架构总览与模块设计
智能家居·照明·极物·极物智能·极物科技·iec 62386·dali协议栈
阿钱真强道4 天前
11 极物科技 | DALI调光灯 - 功能接口与调试指南
智能照明·极物·极物智能·极物科技·dali调光灯·调光控制·调试指南
阿钱真强道4 天前
12 极物科技 | DALI调光灯 - 设备发现与地址分配机制
智能照明·极物·极物智能·极物科技·dali调光灯·设备发现·地址分配
阿钱真强道5 天前
09 极物科技 | DALI调光灯 - IEC 62386 底层协议解析
智能照明·总线协议·极物·极物智能·极物科技·dali调光灯·iec 62386
阿钱真强道6 天前
07 极物科技 | DALI调光灯 - 快速接入指南
智能照明·极物·极物智能·极物科技·dali调光灯·iec 62386·调光控制
阿钱真强道6 天前
08 极物科技 | DALI调光灯 - UDP 通讯协议规范
通讯协议·智能照明·极物·极物智能·极物科技·dali调光灯·iec 62386
阿钱真强道9 天前
06 极物科技 | 创明RS485窗帘 - UDP 通讯协议规范
udp·智能家居·通讯协议·极物·极物智能·极物科技·创明窗帘