25 极物科技 | DALI协议栈 - DT8双色温扩展与PWM映射


tags:

  • 极物
  • 极物智能
  • 极物科技
  • DALI协议栈
  • DT8双色温
  • PWM映射
  • 智能照明
  • 色温控制
  • IEC 62386
  • 嵌入式开发
    description: 本文深入解析极物DALI协议栈DT8双色温扩展与PWM映射实现,涵盖色温范围配置、TC_COLOR_VALUE命令解析、渐变状态机、12位PWM输出及标准调光曲线映射,展示从色温值到硬件PWM输出的完整转换过程。

极物科技 | DALI协议栈 - DT8双色温扩展与PWM映射

前言

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

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

一句话概述:本文深入解析极物 DALI 协议栈 DT8 双色温扩展与 PWM 映射实现,展示从色温值到硬件 PWM 输出的完整转换过程。

本文聚焦于 DALI DT8 双色温控制机制,涵盖色温范围配置、TC_COLOR_VALUE 命令解析、渐变状态机、12位 PWM 输出、标准调光曲线映射等核心内容。通过源码级剖析,帮助读者理解 DALI 从设备如何实现平滑的色温渐变控制。


1. DT8协议扩展概述

DALI DT8(Device Type 8)是DALI标准中针对彩色控制 的扩展协议,支持色温调节(Tc)、RGB控制、XY坐标等多种颜色控制模式。本文聚焦于双色温(Tc)控制的实现,这是智能照明中最常用的色温调节方案。

1.1 DT8在协议栈中的位置

DT8扩展命令属于应用扩展命令(Application Extended Commands),位于标准命令集之上:

c 复制代码
// dali_cmd.h - DT8色温命令定义
#define TC_COLOR_VALUE 231  // 0xE7,设置色温值命令

DT8命令通过DTR0+DTR1双字节传输机制传递16位色温值,这是与普通8位命令的关键区别。

1.2 双色温控制原理

双色温灯具通常包含两路LED:

  • 冷白光(Cold White):色温高,颜色偏白
  • 暖白光(Warm White):色温低,颜色偏黄

通过调节两路LED的PWM占空比比例,实现色温的连续调节:

复制代码
PWM值越大 → 冷白光占比越高 → 颜色越白
PWM值越小 → 暖白光占比越高 → 颜色越黄

二、色温值范围配置

2.1 四级色温范围机制

协议栈设计了四级色温范围,实现灵活的色温控制:

c 复制代码
// dali_cmd.h - 色温范围宏定义
#define TC_COLOR_MAX_COLD (496 / 2)  // 248,配置最冷色温
#define TC_COLOR_MAX_WARN (142 / 2)  // 71,配置最暖色温
c 复制代码
// dali_cmd.h - 变量结构体中的色温字段
struct var {
    uint8_t tc_config_maxwarn_level;   // 配置最暖色温(用户设定)
    uint8_t tc_config_maxcold_level;   // 配置最冷色温(用户设定)
    uint8_t tc_phy_maxwarn_level;      // 物理最暖色温(硬件极限)
    uint8_t tc_phy_maxcold_level;      // 物理最冷色温(硬件极限)
    uint8_t tc_target_level;           // 目标色温值
    uint8_t tc_scene[16];              // 16个场景的色温值
    uint8_t tc_powon_level;            // 上电色温
    uint8_t tc_fail_level;             // 故障色温
};

2.2 四级范围的含义

级别 字段 含义 用途
物理最暖 tc_phy_maxwarn_level 硬件能达到的最暖色温 硬件保护边界
物理最冷 tc_phy_maxcold_level 硬件能达到的最冷色温 硬件保护边界
配置最暖 tc_config_maxwarn_level 用户设定的最暖色温 应用层限制
配置最冷 tc_config_maxcold_level 用户设定的最冷色温 应用层限制

约束关系

复制代码
tc_phy_maxwarn_level ≤ tc_config_maxwarn_level ≤ tc_config_maxcold_level ≤ tc_phy_maxcold_level

2.3 色温范围初始化

设备复位时,色温范围初始化为默认值:

