1、实验简介

参考网址:https://gitee.com/Lockzhiner-Electronics/lz3863/tree/master/apps/b5_rgb_led_i2c

1.1、实验目的

本实验旨在帮助学习者掌握 OpenHarmony 轻量系统中 I2C 总线驱动外设芯片 的基本方法。通过本实验,你将学会:

  1. 理解 I2C 总线的工作原理及寄存器读写机制;
  2. 使用 IoT Hardware 接口初始化 I2C 总线并配置引脚复用;
  3. 理解 AW2023 RGB LED 驱动芯片 的工作模式与 PWM 调光原理;
  4. 掌握 AW2023 驱动库的基本用法,实现三色 LED 循环点亮;
  5. 完成案例代码的编译、烧录与 LED 现象观察。

1.2、实验内容

本案例在 LZ3863-星闪开发板上,通过 I2C1 总线驱动板载 AW2023 芯片,控制三路 RGB LED 依次点亮,形成循环跑马灯效果。

项目 说明
I2C 控制器 I2C1(AW2023_I2C_IDX = 1
SDA 引脚 GPIO15(IOT_IO_FUNC_GPIO_15_I2C1_SDA
SCL 引脚 GPIO16(IOT_IO_FUNC_GPIO_16_I2C1_SCL
通信速率 400 kHz(IoTI2cInit(1, 400000)
AW2023 地址 0x45(7-bit 地址)
芯片 ID 0x09
LED 通道 3 路(LED0 / LED1 / LED2,对应 RGB)
点亮间隔 50 ms(aw2023_led_rotate_forever(50)
任务名称 aw2023_i2c_main

程序将 LED 控制逻辑封装在独立的 RTOS 线程中:上电后完成 I2C 与 AW2023 初始化,随后进入无限循环,依次点亮 LED0 → LED1 → LED2,每次仅一路 LED 全亮,其余熄灭。

1.3、实验环境

项目 说明
硬件 LZ3863-星闪开发板(含板载 AW2023 RGB LED)、USB 数据线
软件 OpenHarmony v5.1.0 源码、hb 编译工具
调试工具 串口助手(波特率 115200,可选,用于查看初始化日志)
案例路径 applications/sample/wifi-iot/app/b5_rgb_led_i2c/

2、基础知识

2.1、什么是 I2C

I2C(Inter-Integrated Circuit) 是一种常用的 两线制串行总线,仅需 SDA(数据线)SCL(时钟线) 两根信号线即可实现主设备与多个从设备之间的通信。

I2C 总线的核心特点:

概念 说明
主从架构 通常由 MCU 作为主机(Master),外设作为从机(Slave)
地址寻址 每个从设备拥有唯一的 7 位或 10 位 I2C 地址
半双工通信 同一时刻数据沿 SDA 单向传输,由 SCL 同步
寄存器访问 先写寄存器地址,再写/读寄存器数据
通信速率 标准模式 100 kHz,快速模式 400 kHz,本案例使用 400 kHz

本实验 MCU 作为 I2C 主机,AW2023 芯片作为从机,通过 IoTI2cWrite() / IoTI2cRead() 读写芯片内部寄存器,从而控制 LED 亮灭与亮度。

2.2、AW2023 RGB LED 驱动芯片

AW2023 是 Awinic(艾为电子)推出的一款 3 通道 LED 驱动芯片,专为 RGB 指示灯、背光等应用设计。芯片内部集成 PWM 控制器,支持多种工作模式。

AW2023 的核心特性:

概念 说明
LED 通道数 3 路独立输出(LED0、LED1、LED2)
工作模式 手动模式(Manual)与图案模式(Pattern)
PWM 调光 8 位 PWM 占空比(0x00~0xFF),控制 LED 亮度
电流控制 每路 LED 可独立设置输出电流(0~15 mA 档)
呼吸灯 Pattern 模式下支持上升/保持/下降/熄灭时序配置
同步控制 支持多路 LED 同步亮灭

本案例使用 手动模式(Manual Mode),通过设置 PWM 寄存器直接控制各路 LED 的亮灭,实现简单直观的循环点亮效果。

2.3、RGB LED 原理

RGB LED 由 红(R)、绿(G)、蓝(B) 三个发光二极管封装在同一灯珠中。通过分别控制三路 LED 的电流与 PWM 占空比,可以混合出多种颜色。

本开发板将 AW2023 的三路输出分别连接至 RGB LED 的三个通道:

AW2023 通道 典型颜色
LED0 红(R)
LED1 绿(G)
LED2 蓝(B)

本案例每次仅点亮一路 LED(PWM = 0xFF),其余两路熄灭(PWM = 0x00),因此可观察到红、绿、蓝三色依次循环切换的效果。

2.4、I2C 与 AW2023 驱动层次

本案例的软件调用层次如下:

应用层(rgb_led_example.c)
    ├── IoTGpioInit() / IoSetFunc()   ← 引脚复用为 I2C
    ├── IoTI2cInit()                  ← 初始化 I2C 总线
    └── aw2023_init() / aw2023_led_rotate_forever()
            └── AW2023 驱动层(aw2023.c)
                    ├── aw2023_i2c_write_reg()  ← 写寄存器
                    ├── aw2023_i2c_read_reg()   ← 读寄存器
                    └── IoTI2cWrite() / IoTI2cRead()
                            └── HAL 层(iot_i2c.h)

应用层负责线程创建与业务逻辑;aw2023.c 封装了芯片初始化、寄存器操作及 LED 演示功能;底层通过 IoT Hardware 的 I2C API 完成硬件通信。

2.5、核心 API 介绍

2.5.1、头文件
#include "aw2023.h"
#include "cmsis_os2.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_i2c.h"
#include "ohos_init.h"
#include <stdbool.h>
#include <stdio.h>
2.5.2、I2C 常用 API
API 名称 功能说明
IoTI2cInit 以指定波特率初始化 I2C 控制器
IoTI2cDeinit 解除 I2C 控制器初始化
IoTI2cWrite 向 I2C 从设备写入数据
IoTI2cRead 从 I2C 从设备读取数据
IoSetFunc 设置引脚复用功能(如 I2C SDA/SCL)
2.5.3、IoTI2cInit — 初始化 I2C
unsigned int IoTI2cInit(unsigned int id, unsigned int baudrate);
参数 说明
id I2C 控制器编号,本案例为 1(I2C1)
baudrate 通信波特率,本案例为 400000(400 kHz)
返回值 IOT_SUCCESS 表示成功,否则为失败
2.5.4、AW2023 驱动库常用 API
API 名称 功能说明
aw2023_init 芯片软复位、使能、校验 ID,配置全局参数
aw2023_i2c_write_reg 向 AW2023 指定寄存器写入数据
aw2023_i2c_read_reg 从 AW2023 指定寄存器读取数据
aw2023_set_pwm_dimming 设置指定 LED 通道的 PWM 调光值(0x00~0xFF)
aw2023_led_enable_ctrl 使能或关闭指定 LED 通道
aw2023_set_led_operating_mode 设置 LED 工作模式(手动/图案)
aw2023_led_rotate_forever 无限循环依次点亮 LED0/LED1/LED2
aw2023_all_led_full_on 三路 LED 全亮演示
aw2023_all_led_breath 三路 LED 独立呼吸灯演示

3、程序设计

3.1、工程目录结构

applications/sample/wifi-iot/app/b5_rgb_led_i2c/
├── rgb_led_example.c   # 应用入口,创建 AW2023 控制任务
├── aw2023.c              # AW2023 驱动实现(寄存器读写、LED 控制)
├── aw2023.h              # AW2023 驱动头文件(寄存器地址、宏定义)
├── BUILD.gn              # 编译配置
├── README_zh.md          # 案例简要说明
└── 实验手册.md           # 本实验手册

3.2、关键宏定义

应用层 I2C 与引脚配置(rgb_led_example.c):

#define AW2023_I2C_IDX      1                    // I2C 总线编号
#define AW2023_I2C_BAUDRATE 400000               // I2C 通信速率(400 kHz)
#define AW2023_SDA_GPIO     IOT_IO_NAME_GPIO_15  // SDA 引脚
#define AW2023_SCL_GPIO     IOT_IO_NAME_GPIO_16  // SCL 引脚

AW2023 芯片配置(aw2023.h):

#define AW2023_DEVICE_ADDR  0x45   // AW2023 7-bit I2C 地址
#define AW2023_CHIP_ID      0x09   // 芯片 ID,用于初始化校验
#define AW2023_LED_NUM      3      // LED 通道数量
#define AW2023_LED0         0      // 红色通道
#define AW2023_LED1         1      // 绿色通道
#define AW2023_LED2         2      // 蓝色通道

3.3、主要代码分析

(1)I2C 寄存器写入 — aw2023_i2c_write_reg

aw2023_i2c_write_reg 是驱动层与 AW2023 交互的基础函数,将寄存器地址与数据打包后通过 I2C 发送,并带有重试机制:

AW_U8 aw2023_i2c_write_reg(AW_U8 reg_addr, AW_U8 reg_data)
{
    AW_U8 res = 0;
    AW_U8 cnt = 0;
    uint8_t buffer[2] = {reg_addr, reg_data};

    while (cnt < I2C_RETRY_TIMES)
    {
        res = IoTI2cWrite(AW2023_I2C_IDX, AW2023_DEVICE_ADDR, buffer, 2);
        if (res == IOT_SUCCESS)
        {
            break;
        }
        cnt++;
    }

    return (res == IOT_SUCCESS) ? AW_I2C_OK : AW_I2C_ERROR;
}
(2)AW2023 芯片初始化 — aw2023_init

aw2023_init 完成芯片软复位、使能、ID 校验及全局参数配置:

AW_BOOL aw2023_init(void)
{
    AW_BOOL ret = AW_FALSE;

    aw2023_soft_rst();              // 1. 软件复位
    aw2023_chip_enable(AW_TRUE);    // 2. 芯片使能
    ret = aw2023_read_chipid();     // 3. 读取并校验芯片 ID
    if (ret == AW_TRUE)
    {
        aw2023_set_imax(AW2023_IMAX_15MA);       // 4. 设置最大输出电流 15mA
        aw2023_set_pwm_freq(AW2023_PWM_FREQ_250HZ); // 5. 设置 PWM 频率 250Hz
    }

    return ret;
}
(3)手动模式配置 — aw2023_setup_for_manual

循环点亮功能依赖手动模式。aw2023_setup_for_manual 将三路 LED 配置为手动模式、线性 PWM、最大电流,并初始化为熄灭状态:

static AW_BOOL aw2023_setup_for_manual(void)
{
    AW_BOOL ret = aw2023_init();
    if (ret != AW_TRUE)
    {
        return AW_FALSE;
    }

    aw2023_set_pwm_mode(AW2023_PWM_LINEAR);
    aw2023_set_pwm_freq(AW2023_PWM_FREQ_250HZ);

    for (AW_U8 i = 0; i < AW2023_LED_NUM; i++)
    {
        aw2023_set_led_current(i, 0x0F);
        aw2023_set_led_operating_mode(i, AW2023_MANUAL_MODE);
        aw2023_fade_in_enable_ctrl(i, AW_FALSE);
        aw2023_fade_out_enable_ctrl(i, AW_FALSE);
        aw2023_set_pwm_dimming(i, 0x00);
    }

    aw2023_led_enable_ctrl(AW2023_LED0_EN | AW2023_LED1_EN | AW2023_LED2_EN, AW_TRUE);
    return AW_TRUE;
}
(4)单路 LED 点亮 — aw2023_set_active_led

aw2023_set_active_led 先将三路 PWM 全部置 0(熄灭),再将目标通道 PWM 置为 0xFF(全亮):

static void aw2023_set_active_led(AW_U8 led_index)
{
    aw2023_set_pwm_dimming(AW2023_LED0, 0x00);
    aw2023_set_pwm_dimming(AW2023_LED1, 0x00);
    aw2023_set_pwm_dimming(AW2023_LED2, 0x00);

    if (led_index < AW2023_LED_NUM)
    {
        aw2023_set_pwm_dimming(led_index, 0xFF);
    }
}
(5)LED 循环点亮 — aw2023_led_rotate_forever

aw2023_led_rotate_forever 是本案例的核心演示函数,按 LED0 → LED1 → LED2 顺序无限循环点亮:

void aw2023_led_rotate_forever(AW_U32 delay_ms_per_led)
{
    if (delay_ms_per_led == 0)
    {
        delay_ms_per_led = 500;
    }

    aw2023_setup_for_manual();

    while (1)
    {
        for (AW_U8 i = 0; i < AW2023_LED_NUM; i++)
        {
            aw2023_set_active_led(i);
            delay_ms(delay_ms_per_led);
        }
    }
}

本案例传入参数 50,表示每路 LED 点亮持续 50 ms

(6)硬件初始化 — InitI2CAndGpio

InitI2CAndGpio 完成 GPIO 引脚初始化、I2C 功能复用及 I2C 总线初始化:

static bool InitI2CAndGpio(void)
{
    IoTGpioInit(AW2023_SDA_GPIO);
    IoTGpioInit(AW2023_SCL_GPIO);

    if (IoSetFunc(AW2023_SDA_GPIO, IOT_IO_FUNC_GPIO_15_I2C1_SDA) != IOT_SUCCESS)
    {
        printf("Failed to set SDA pin function!\r\n");
        return false;
    }
    if (IoSetFunc(AW2023_SCL_GPIO, IOT_IO_FUNC_GPIO_16_I2C1_SCL) != IOT_SUCCESS)
    {
        printf("Failed to set SCL pin function!\r\n");
        return false;
    }

    if (IoTI2cInit(AW2023_I2C_IDX, AW2023_I2C_BAUDRATE) != IOT_SUCCESS)
    {
        printf("AW2023 I2C init failed!\r\n");
        return false;
    }

    return true;
}
(7)AW2023 控制任务 — aw2023_i2c_main

aw2023_i2c_main 是核心工作线程,完成硬件初始化、芯片初始化及 LED 循环演示:

void aw2023_i2c_main(void *arg)
{
    if (!InitI2CAndGpio())
    {
        printf("I2C and GPIO initialization failed!\r\n");
        return;
    }

    while (aw2023_init() != 1)
        ;
    printf("AW2023 initialized successfully!\r\n");

    while (1)
    {
        aw2023_led_rotate_forever(50);
    }
}

芯片初始化采用 无限重试 机制,确保 AW2023 就绪后再进入 LED 演示。

(8)应用启动入口 — aw2023_i2c_example

系统启动后,通过 APP_FEATURE_INIT 宏自动调用此函数,创建 AW2023 控制线程:

static void aw2023_i2c_example(void)
{
    osThreadAttr_t attr = {0};
    attr.name       = "aw2023_i2c_main";
    attr.stack_size = 4096;
    attr.priority   = osPriorityNormal;

    if (osThreadNew(aw2023_i2c_main, NULL, &attr) == NULL)
    {
        printf("[AW2023] Failed to create aw2023_i2c_main thread!\n");
    }
}

APP_FEATURE_INIT(aw2023_i2c_example);

3.4、程序执行流程

RGB LED AW2023 芯片 I2C1 总线 aw2023_i2c_main aw2023_i2c_example 系统启动 RGB LED AW2023 芯片 I2C1 总线 aw2023_i2c_main aw2023_i2c_example 系统启动 loop [无限循环] APP_FEATURE_INIT 触发 osThreadNew(aw2023_i2c_main) InitI2CAndGpio() IoTI2cInit(1, 400000) aw2023_init()(重试至成功) 芯片 ID 校验通过 点亮 LED0(PWM=0xFF) 红色亮 osDelay(50ms) 点亮 LED1(PWM=0xFF) 绿色亮 osDelay(50ms) 点亮 LED2(PWM=0xFF) 蓝色亮 osDelay(50ms)

4、编译步骤

4.1、确认案例目录

确认案例已位于 OpenHarmony 源码目录下:

applications/sample/wifi-iot/app/b5_rgb_led_i2c/
├── rgb_led_example.c
├── aw2023.c
├── aw2023.h
├── BUILD.gn
└── 实验手册.md

若从外部复制,请将 b5_rgb_led_i2c 目录放到上述 app/ 路径下。

4.2、修改 BUILD.gn(注册编译组件)

编辑 applications/sample/wifi-iot/app/BUILD.gn,在 features 列表中添加本案例:

lite_component("app") {
  features = [
    "startup",
    "b5_rgb_led_i2c:rgb_led_i2c_example",   // 添加此行
  ]
}

4.3、修改 SDK 配置文件

步骤 1:编辑 device/soc/hisilicon/ws63v100/sdk/build/config/target_config/ws63/config.py

找到 'ws63-liteos-app' 配置段,在其 'ram_component' 列表中添加:

"rgb_led_i2c_example"

步骤 2:编辑 device/soc/hisilicon/ws63v100/sdk/libs_url/ws63/cmake/ohos.cmake

找到 "ws63-liteos-app" 对应的 set(COMPONENT_LIST 部分,添加:

"rgb_led_i2c_example"

4.4、执行编译

在 OpenHarmony 源码根目录下执行:

rm -rf out
hb set -root .
# 通过上下方向键选择 ws63 对应的编译分支(如 nearlink_dk_3863 / ws63-liteos-app)
hb build -f

编译成功后,固件输出路径通常在 out/ws63/ 目录下。

4.5、烧录固件

使用开发板配套的烧录工具,将编译生成的固件烧写到 LZ3863-星闪开发板。具体烧录步骤请参考开发板用户手册。


5、运行结果

5.1、串口配置(可选)

如需查看调试日志,可打开串口助手,配置参数如下:

参数
波特率 115200
数据位 8
停止位 1
校验位

5.2、预期现象

烧录并复位开发板后,可观察到:

  • 板载 RGB LED红 → 绿 → 蓝 顺序循环点亮;
  • 每次仅一路 LED 全亮,其余两路熄灭;
  • 每路 LED 点亮持续约 50 ms,三路完整循环周期约 150 ms
  • 循环持续进行,不会停止。

5.3、串口输出说明

初始化成功后,串口可能输出:

read same id
ret:1
AW2023 initialized successfully!
输出内容 说明
read same id AW2023 芯片 ID 读取成功,与预期值 0x09 匹配
AW2023 initialized successfully! 芯片初始化完成,即将进入 LED 循环演示
Failed to set SDA/SCL pin function! 引脚复用配置失败
AW2023 I2C init failed! I2C 总线初始化失败
[AW2023] Failed to create aw2023_i2c_main thread! RTOS 线程创建失败

5.4、结果分析

现象 说明
RGB 三色循环点亮 aw2023_led_rotate_forever 正常运行,手动模式 PWM 切换成功
每色持续约 50 ms delay_ms_per_led 参数为 50,经 osDelay() 实现
上电即循环 APP_FEATURE_INIT 在系统启动后自动创建并运行 AW2023 任务
仅一路 LED 亮 aw2023_set_active_led 先将三路 PWM 清零,再点亮目标通道

5.5、常见问题排查

问题 可能原因 解决方法
RGB LED 完全不亮 案例未加入编译或烧录了错误固件 核对 4.2、4.3 节三处配置,重新编译烧录
LED 常亮不变色 aw2023_init 失败或 I2C 通信异常 检查串口是否有初始化失败日志,确认 I2C 引脚配置
串口报 I2C 错误 引脚复用或 I2C 端口配置错误 确认 GPIO15/GPIO16 已复用为 I2C1_SDA/SCL
颜色切换过快或过慢 delay_ms_per_led 参数不合适 修改 aw2023_led_rotate_forever() 的参数,如改为 200
编译报错找不到 rgb_led_i2c_example BUILD.gn 或 config.py 未正确修改 逐步核对 4.2、4.3 节的配置项
与 OLED 案例冲突 I2C1 总线被其他案例占用 同一时刻仅编译运行一个使用 I2C1 的案例

6、实验扩展

完成基本实验后,可尝试以下扩展练习:

  1. 调整循环速度:将 aw2023_led_rotate_forever(50) 的参数改为 200500,观察 LED 切换快慢变化;
  2. 三路全亮:将主循环中的调用替换为 aw2023_all_led_full_on(),观察白色(RGB 混合)效果;
  3. 呼吸灯效果:调用 aw2023_all_led_breath(),体验 Pattern 模式下的自动呼吸动画;
  4. 同步呼吸灯:调用 aw2023_all_led_breath_with_sync(),三路 LED 同步亮灭;
  5. 手动渐变:调用 aw2023_all_led_manual_ctrl(),体验手动模式下的淡入淡出效果;
  6. 自定义颜色:在手动模式下同时设置多路 PWM 值(如 R=0xFF, G=0x80, B=0x00),混合出橙色等自定义颜色;
  7. 结合 OLED 显示:配合 b4_oled_i2c 案例思路,在 OLED 上显示当前点亮的 LED 颜色名称(需注意 I2C 总线共享与案例互斥编译)。
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