根據您上傳的 AW2013 芯片手冊,我將為您分三個部分詳細解讀:
一、芯片簡介(AW2013 概述)
AW2013 是一款 3 通道的 I2C 控制恒流 LED 驅動芯片,支持以下功能:
-
單通道最大恒流輸出:15mA,支持 4 級可調(0 / 5 / 10 / 15 mA)
-
每通道 256 級 PWM 控制亮度
-
兩種控制模式:
- PWM控制模式:MCU 定時寫寄存器調節亮度
- 一次性編程(One Shot Programming)模式:芯片自動跑呼吸燈動畫
-
支持 Fade in/out(亮度平滑過渡)
-
支持中斷 INTN(低電平有效)
-
內部集成振蕩器和LDO
-
供電:VCC = 2.5V ~ 3.3V
-
I2C 最高頻率:400kHz
-
默認地址:
0x45
(可配置)
二、實用配置流程
以配置 LED0 為呼吸燈效果,頻率 2Hz,占空比 80% 為例,推薦使用 One Shot Programming 模式:
1. 上電初始化(必要)
write_reg(0x00, 0x55); // Soft Reset
write_reg(0x01, 0x01); // GCR: ENABLE = 1
2. 配置 LED0 通道工作模式
// 設置 LED0 為 One Shot 模式 + 最大電流(15mA)
write_reg(0x31, 0b00010011); // LCFG0: MD=1, IMAX=11
3. 設置呼吸燈節奏(T0~T4 時間)
呼吸燈周期:T1 + T2 + T3 + T4,設置為約 0.5s(約2Hz頻率)
// LED0T0: T1=001(0.26s), T2=001(0.26s)
write_reg(0x37, (1 << 4) | 1);// LED0T1: T3=000(0.13s), T4=000(0.13s)
write_reg(0x38, (0 << 4) | 0);// LED0T2: T0=0000(0s), REPEAT=0000(無限循環)
write_reg(0x39, 0x00);
4. 使能 LED0 輸出
write_reg(0x30, 0x01); // LCTR: LE0=1
三、寄存器總結與地址映射
地址 | 寄存器名 | 說明 |
---|---|---|
00h | RSTR | 寫入 0x55 觸發軟件復位 |
01h | GCR | 全局控制(ENABLE 開啟芯片) |
02h | ISR | 中斷狀態(如呼吸結束、上電) |
30h | LCTR | 各通道開關(LE0 ~ LE2) |
31h~33h | LCFGx | 模式配置(MD 模式 / IMAX 電流 / Fade) |
34h~36h | PWMx | PWM亮度(僅 PWM 模式生效) |
37h~3Fh | LEDxTn | 呼吸模式時序配置 |
77h | IADR | 修改I2C地址 |
四、注意事項和建議
- 建議每次上電或復位后重新配置所有寄存器。
- Fade in/out 僅在 PWM 模式 下生效。
- One Shot 模式配置完 T0~T4 后,寫
PWMx.MD=1
才開始跑動畫。 - INTN 引腳可以通過讀取
ISR
判斷哪個通道完成動畫。 - 上拉電阻建議使用 4.7kΩ。
如果你有多個 LED 需要同時呼吸同步,請使用如下順序配置三個通道:
write_reg(0x30, 0x00); // 關閉所有通道
write_reg(0x31, 0x00); // 設置為 PWM 模式(先暫時禁止 One Shot)
write_reg(0x32, 0x00);
write_reg(0x33, 0x00);// 配置 T0~T4 ...
write_reg(0x37, ...); // LED0 T0~T4
write_reg(0x3A, ...); // LED1
write_reg(0x3D, ...); // LED2write_reg(0x31, 0x13); // MD = 1,IMAX=15mA
write_reg(0x32, 0x13);
write_reg(0x33, 0x13);write_reg(0x30, 0x07); // 使能三個 LED(同步啟動)
如需我幫您寫一個完整應用層 C 示例或 ioctl 控制流程,也可以繼續提問。
這是一個非常好的問題,很多人第一次看 AW2013 的“PWM 控制模式” 和 “One Shot Programming 模式”時都會疑惑:它們都是為了實現呼吸燈,區別在哪?
我來幫你深入本質地理解這兩種模式的核心差異:
🌟一圖概括
對比項 | PWM 控制模式 | One Shot 編程模式 |
---|---|---|
控制方式 | MCU 實時寫 PWM 寄存器 | MCU 只寫一次,芯片自動運行 |
呼吸邏輯 | MCU 自己每 N 毫秒改變亮度 | 芯片內部定時器負責自動調節亮度 |
占用 MCU | 高(需周期性操作) | 低(配置完自動運行) |
動畫復雜性 | 自由度高,需 MCU 配合 | 程序預設的動畫結構 |
是否支持 Fade | 支持(FI / FO 位控制) | 自動包含 Fade 效果 |
適合場景 | 自定義燈效,如音樂節奏燈 | 簡單、節能、預設呼吸燈 |
🎯詳細解釋每種模式
? PWM 控制模式(LCFGx.MD = 0)
MCU主動控制,每次調亮度都要寫寄存器
-
你在 MCU 上運行一個定時器,比如每 50ms 寫一次亮度值:
write_reg(PWM0, val); // val 從 0 到 255 緩慢變化
-
如果啟用了 Fade-in / Fade-out(FI / FO 位),會有平滑過渡效果。
-
本質上:MCU 自己寫“動畫幀”,芯片只執行亮度變化。
🟡 優點:
- 靈活,亮度隨音頻或狀態變化。
- 動畫可以自定義成任何形狀(不是只有呼吸)。
🔴 缺點:
- MCU 開銷大。
- 需要 MCU 持續參與。
? One Shot Programming 模式(LCFGx.MD = 1)
MCU只配置一次,芯片自動按照時序完成呼吸效果。
- 設置 T0~T4 寄存器(定義呼吸燈動畫的時間點)
- 寫入 LEDxT2 時立即啟動一次動畫
- 可設置重復次數(0 = 無限循環)
🌈 呼吸周期包含:
T0(延遲)→ T1(亮度上升)→ T2(保持高亮)→ T3(下降)→ T4(低亮等待)→ 重復
🟢 優點:
- MCU 解放了,節能。
- 動畫由 AW2013 自動控制,定時精確。
- 可以實現 3 通道異步 / RGB 自動輪換呼吸等效果。
🔴 缺點:
- 動畫形式固定為「呼吸」結構。
- 如果想要自定義復雜燈效(閃爍、律動),就做不到了。
?"一次性編程" 是“只跑一次”嗎?
不是。它的“One Shot”指的是“一次性寫入配置即可運行完整呼吸流程”,并不是“只運行一次”。
你可以通過 REPEAT
字段設置循環次數:
REPEAT = 0
:無限循環呼吸燈REPEAT = 1~15
:呼吸燈動畫運行指定次數后自動停止
當動畫完成后,可通過中斷或輪詢 ISR
中的 LISx
位判斷哪個通道結束。
? 總結建議
場景 | 推薦模式 |
---|---|
要做精確的 RGB 呼吸燈(不同通道異步) | One Shot 模式 |
要實現亮度跟隨狀態/節奏/外部傳感器 | PWM 模式 |
要節能、MCU 低占用 | One Shot 模式 |
要做頻閃、閃爍、跑馬燈等復雜動態 | PWM 模式 |
需要我給你寫一個 PWM 模式的呼吸燈 MCU demo、和 One Shot 模式的完整初始化流程嗎?
好的,我們分別來看:
? 一、PWM 模式下 MCU 控制呼吸燈(示例代碼)
此方案是 MCU 以定時器為基礎,不斷更改 LED 亮度值來實現呼吸燈效果。
💡 思路
- 初始化 AW2013 芯片
- 設置為 PWM 模式,開啟 LED 通道
- MCU 周期性寫入亮度(0 ~ 255 ~ 0)
- (可選)開啟 Fade-in / Fade-out 平滑過渡
? 示例(以 LED0 為例,開啟 Fade,亮度從 0 到 255 再下降)
void aw2013_init_pwm_mode(int fd)
{// 1. 軟件復位i2c_write(fd, 0x00, 0x55);// 2. 啟用芯片功能i2c_write(fd, 0x01, 0x01); // ENABLE=1// 3. LED0 模式為 PWM,最大電流,開啟Fadei2c_write(fd, 0x31, 0b01100011); // MD=0, FO=1, FI=1, IMAX=11(15mA)// 4. 使能 LED0 通道i2c_write(fd, 0x30, 0x01); // LE0=1
}
void aw2013_pwm_breath_loop(int fd)
{uint8_t brightness = 0;int8_t step = 5; // 調節步長,可根據速度需求改while (1) {i2c_write(fd, 0x34, brightness); // PWM0 地址=0x34usleep(20000); // 20ms 刷新一次brightness += step;if (brightness == 0 || brightness == 255)step = -step; // 到達邊界反轉}
}
? 二、One Shot 模式:自動呼吸燈初始化(LED0,2Hz)
初始化一次即可運行自動呼吸燈動畫,無需 MCU 控制循環。
💡 目標設置
- 每個呼吸周期約 0.5s
- 無限循環
- 最大亮度為 15mA
? 示例代碼:
void aw2013_init_one_shot_mode(int fd)
{// 1. 軟件復位 + 啟用芯片i2c_write(fd, 0x00, 0x55);i2c_write(fd, 0x01, 0x01);// 2. 設置 LED0 為 PWM 模式,暫時不啟用i2c_write(fd, 0x31, 0x00); // MD = 0,關閉 OneShot,防止提前運行i2c_write(fd, 0x30, 0x00); // 全部 LED 先關閉// 3. 配置呼吸燈 T0~T4i2c_write(fd, 0x37, (1 << 4) | 1); // T1=0.26s, T2=0.26si2c_write(fd, 0x38, (0 << 4) | 0); // T3=0.13s, T4=0.13si2c_write(fd, 0x39, 0x00); // T0=0s, REPEAT=0 無限循環// 4. 啟用 One Shot 模式 + 設置最大電流i2c_write(fd, 0x31, 0x13); // MD=1, IMAX=3=15mA// 5. 啟用 LED0 輸出(此時動畫自動啟動)i2c_write(fd, 0x30, 0x01); // LE0=1
}
📌 補充說明
-
i2c_write(fd, reg, val)
是偽函數,請根據你項目實際 I2C 封裝改寫。 -
PWM 模式建議配合 MCU 定時器運行(RTOS/裸機都行)
-
One Shot 模式如果想要同步多個通道運行,請用:
i2c_write(fd, 0x30, 0x00); // 全部關閉 // 配置三個 LEDxT 寄存器... i2c_write(fd, 0x31~0x33, 0x13); // MD=1 啟用 One Shot i2c_write(fd, 0x30, 0x07); // 同步啟用 LED0~2
? 需要我幫你寫成 C 工程結構(比如 Makefile、封裝接口、main 函數跑呼吸燈)也可以繼續說。如果你要在 ioctl 接口中封裝呼吸燈命令,也可以一起做。
太好了!那我們來逐步設計一個通用、靈活的 ioctl
控制接口,支持 AW2013 常亮、呼吸燈、多通道控制等功能。
? 一、設計目標
- 支持常亮、呼吸燈兩種模式
- 支持多通道 LED(LED0、LED1、LED2)獨立控制
- 用戶空間通過
ioctl()
控制驅動,不直接操作寄存器 - 簡化用戶邏輯,驅動完成寄存器映射和寫入
? 二、ioctl 命令定義
建議頭文件 aw2013_ioctl.h
#ifndef _AW2013_IOCTL_H_
#define _AW2013_IOCTL_H_#include <linux/ioctl.h>#define AW2013_MAGIC 'A'// 模式選擇
#define AW2013_MODE_PWM 0
#define AW2013_MODE_BREATH 1
#define AW2013_MODE_CONSTANT 2// 命令定義
#define AW2013_IOC_SET_MODE _IOW(AW2013_MAGIC, 0x01, struct aw2013_mode_cfg)
#define AW2013_IOC_LED_ON _IOW(AW2013_MAGIC, 0x02, int) // 參數: led_idx
#define AW2013_IOC_LED_OFF _IOW(AW2013_MAGIC, 0x03, int) // 參數: led_idx// PWM亮度/呼吸燈設置結構
struct aw2013_mode_cfg {int led; // 0,1,2 -> LED通道int mode; // AW2013_MODE_*int brightness; // 0~255(PWM模式、常亮模式使用)int imax; // 0~3 (0mA/5mA/10mA/15mA)// 呼吸燈用int t0; // 延遲啟動時間,單位:索引(0~8)int t1, t2, t3, t4; // 呼吸燈節奏時間(0~7)int repeat; // 重復次數,0 = 無限循環
};#endif
? 三、驅動側實現參考(關鍵邏輯)
static long aw2013_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{struct aw2013_dev *dev = filp->private_data;struct aw2013_mode_cfg cfg;switch (cmd) {case AW2013_IOC_SET_MODE:if (copy_from_user(&cfg, (void __user *)arg, sizeof(cfg)))return -EFAULT;return aw2013_config_mode(dev, &cfg);case AW2013_IOC_LED_ON:return aw2013_set_led(dev, (int)arg, true);case AW2013_IOC_LED_OFF:return aw2013_set_led(dev, (int)arg, false);default:return -EINVAL;}
}
函數 aw2013_config_mode()
根據模式不同,調用具體 PWM / 呼吸燈 / 常亮控制流程。
? 四、用戶層使用示例
#include "aw2013_ioctl.h"int main()
{int fd = open("/dev/aw2013", O_RDWR);struct aw2013_mode_cfg cfg = {.led = 0,.mode = AW2013_MODE_CONSTANT,.brightness = 128,.imax = 3, // 15mA};ioctl(fd, AW2013_IOC_SET_MODE, &cfg);ioctl(fd, AW2013_IOC_LED_ON, 0);close(fd);return 0;
}
? 五、可擴展方向
功能 | 可擴展方式 |
---|---|
呼吸燈動態變化 | 多個 cfg 結構發送 |
RGB 同步呼吸 | 同時配置 LED0/1/2 |
停止呼吸燈 | LED_OFF 或設置模式為常亮,PWM=0 |
支持多設備 | 用 /dev/aw2013X 多實例 |
如果你同意這個設計,我們可以繼續往下寫:
- 內核驅動端的
aw2013_config_mode()
函數實現 - 呼吸燈參數轉寄存器映射代碼
- 用戶層封裝的 CLI 工具(例如
aw2013ctl -m breath -l 1
) - 多通道控制 demo
需要哪一部分直接告訴我就行 😎