c 复制代码
// dali_cmd.c - 复位时色温初始化
case RESET:
    // tc init
    dali_ram.variable.tc_config_maxcold_level = TC_COLOR_MAX_COLD; // 248
    dali_ram.variable.tc_config_maxwarn_level = TC_COLOR_MAX_WARN; // 71
    dali_ram.variable.tc_phy_maxcold_level = TC_COLOR_MAX_COLD;    // 248
    dali_ram.variable.tc_phy_maxwarn_level = TC_COLOR_MAX_WARN;    // 71
    dali_ram.variable.tc_target_level = TC_COLOR_MAX_COLD;         // 默认最冷
    
    // 16个场景色温初始化为最冷
    for (i = 0; i < 16; i++) {
        dali_ram.variable.tc_scene[i] = dali_ram.variable.tc_config_maxcold_level;
    }
    dali_ram.variable.tc_powon_level = 100;  // 上电色温默认100
    break;

2.4 色温范围合法性校验

系统启动时进行色温范围校验,防止异常值:

c 复制代码
// dali_cmd.c - 色温范围校验
void dali_tc_range_check(void) {
    if (dali_ram.variable.tc_config_maxcold_level == 0xFF) {
        printf("error tc_config_maxcold_level \r\n");
        dali_ram.variable.tc_config_maxcold_level = TC_COLOR_MAX_COLD;
    }
    
    if (dali_ram.variable.tc_config_maxwarn_level == 0xFF) {
        printf("error tc_config_maxwarn_level \r\n");
        dali_ram.variable.tc_config_maxwarn_level = TC_COLOR_MAX_WARN;
    }
    
    if (dali_ram.variable.tc_phy_maxcold_level == 0xFF) {
        printf("error tc_phy_maxcold_level \r\n");
        dali_ram.variable.tc_phy_maxcold_level = TC_COLOR_MAX_COLD;
    }
    
    if (dali_ram.variable.tc_phy_maxwarn_level == 0xFF) {
        printf("error tc_phy_maxwarn_level \r\n");
        dali_ram.variable.tc_phy_maxwarn_level = TC_COLOR_MAX_WARN;
    }
}

三、TC_COLOR_VALUE命令解析

3.1 命令格式

TC_COLOR_VALUE(231/0xE7)是DT8色温控制的核心命令,采用DTR0+DTR1双字节传输16位色温值:

复制代码
DTR1 (高8位) | DTR0 (低8位) → 16位色温值
实际色温 = (DTR1 × 256 + DTR0) / 2

3.2 命令处理流程

c 复制代码
// dali_cmd.c - TC_COLOR_VALUE命令处理
case TC_COLOR_VALUE:
    // DTR1和DTR0组合成16位色温值,除以2得到实际色温
    dali_cmd_direct_arc_tc_control((dtr1 * 256 + dtr0) / 2);
    break;

示例

  • DTR1=0x01, DTR0=0x90 → (1×256 + 144) / 2 = 200
  • DTR1=0x00, DTR0=0x8C → (0×256 + 140) / 2 = 70

四、色温直接控制函数

4.1 dali_cmd_direct_arc_tc_control

这是色温控制的核心函数,负责将目标色温值转换为PWM输出:

c 复制代码
// dali_cmd.c - 色温直接控制函数
void dali_cmd_direct_arc_tc_control(uint8_t tc_level)
{
    uint32_t tc_current_value;
    uint32_t tc_target_level;
    uint32_t tc_level_change = 0;
    float tmp;

    // 1. 色温范围合法性检查
    if (dali_ram.variable.tc_config_maxwarn_level < dali_ram.variable.tc_phy_maxwarn_level) {
        return;
    }
    if (dali_ram.variable.tc_config_maxcold_level > dali_ram.variable.tc_phy_maxcold_level) {
        return;
    }
    if (dali_ram.variable.tc_config_maxwarn_level > dali_ram.variable.tc_config_maxcold_level) {
        return;
    }
    if (dali_ram.variable.tc_phy_maxwarn_level > dali_ram.variable.tc_phy_maxcold_level) {
        return;
    }

    // 2. 目标色温值限幅
    if (tc_level == 0) {
        dali_ram.variable.tc_target_level = 0;
    }
    else if (tc_level <= dali_ram.variable.tc_config_maxwarn_level) {
        dali_ram.variable.tc_target_level = dali_ram.variable.tc_config_maxwarn_level;
    }
    else if (tc_level >= dali_ram.variable.tc_config_maxcold_level) {
        dali_ram.variable.tc_target_level = dali_ram.variable.tc_config_maxcold_level;
    }
    else {
        dali_ram.variable.tc_target_level = tc_level;
    }

    // 3. 初始化色温渐变状态
    tc_fede_status.tc_dirction = FADE_IDLE;
    tc_fede_status.tc_step = 0;
    tc_fede_status.tc_target_vaule = 0;
    tc_fede_status.tc_current_vaule = 0;

    // 4. 色温值映射到PWM值
    tmp = (dali_ram.variable.tc_target_level - dali_ram.variable.tc_phy_maxwarn_level) / 
          (dali_ram.variable.tc_phy_maxcold_level - dali_ram.variable.tc_phy_maxwarn_level);
    tmp = tmp * PWM_CYSCLE;
    tc_target_level = tmp;
    tc_current_value = dali_hal_get_tc_value();

    // 5. 计算渐变方向和步进
    if (tc_current_value == tc_target_level) {
        tc_fede_status.tc_dirction = FADE_IDLE;
        return;
    }
    else {
        if (tc_target_level > tc_current_value) {
            tc_level_change = tc_target_level - tc_current_value;
            tc_fede_status.tc_dirction = FADE_TIME_UP;  // 变白,值变大
        }
        else {
            tc_level_change = tc_current_value - tc_target_level;
            tc_fede_status.tc_dirction = FADE_TIME_DOWN;  // 变黄,值变小
        }

        // 6. 根据渐变时间计算步进值
        if (tc_fade_time[dali_ram.variable.fade_time] != 0) {
            tmp = tc_fade_time[dali_ram.variable.fade_time] / TC_FADE_MS_CHANGE;
            tc_fede_status.tc_step = (tc_level_change) / tmp;
        }
        else {
            tc_fede_status.tc_dirction = FADE_DIRECT;  // 直接跳转
        }

        tc_fede_status.tc_current_vaule = tc_current_value;
        tc_fede_status.tc_target_vaule = tc_target_level;
    }
}

4.2 色温映射算法详解

核心映射公式:

c 复制代码
tmp = (tc_target_level - tc_phy_maxwarn_level) / (tc_phy_maxcold_level - tc_phy_maxwarn_level);
tmp = tmp * PWM_CYSCLE;

映射过程

  1. 计算目标色温在物理范围内的相对位置(0~1)
  2. 将相对位置映射到PWM周期范围(0~PWM_CYSCLE)

示例

  • tc_phy_maxwarn_level = 71,tc_phy_maxcold_level = 248
  • tc_target_level = 160
  • 相对位置 = (160-71) / (248-71) = 89/177 ≈ 0.503
  • PWM值 = 0.503 × 4095 ≈ 2060

五、色温渐变状态机

5.1 色温状态结构体

c 复制代码
// dali_cmd.h - 色温渐变状态
struct dali_tc {
    uint32_t tc_step;           // 渐变步进值
    uint8_t tc_dirction;        // 渐变方向
    uint32_t tc_target_vaule;   // 目标PWM值
    uint32_t tc_current_vaule;  // 当前PWM值
};

5.2 渐变方向枚举

c 复制代码
// 色温渐变方向
#define FADE_IDLE       0  // 空闲
#define FADE_TIME_UP    1  // 渐变上升(变白)
#define FADE_TIME_DOWN  2  // 渐变下降(变黄)
#define FADE_DIRECT     3  // 直接跳转

5.3 色温渐变时间表

c 复制代码
// dali_cmd.c - 色温渐变时间表(单位:ms)
uint16_t tc_fade_time[] = {
    0,     700,   1000,  1400,  2000,  2800,  4000,  5700,
    8000,  11300, 16000, 22600, 32000, 45300, 64000, 90500
};

#define TC_FADE_MS_CHANGE (10)  // TC变化周期10ms

渐变时间索引由fade_time变量决定(0~15),对应不同的渐变速度。

5.4 色温渐变定时器

c 复制代码
// dali_cmd.c - 色温渐变1ms定时器
void dali_command_fade_ms_tick_tc(void)
{
    switch (tc_fede_status.tc_dirction)
    {
    case FADE_IDLE:
        break;
        
    case FADE_TIME_UP:  // 变白,值变大
        if (tc_fede_status.tc_current_vaule > tc_fede_status.tc_target_vaule) {
            tc_fede_status.tc_dirction = FADE_IDLE;
            dali_hal_update_pwm_output_tc(tc_fede_status.tc_target_vaule);
        }
        else {
            tc_fede_status.tc_current_vaule += tc_fede_status.tc_step;
            if (tc_fede_status.tc_current_vaule >= PWM_CYSCLE) {
                tc_fede_status.tc_current_vaule = PWM_CYSCLE;
                tc_fede_status.tc_dirction = FADE_IDLE;
            }
            dali_hal_update_pwm_output_tc(tc_fede_status.tc_current_vaule);
        }
        break;
        
    case FADE_TIME_DOWN:  // 变黄,值变小
        if (tc_fede_status.tc_current_vaule < tc_fede_status.tc_target_vaule || 
            tc_fede_status.tc_current_vaule <= tc_fede_status.tc_step) {
            tc_fede_status.tc_dirction = FADE_IDLE;
            dali_hal_update_pwm_output_tc(tc_fede_status.tc_target_vaule);
        }
        else {
            tc_fede_status.tc_current_vaule -= tc_fede_status.tc_step;
            dali_hal_update_pwm_output_tc(tc_fede_status.tc_current_vaule);
        }
        break;
        
    case FADE_DIRECT:  // 直接跳转
        tc_fede_status.tc_dirction = FADE_IDLE;
        dali_hal_update_pwm_output_tc(tc_fede_status.tc_target_vaule);
        break;
        
    default:
        break;
    }
}

渐变逻辑

  • FADE_TIME_UP:每10ms增加一个step,直到达到目标值
  • FADE_TIME_DOWN:每10ms减少一个step,直到达到目标值
  • FADE_DIRECT:立即跳转到目标PWM值

六、PWM硬件抽象层

6.1 PWM通道定义

c 复制代码
// dali_tc.h - PWM通道定义
#define DALI_BRIGHTNESS_PWM_CHANNEL 1  // 亮度PWM通道
#define DALI_CCT_PWM_CHANNEL 2         // 色温PWM通道

// dali_hal.h - PWM ID定义
#define LIGHT_BRIGHT_PWM_ID 1
#define LIGHT_TC_PWM_ID 2

6.2 PWM定时器配置

c 复制代码
// dali_tc.h - PWM定时器配置
#define SYS_TICK_TC_TOP (CLK_CPU / DALI_PWM_CLOCK_HZ)
#define DALI_PWM_CLOCK_HZ 1470
#define DALI_PWM_TC_TOP 0x0FFF  // 12位分辨率(4095)

// dali_bit.h - DALI位定时器
#define DALI_BIT_TC_TOP (CLK_CPU / 2400 / TE_CNT)
#define TE_CNT 13

6.3 PWM初始化

c 复制代码
// dali_tc.c - PWM通道2初始化(色温)
void dali_pwm_channel_2_init()
{
    int channel_num = 2;

    /* PWM0 channel 2 frequency prescaler to 1 */
    PWM_SET_PRESCALER(PWM0, channel_num, 0);

    /* PWM0 channel 2 frequency period to 4095 (12bits) */
    PWM_SET_CNR(PWM0, channel_num, DALI_PWM_TC_TOP);

    /* PWM0 channel 2 frequency comparator to 0, default output 0 */
    PWM_SET_CMR(PWM0, channel_num, 0);

    /* PWM0 channel 2 is edge-aligned and down counter type */
    PWM_SET_ALIGNED_TYPE(PWM0, BIT2, PWM_EDGE_ALIGNED);

    /* ZeroLevel: Low, CmpDownLevel: High */
    PWM_SET_OUTPUT_LEVEL(PWM0, PWM_CH_2_MASK, 
                         PWM_OUTPUT_LOW, PWM_OUTPUT_NOTHING, 
                         PWM_OUTPUT_NOTHING, PWM_OUTPUT_HIGH);

    /* Enable output of PWM0 channel 2 */
    PWM_EnableOutput(PWM0, PWM_CH_2_MASK);

    /* Start PWM counter */
    PWM_Start(PWM0, PWM_CH_2_MASK);
}

// dali_tc.c - PWM通道1初始化(亮度)
void dali_pwm_channel_1_init()
{
    int channel_num = 1;

    PWM_SET_PRESCALER(PWM0, channel_num, 0);
    PWM_SET_CNR(PWM0, channel_num, DALI_PWM_TC_TOP);
    PWM_SET_CMR(PWM0, channel_num, 0);

    PWM0->CTL1 = (PWM0->CTL1 & (~PWM_CTL1_CNTTYPE0_Msk)) | PWM_DOWN_COUNTER;

    PWM_SET_OUTPUT_LEVEL(PWM0, PWM_CH_1_MASK, 
                         PWM_OUTPUT_LOW, PWM_OUTPUT_NOTHING, 
                         PWM_OUTPUT_NOTHING, PWM_OUTPUT_HIGH);

    PWM0->POEN |= PWM_POEN_POEN1_Msk;
    PWM0->CNTEN |= PWM_CNTEN_CNTEN0_Msk;
}

6.4 PWM输出更新

c 复制代码
// dali_hal.c - 亮度PWM更新
void dali_hal_update_pwm_output(uint16_t pwm_value)
{
    UpdatePwm(LIGHT_BRIGHT_PWM_ID, pwm_value, 0);
}

// dali_hal.c - 色温PWM更新
void dali_hal_update_pwm_output_tc(uint16_t pwm_value)
{
    UpdatePwm(LIGHT_TC_PWM_ID, pwm_value, 0);
}

// dali_hal.c - 获取当前PWM值
uint16_t dali_hal_get_tc_value()
{
    return GetPwm(LIGHT_TC_PWM_ID);
}

uint16_t dali_hal_get_bright_value()
{
    return GetPwm(LIGHT_BRIGHT_PWM_ID);
}

七、DALI标准调光曲线

7.1 dali_color_value表

DALI标准定义了对数调光曲线,确保人眼感知的亮度变化是线性的:

c 复制代码
// dali_cmd.c - DALI标准12位PWM值表(部分)
uint16_t dali_color_value[] = {
    0, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 16, 16, 16, 16,
    16, 16, 18, 18, 18, 18, 18, 18, 21, 21, 21, 21, 24, 24, 24, 24,
    27, 27, 27, 27, 29, 29, 29, 32, 32, 32, 35, 35, 35, 37, 37, 37,
    40, 40, 43, 43, 43, 46, 46, 48, 48, 51, 51, 54, 56, 56, 59, 59,
    62, 65, 65, 67, 70, 70, 73, 75, 75, 78, 81, 84, 86, 89, 92, 92,
    94, 97, 100, 102, 105, 111, 113, 116, 119, 121, 127, 130, 132,
    135, 140, 143, 149, 151, 157, 159, 165, 170, 176, 178, 184, 189,
    195, 200, 205, 211, 216, 224, 230, 235, 243, 249, 257, 262, 271,
    279, 287, 292, 300, 311, 319, 327, 336, 346, 355, 365, 376, 384,
    395, 406, 420, 430, 441, 455, 466, 479, 493, 506, 520, 536, 550,
    566, 582, 598, 615, ...
};

特点

  • 低亮度区(0~50):PWM值变化缓慢,确保平滑过渡
  • 中亮度区(50~200):PWM值变化加快
  • 高亮度区(200~255):PWM值变化更快

7.2 电流补偿映射

实际应用中需要根据LED驱动电流进行补偿:

c 复制代码
// dali_cmd.c - 电流补偿PWM映射
void dali_pwm_value_init(void)
{
    float rate;
    float tmp;
    uint16_t i;
    bool int_flag = false;

#if DALI_NORMAL_LIGHT
    rate = get_electric_current_config();  // 获取电流配置
#elif DALI_MAGNETIC_ABSORPTION_LAMP
    rate = get_current_cixideng();
#endif

    // 亮度PWM值映射(带电流补偿)
    for (i = 0; i <= 255; i++) {
        tmp = (float)dali_color_value[i] * rate / 10;
        dali_color_value_use[i] = (u16)tmp;
        if (dali_color_value_use[i] >= PWM_CYSCLE) {
            dali_color_value_use[i] = PWM_CYSCLE;
        }
        printf("dali_color_value_use %hx\r\n", dali_color_value_use[i]);
    }

    // 调光器PWM值映射
    for (i = 0; i <= 255; i++) {
        tmp = (float)dali_dimmer_value[i] * rate / 10;
        tmp = tmp * ((float)i / (float)255);
        dali_dimmer_value[i] = (u16)tmp;
        if (dali_dimmer_value[i] >= PWM_CYSCLE) {
            dali_dimmer_value[i] = PWM_CYSCLE;
        }
        printf("dali_dimmer_value %hx\r\n", dali_dimmer_value[i]);
    }
}

八、Identify设备识别

8.1 识别功能实现

DALI标准支持设备识别功能,通过PWM闪烁来定位物理设备:

c 复制代码
// dali_hal.c - 设备识别功能
u32 identify_count = 0;
u8 identify_count_flag = 0;
u8 identify_delay = 10;

void dali_hal_identify_device(void)
{
    if (identify_delay-- == 0) {
        identify_delay = 10;
    }
    else {
        return;
    }

    // PWM值三角波变化
    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--;
    }
    
    // 同时更新亮度和色温PWM
    dali_hal_update_pwm_output(identify_count);
    dali_hal_update_pwm_output_tc(identify_count);
}

识别效果

  • PWM值从0到4095三角波变化
  • 亮度和色温同时渐变
  • 产生明显的呼吸灯效果,便于定位设备

九、拨码开关地址配置

9.1 硬件拨码读取

部分设备支持通过拨码开关设置短地址:

c 复制代码
// dali_hal.h - 拨码地址位定义
#define SHOTADDRESS_VAULE_BIT1 (P02 ? 0 : 1)
#define SHOTADDRESS_VAULE_BIT2 (P43 ? 0 : 1)
#define SHOTADDRESS_VAULE_BIT3 (P03 ? 0 : 1)
#define SHOTADDRESS_VAULE_BIT4 (P04 ? 0 : 1)
#define SHOTADDRESS_VAULE_BIT5 (P05 ? 0 : 1)
#define SHOTADDRESS_VAULE_BIT6 (P06 ? 0 : 1)

#define SHOTADDRESS_VALUE (SHOTADDRESS_VAULE_BIT1 |            \
                           _crol_(SHOTADDRESS_VAULE_BIT2, 1) | \
                           _crol_(SHOTADDRESS_VAULE_BIT3, 2) | \
                           _crol_(SHOTADDRESS_VAULE_BIT4, 3) | \
                           _crol_(SHOTADDRESS_VAULE_BIT5, 4) | \
                           _crol_(SHOTADDRESS_VAULE_BIT6, 5))

9.2 拨码引脚初始化

c 复制代码
// dali_hal.c - 拨码开关引脚初始化
void dali_dip_swtch_address_init()
{
    // 高阻输入模式配置
    P0M1 = 0x04 | P0M1;  // P02高阻
    P0M0 = 0x00 | P0M0;
    
    P4M1 = 0x08 | P4M1;  // P43高阻
    P0M1 = 0x08 | P0M1;  // P03高阻
    P0M1 = 0x10 | P0M1;  // P04高阻
    P0M1 = 0x20 | P0M1;  // P05高阻
    P0M1 = 0x40 | P0M1;  // P06高阻
}

十、系统架构总结

10.1 DT8双色温控制数据流

复制代码
DALI总线
  ↓
帧接收与解析
  ↓
TC_COLOR_VALUE命令 (DTR0+DTR1)
  ↓
dali_cmd_direct_arc_tc_control()
  ↓
色温范围限幅与映射
  ↓
tc_fede_status状态机
  ↓
dali_command_fade_ms_tick_tc() (10ms周期)
  ↓
dali_hal_update_pwm_output_tc()
  ↓
PWM硬件输出 (12位分辨率)
  ↓
LED驱动电路
  ↓
冷白光/暖白光比例调节

10.2 关键设计亮点

  1. 四级色温范围:物理边界+配置边界,双重保护
  2. 渐变状态机:支持平滑过渡和直接跳转
  3. 标准调光曲线:符合DALI标准的对数曲线
  4. 电流补偿:适配不同LED驱动电流
  5. 12位PWM分辨率:4096级精细控制
  6. 双通道独立控制:亮度和色温独立PWM通道
  7. Identify识别:三角波PWM便于设备定位

十一、应用场景

11.1 智能办公照明

  • 上午:冷白光(高色温),提高注意力
  • 下午:暖白光(低色温),缓解疲劳
  • 会议模式:最冷色温,清晰明亮

11.2 智能家居照明

  • 起床模式:从暖白渐变到冷白
  • 阅读模式:冷白光,高亮度
  • 休息模式:暖白光,低亮度
  • 影院模式:最暖色温,最低亮度

11.3 商业展示照明

  • 商品展示:冷白光,突出细节
  • 氛围营造:暖白光,温馨舒适
  • 场景切换:平滑渐变,无闪烁

12. 总结

本文详细解析了DALI协议栈中DT8双色温扩展的实现,涵盖:

  • 四级色温范围机制:物理边界与配置边界双重保护
  • TC_COLOR_VALUE命令:DTR0+DTR1双字节传输16位色温值
  • 色温映射算法:将色温值线性映射到PWM占空比
  • 渐变状态机:支持平滑过渡和直接跳转
  • PWM硬件抽象:12位分辨率双通道独立控制
  • 标准调光曲线:符合DALI标准的对数曲线
  • 电流补偿机制:适配不同LED驱动电流

通过本文的解析,读者可以深入理解DALI DT8双色温控制的完整实现,为智能照明系统的开发提供技术参考。


关于极物科技(ZEEWO)

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

我们的核心能力:

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

我们的市场覆盖:

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

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

相关推荐
阿钱真强道5 小时前
24 极物科技 | DALI协议栈 - 定时器与中断系统
定时器·曼彻斯特编码·极物·极物智能·极物科技·dali协议栈·智慧照明
阿钱真强道11 小时前
23 极物科技 | DALI协议栈 - EEPROM持久化机制
eeprom·极物·极物智能·极物科技·iec 62386·dali协议栈·智慧照明
阿钱真强道1 天前
20 极物科技 | DALI协议栈 - 配置命令详解
智能照明·极物·极物智能·极物科技·iec 62386·dali协议栈·场景配置
阿钱真强道2 天前
22 极物科技 | DALI协议栈 - 特殊命令与设备发现机制
极物·极物智能·极物科技·iec 62386·设备发现·dali协议栈·智慧照明
阿钱真强道2 天前
19 极物科技 | DALI协议栈 - 标准命令集解析
极物·极物智能·极物科技·iec 62386·调光控制·dali协议栈·标准命令
阿钱真强道2 天前
17 极物科技 | DALI协议栈 - 物理层位编解码详解
曼彻斯特编码·极物·极物智能·极物科技·iec 62386·dali协议栈
阿钱真强道4 天前
16 极物科技 | DALI协议栈 - 架构总览与模块设计
智能家居·照明·极物·极物智能·极物科技·iec 62386·dali协议栈
阿钱真强道5 天前
11 极物科技 | DALI调光灯 - 功能接口与调试指南
智能照明·极物·极物智能·极物科技·dali调光灯·调光控制·调试指南
阿钱真强道6 天前
12 极物科技 | DALI调光灯 - 设备发现与地址分配机制
智能照明·极物·极物智能·极物科技·dali调光灯·设备发现·地址分配