DWM22测试板

This commit is contained in:
2026-07-29 17:37:05 +08:00
parent 6d114add28
commit 99d4844c01
100 changed files with 6604 additions and 4433 deletions
@@ -0,0 +1,779 @@
# 1224V 2P2N双色LED H桥驱动原理与器件设计
## 1. 文档目的
本文针对一套输入电压为12~24V的双色LED H桥驱动电路。主功率桥由2只PMOS和2只NMOS组成,另外使用2只小信号NMOS驱动高边PMOS,因此整个驱动部分共使用6只MOS管。
本文说明:
- 2P2N主桥和2只驱动MOS分别承担什么工作;
- 双色LED为什么需要H桥改变电流方向;
- 两路PWM输入怎样控制暖光、冷光和关闭状态;
- 为什么两路输入绝对不能同时为高电平;
- 为什么换向必须先输出`00`并保留死区;
- PMOS为什么需要栅极上拉电阻和下拉电阻;
- 两个电阻为什么会形成分压;
- 电阻太大或太小分别会产生什么问题;
- 12V稳压管在电路中起什么作用;
- 如何计算PMOS的栅源电压、电阻功耗和稳压管电流;
- 如果取消稳压管,应当如何重新选择电阻;
- 为什么还必须检查死区时间、MOS管尖峰和PCB布局。
本文尽量使用直观的方式说明,适合刚接触MOS管驱动电路的工程人员阅读。
---
## 2. 完整电路由哪些部分组成
![1224V 2P2N双色LED H桥驱动原理图](images/12-24V_2P2N_H桥驱动原理图.png)
图1:本项目12~24V、2P2N主桥加2只小MOS驱动的完整原理图。
图中的主要器件分工如下:
| 器件 | 类型 | 作用 |
|---|---|---|
| Q1、Q2 | 高边PMOS60P03 | 分别把C端、W端连接到12~24V电源 |
| Q9、Q10 | 低边NMOS60N03 | 分别把C端、W端连接到GND |
| Q7、Q8 | 小信号NMOSAO3400A | 分别下拉Q1、Q2的栅极 |
| R1、R2 | 2.4kΩ上拉电阻 | 使Q1、Q2快速关断 |
| R3、R4 | 3kΩ下拉通路电阻 | 与R1、R2分压,限制高边PMOS的导通VGS |
| D1、D2 | 12V稳压管(BZT52C12 | 限制高边PMOS的栅源电压尖峰 |
| R14、R15 | 10kΩ栅源下拉电阻 | 确保Q9、Q10在控制信号悬空时保持关闭 |
### 2.1 2只高边PMOS
高边使用2只PMOS
- 左侧PMOS负责把输出端`C`连接到1224V电源;
- 右侧PMOS负责把输出端`W`连接到1224V电源。
PMOS适合放在高边,是因为它的源极可以直接接正电源,栅极只需要从源极电压向下拉,就能导通。
### 2.2 2只低边NMOS
低边使用2只NMOS
- 左侧NMOS负责把输出端`C`连接到GND
- 右侧NMOS负责把输出端`W`连接到GND。
低边NMOS的源极接地,MCU输出高电平后比较容易直接驱动其栅极。
### 2.3 2只PMOS驱动NMOS
MCU通常只有3.3V输出,不能直接把接在12~24V电源上的PMOS栅极拉到合适电位,所以增加2只小信号NMOS:
- 左侧驱动NMOS负责下拉左侧PMOS栅极;
- 右侧驱动NMOS负责下拉右侧PMOS栅极。
这2只小MOS不直接承受LED主电流,只负责PMOS栅极的充电和放电控制。
### 2.4 负载是反向并联双色LED
双色LED连接在`C``W`两个H桥输出端之间。两种颜色的LED芯片方向相反:
- 电流从`C`流向`W`时,点亮一种颜色;
- 电流从`W`流向`C`时,点亮另一种颜色;
- 两个方向快速分时工作时,肉眼看到混合色或中性光。
H桥的作用不是简单提供两路独立正电压,而是改变流过双色LED的电流方向。
---
## 3. 两路输入如何控制H桥
本文把两路控制信号称为:
- `PWM_W`:驱动Q7和对角线上的Q10,形成`C→W`电流;
- `PWM_C`:驱动Q8和对角线上的Q9,形成`W→C`电流。
按照当前交叉驱动结构,一路信号会同时控制一只高边PMOS和对角线上的一只低边NMOS。
> `PWM_C`、`PWM_W`是电路网络名称。最终点亮暖色还是冷色,还取决于双色LED的实际安装方向。
### 3.1 PWM_W有效
`PWM_W=1、PWM_C=0`时:
- Q7导通并下拉Q1的栅极,使左侧高边PMOS Q1导通;
- 对角线上的右侧低边NMOS Q10导通;
- `C`端接近电源;
- `W`端接近GND
- 电流方向为`电源 → C → LED → W → GND`
此时点亮一个颜色。
### 3.2 PWM_C有效
`PWM_C=1、PWM_W=0`时:
- Q8导通并下拉Q2的栅极,使右侧高边PMOS Q2导通;
- 对角线上的左侧低边NMOS Q9导通;
- `W`端接近电源;
- `C`端接近GND
- 电流方向为`电源 → W → LED → C → GND`
此时点亮另一个颜色。
### 3.3 两路均为低电平
`PWM_C=0、PWM_W=0`时:
- 两只高边PMOS关闭;
- 两只低边NMOS关闭;
- H桥处于关闭状态;
- LED没有持续驱动电流。
换向时必须先进入这个状态。
### 3.4 两路均为高电平
`PWM_C=1、PWM_W=1`是禁止状态。
此时两组对角桥臂同时收到导通命令,可能导致同一桥臂的上管和下管同时导通,形成:
```text
电源 → 上管 → 下管 → GND
```
这条路径几乎没有LED负载限流,会产生很大的直通电流,可能造成:
- 电源异响;
- MOS管快速发热;
- 电源电压跌落;
- MCU复位或蓝牙掉线;
- MOS管损坏;
- PCB走线或电源器件损坏。
控制真值表如下:
| PWM_C | PWM_W | H桥状态 | 结果 |
|---:|---:|---|---|
| 0 | 0 | 全部关闭 | 安全关闭/换向死区 |
| 0 | 1 | C高、W低 | 电流从C流向W |
| 1 | 0 | W高、C低 | 电流从W流向C |
| 1 | 1 | 禁止状态 | 可能发生桥臂直通 |
---
## 4. 为什么换向必须设置死区
MOS管不是收到控制电平后立即完成导通或关断。栅极电容、米勒平台、驱动电阻和PCB寄生参数都会产生延迟。
如果直接执行:
```text
PWM_C有效 → PWM_W有效
```
可能出现:
- 原方向的PMOS和NMOS还没有完全关闭;
- 新方向的PMOS和NMOS已经开始导通;
- 两个方向在很短时间内重叠;
- H桥形成瞬间直通。
正确换向顺序应为:
```text
方向C导通 → 输出00 → 等待死区 → 方向W导通
方向W导通 → 输出00 → 等待死区 → 方向C导通
```
死区时间不能只根据软件定时值决定,必须结合实际MOS管栅极波形测量。对于本类低频LED PWM,可以先设置较保守的死区进行验证,再根据示波器结果缩短。
需要注意:
- 死区太短,可能发生直通;
- 死区太长,会降低最大有效占空比和LED峰值亮度;
- 调高PWM频率后,相同死区占整个周期的比例会变大;
- PMOS上拉电阻变大后,通常需要重新确认死区是否足够。
---
## 5. 先认识PMOS的三个引脚
PMOS有三个主要引脚:
- `S`:源极(Source),本电路接12V或24V电源;
- `G`:栅极(Gate),用于控制PMOS导通和关断;
- `D`:漏极(Drain),连接H桥输出端。
PMOS是否导通,主要取决于栅源电压:
```text
VGS = VG - VS
```
其中:
- `VG`是栅极对地电压;
- `VS`是源极对地电压。
假设源极接24V
| 栅极电压VG | 栅源电压VGS | PMOS状态 |
|---:|---:|---|
| 24V | 0V | 关断 |
| 20V | -4V | 开始较明显导通 |
| 14V | -10V | 充分导通 |
| 12V | -12V | 充分导通 |
| 0V | -24V | 超过多数PMOS的栅源耐压,危险 |
> 注意:数据手册中的`VGS(th)`是“刚开始有很小电流”的开启阈值,不代表MOS管已经充分导通。
以SL60P03D为例:
- `VGS(th)`约为-1.0V至-2.2V
- 导通电阻通常在`VGS=-4.5V``VGS=-10V`条件下标定;
- 栅源极绝对最大耐压为`±20V`
所以“20V”不是开启阈值,而是不能超过的栅源极极限耐压。
---
## 6. 上拉电阻和下拉电阻分别做什么
为避免受到原理图位号差异影响,本文统一使用下面的名称:
- `RUP`:PMOS栅极到源极(电源)的上拉电阻;
- `RDOWN`PMOS栅极到地的下拉电阻;
- `DZ`:跨接在PMOS栅极和源极之间的稳压管;
- `QDRV`:把PMOS栅极向地拉低的小信号MOS管。
简化结构如下:
```text
电源12V/24V
|
+--------- PMOS源极S
|
RUP
|
+--------- PMOS栅极G
|
RDOWN
|
QDRV
|
GND
DZ稳压管跨接在PMOS的S和G之间。
```
### 6.1 PMOS关断过程
`QDRV`关闭后,下拉路径断开,`RUP`把PMOS栅极充电到源极电压:
```text
VG ≈ VS
VGS ≈ 0V
```
PMOS关断。
因此,`RUP`越小,给栅极电容充电的电流越大,PMOS通常关断得越快。
### 6.2 PMOS导通过程
`QDRV`导通后,`RUP``RDOWN`形成从电源到地的分压回路,栅极电压下降,PMOS得到负的`VGS`并导通。
因此:
- `RUP`太小:关断快,但栅极不容易被拉低,PMOS导通电压可能不足;
- `RUP`太大:PMOS容易得到较大的负`VGS`,但栅极充电慢,关断时间增加;
- `RDOWN`太小:PMOS导通更充分,但电流和电阻功耗增加;
- `RDOWN`太大:功耗降低,但PMOS导通电压减小。
两个电阻必须综合考虑,不能只追求其中一个方向。
---
## 7. 没有稳压管时如何计算
先忽略稳压管,假设`QDRV`已经完全导通。
栅极电压为:
```text
VG = VCC × RDOWN / (RUP + RDOWN)
```
PMOS栅源电压的绝对值为:
```text
|VGS| = VCC × RUP / (RUP + RDOWN)
```
回路电流为:
```text
I = VCC / (RUP + RDOWN)
```
两个电阻的功耗分别为:
```text
PUP = I² × RUP
PDOWN = I² × RDOWN
```
### 7.1 当前原理图:24V、上拉2.4kΩ、下拉3kΩ
```text
VCC = 24V
RUP = 2.4kΩ
RDOWN = 3kΩ
```
计算结果:
```text
VG = 24 × 3 / (2.4 + 3) ≈ 13.33V
VGS = 13.33 - 24 ≈ -10.67V
I = 24 / 5.4k ≈ 4.44mA
PUP = I² × 2.4k ≈ 47mW
PDOWN = I² × 3k ≈ 59mW
```
所以栅极并不会被拉到0V,而是被两个电阻分压到约13.33V。
PMOS得到约-10.67V的栅源电压,能够充分导通。这个数值没有达到12V稳压管的击穿电压,因此D1/D2在稳定导通状态下基本不工作,主要用于处理换向尖峰。
### 7.2 当前原理图:12V、上拉2.4kΩ、下拉3kΩ
同样的电阻在12V输入下:
```text
VG = 12 × 3 / (2.4 + 3) ≈ 6.67V
VGS = 6.67 - 12 ≈ -5.33V
I = 12 / 5.4k ≈ 2.22mA
PUP ≈ 12mW
PDOWN ≈ 15mW
```
此时PMOS仍然可以可靠导通,而且12V稳压管在正常稳定状态下不会反向击穿。
---
## 8. 稳压管的真正作用
12V稳压管跨接在PMOS的源极和栅极之间,主要作用是限制`|VGS|`
### 8.1 正常关断时
PMOS栅极被`RUP`拉到源极电压:
```text
VGS ≈ 0V
```
稳压管不工作。
### 8.2 正常导通时
栅极被下拉,`|VGS|`逐渐增大。
`|VGS|`接近稳压管的击穿电压后,稳压管开始反向导通,把`|VGS|`限制在大约12V附近。
24V输入、12V稳压管钳位时,理想状态约为:
```text
VS ≈ 24V
VG ≈ 12V
VGS ≈ -12V
```
### 8.3 换向尖峰出现时
H桥换向会受到以下因素影响:
- MOS管栅极电容;
- 米勒电容;
- PCB走线电感;
- LED和供电线路电感;
- MOS管体二极管反向恢复;
- 电源母线尖峰。
这些因素可能让`VGS`在很短时间内超过正常分压值。稳压管可以吸收部分栅源尖峰,避免PMOS栅极氧化层承受过高电压。
### 8.4 正向栅源尖峰
如果换向时栅极瞬间高于源极,稳压管会像普通二极管一样正向导通,把正向`VGS`限制在约0.7V至1V附近。
### 8.5 稳压管不能保护什么
栅源稳压管只能保护PMOS的`VGS`,不能保护PMOS的漏源极`VDS`
例如:
- 电源为24V
- PMOS的`VDS`额定值为-30V。
这时漏源极只有约6V的理论尖峰余量。电源母线仍需考虑:
- TVS管;
- 就近低ESR电容;
- 较短、较宽的功率走线;
- 减小H桥电流环路面积;
- 必要时使用耐压更高的MOS管。
---
## 9. 为什么稳压管不是接上就一定能稳定在12V
稳压管必须获得足够的反向电流,才能进入比较稳定的击穿区。
为了说明稳压管为什么需要足够电流,下面使用“上拉1.2kΩ、下拉1kΩ”作为对比算例。这不是图1当前采用的2.4kΩ、3kΩ参数。
假设:
```text
VCC = 24V
VZ = 12V
RUP = 1.2kΩ
RDOWN = 1kΩ
```
钳位后栅极约为12V。
下拉电阻电流:
```text
IDOWN = 12V / 1kΩ = 12mA
```
上拉电阻电流:
```text
IUP = (24V - 12V) / 1.2kΩ = 10mA
```
稳压管电流约为:
```text
IZ = IDOWN - IUP = 12mA - 10mA = 2mA
```
因此,1.2kΩ上拉加1kΩ下拉时,稳压管大约只有2mA电流。
这通常可以产生一定的钳位作用,但实际电压未必正好是12.00V。稳压管的标称电压、测试电流、动态电阻和温度特性需要查看具体厂家的数据手册。
如果上拉和下拉都是1kΩ:
```text
IUP = 12mA
IDOWN = 12mA
IZ ≈ 0mA
```
此时稳压管几乎没有剩余电流,不能指望它进入稳定的反向击穿状态。
对于图1当前的2.4kΩ上拉和3kΩ下拉,在24V正常导通时,计算得到`|VGS|≈10.67V`,低于12V,因此稳压管不会持续击穿。这正是更合适的状态:正常工作由电阻分压确定栅极电压,稳压管只处理异常瞬态。
---
## 10. 为什么电阻不能只考虑关断速度
MOS管的栅极不是普通的纯电阻负载,可以把它理解为一个需要充电和放电的电容。
SL60P03D的典型参数包括:
- 输入电容`CISS`约为1988pF
- 总栅极电荷`Qg`约为35nC(特定测试条件下);
- 米勒电荷`Qgd`约为8.8nC。
PMOS关断时,`RUP`负责给栅极充电。可以先用RC时间常数粗略估算:
```text
τ ≈ RUP × CISS
```
例如:
| RUP | 估算时间常数τ |
|---:|---:|
| 1.2kΩ | 约2.4μs |
| 2.2kΩ | 约4.4μs |
| 2.4kΩ | 约4.8μs |
| 3.6kΩ | 约7.2μs |
实际关断时间还受到栅极电荷、米勒平台、漏极电压变化和PCB寄生参数影响,不能只用一个RC公式定论。
### 10.1 RUP太大
可能产生:
- PMOS关断变慢;
- 换向时上管尚未完全关断,下管已经开启;
- H桥上下管短暂直通;
- 电源出现大电流尖峰;
- MOS管异常发热;
- 电路发出异响;
- 严重时损坏MOS管或电源。
### 10.2 RUP太小
可能产生:
- PMOS关断速度加快;
- 但下拉时大量电流被RUP分走;
- 栅极下拉不够,PMOS的负`VGS`不足;
- PMOS没有充分导通,导通电阻增大;
- 驱动回路静态功耗增加;
- 电阻和驱动管温升增加。
所以“上拉电阻越小越安全”并不成立。
---
## 11. 电阻功耗不能只按照死区时间计算
这是非常容易出现的误区。
死区时间,例如25μs或50μs,表示换向时两边都关闭的保护时间。它不代表上拉、下拉电阻只通电25μs或50μs。
当PMOS保持导通时:
- `QDRV`持续导通;
- `RUP``RDOWN`和稳压管可能持续有电流;
- 电阻功耗会持续整个PMOS导通阶段。
因此必须分别检查:
1. 正常导通期间的连续或平均功耗;
2. 换向尖峰期间的瞬时脉冲功耗。
### 11.1 对比算例:24V钳位在12V、RUP=1.2kΩ、RDOWN=1kΩ
钳位时:
```text
PUP = 12² / 1.2k ≈ 120mW
PDOWN = 12² / 1k ≈ 144mW
PZ = 12V × 2mA ≈ 24mW
```
普通0603电阻常见连续额定功率约为0.1W,但不同厂家、环境温度和PCB焊盘条件会有差异。
因此:
- 120mW和144mW不能简单地当成“只有50μs”;
- 如果PMOS长时间保持导通,电阻可能接近连续承受该功耗;
- 建议使用0805封装,或使用多个电阻分担功耗;
- 最终必须查看所选电阻的数据手册和降额曲线。
图1当前采用2.4kΩ上拉和3kΩ下拉,24V稳定工作时功耗分别约为47mW和59mW,不会出现上述持续钳位功耗;但0603电阻仍应考虑环境温度和功率降额。
---
## 12. 取消稳压管时如何选择电阻
如果决定不安装稳压管,就必须完全依靠电阻分压限制`VGS`
设计时应检查最坏情况:
```text
|VGS|max = VCC,max × RUP,max / (RUP,max + RDOWN,min)
```
必须同时考虑:
- 电源最高电压;
- 电源启动和负载突卸尖峰;
- 电阻误差;
- 温度;
- 驱动管导通压降;
- PCB寄生参数。
### 12.1 同时兼容12V和24V的参考值
可以考虑:
```text
RUP = 2.4kΩ
RDOWN = 3kΩ
```
计算结果:
| 输入电压 | 栅源电压VGS | 回路电流 |
|---:|---:|---:|
| 12V | 约-5.33V | 约2.22mA |
| 24V | 约-10.67V | 约4.44mA |
24V时电阻功耗:
```text
PUP ≈ 47mW
PDOWN ≈ 59mW
```
这个组合具有以下特点:
- 12V输入时仍能获得约-5.33V驱动;
- 24V输入时约为-10.67V
- 正常功耗低于1.2kΩ加1kΩ方案;
- 2.4kΩ上拉的关断速度仍然较快;
- 不需要依靠稳压管在正常工作时持续击穿。
即使使用这个分压,保留稳压管仍然有价值:它在正常工作时不导通,只在异常尖峰时保护PMOS。
---
## 13. 两种方案对比
### 方案A:电阻分压加稳压管
优点:
- 对栅源尖峰有额外保护;
- 元件误差或异常状态下更安全;
- 可以限制`VGS`不超过约12V。
缺点:
- 必须保证稳压管具有合适的工作电流;
- 如果设计成稳压管持续击穿,会增加静态功耗;
- 电阻功耗和稳压管功耗都需要核算。
适合:
- 24V供电;
- H桥换向尖峰明显;
- 对可靠性要求较高;
- PCB空间允许增加保护器件。
### 方案B:只使用电阻分压
优点:
- 元件少;
- 不存在稳压管持续工作产生的额外功耗;
- 参数计算直观。
缺点:
- 失去栅源尖峰钳位;
- 对电源波动、电阻误差和PCB寄生参数更敏感;
- 上拉电阻开路等故障可能让`VGS`超过额定值。
适合:
- 输入电压范围明确;
- 电源尖峰受到良好控制;
- 已经通过示波器确认`VGS`安全;
- 有足够的设计余量。
---
## 14. 本电路的建议
### 14.1 如果保留12V稳压管
建议:
- 不要只根据“关断越快越好”无限减小上拉电阻;
- 计算稳压管电流,确认能够形成有效钳位;
- 按整个PMOS导通时间核算电阻平均功耗;
- 对超过或接近0.1W的电阻优先使用0805;
- 用示波器测量真实`VGS`,确认导通时约为-10V至-12V,关断时回到0V。
### 14.2 如果取消稳压管
12V至24V输入可以先测试:
```text
RUP = 2.4kΩ
RDOWN = 3kΩ
```
但必须满足:
- 实测最大负`VGS`有足够余量;
- 实测正向和反向尖峰没有接近`±20V`
- 电源母线已经做好TVS和就近电容;
- PMOS能在下管开启前完全关断;
- 保留足够的硬件或软件死区。
### 14.3 关于死区
死区的最终取值不能仅凭计算,应根据示波器实测决定。
至少同时测量:
- 上管PMOS的`VGS`
- 下管NMOS的`VGS`
- H桥输出节点;
- 24V母线电压;
- 条件允许时测量桥臂电流。
判断标准是:
> 下管开始导通之前,对应上管必须已经退出导通区,并且换向过程中没有异常母线电流尖峰。
---
## 15. 初学者常见误区
### 误区一:PMOS的20V是开启阈值
错误。20V通常是栅源极最大耐压。真正的`VGS(th)`一般只有约1V至3V,但这个电压只能让MOS管刚刚开始导通。
### 误区二:栅极下拉后一定是0V
错误。如果存在上拉和下拉电阻,栅极由两个电阻分压,不会自然等于0V。
### 误区三:装了12V稳压管,VGS就一定是-12V
错误。稳压管必须获得足够的反向电流,实际钳位电压还受到电流、温度和器件误差影响。
### 误区四:上拉电阻越小,电路越安全
错误。上拉电阻减小会加快关断,但也会降低PMOS导通时的负`VGS`,并增加静态功耗。
### 误区五:电阻的高功耗只持续死区时间
错误。PMOS导通期间,分压回路可能持续有电流。必须按照实际占空比和最坏工作状态核算平均功耗。
### 误区六:栅源稳压管可以保护整个MOS管
错误。它主要保护`VGS`,不能代替24V母线TVS,也不能阻止`VDS`超过MOS管额定值。
---
## 16. 最终检查清单
原理图确定后,至少完成以下检查:
- [ ] 确认PMOS的`VGS(th)`、推荐驱动电压和`VGS(max)`
- [ ] 计算12V和24V下的正常`VGS`
- [ ] 计算最高电源电压和电阻误差下的最坏`VGS`
- [ ] 计算上拉、下拉电阻连续功耗;
- [ ] 计算稳压管正常电流和功耗;
- [ ] 检查0603/0805电阻的额定功率和降额曲线;
- [ ] 测量PMOS栅极对源极波形,而不是只测栅极对地;
- [ ] 检查换向时是否有正向或反向`VGS`尖峰;
- [ ] 检查上下管是否发生交叉导通;
- [ ] 验证`PWM_C=1、PWM_W=1`在软硬件中都不会出现;
- [ ] 验证每次方向切换都经过`00`关闭状态;
- [ ] 检查24V母线是否超过PMOS的`VDS`额定值;
- [ ] 高温、低温、最低输入和最高输入条件下重复测试。
---
## 17. 总结
PMOS栅极驱动电阻的选择,本质上是在以下四项之间寻找平衡:
1. PMOS必须得到足够的负`VGS`,保证充分导通;
2. PMOS必须快速回到`VGS≈0V`,保证及时关断;
3. 分压回路的电流和电阻功耗不能过大;
4. 栅源电压和换向尖峰不能超过MOS管额定值。
稳压管的核心作用是保护PMOS栅源极,而不是替代电阻分压,也不是控制死区。合理的设计应先用电阻比例确定正常工作点,再用稳压管处理异常和瞬态过压,最后通过示波器实测确认。
对于这套12~24V、2P2N主桥加2只驱动MOS的双色LED电路,还必须始终遵守两个基本原则:
1. `PWM_C``PWM_W`不能同时为高电平;
2. 两个电流方向切换时,必须先输出`00`,等待确认安全的死区后再开启另一方向。
Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

@@ -102,7 +102,12 @@ static uint8_t pair_command_replay;
#define PAIRING_WINDOW_TICKS 50000UL
#define RF433_RELEASE_TIMEOUT_TICKS 1500U
#define RF433_MS_TO_SAMPLE_TICKS(ms) ((uint16_t)((ms) * (1000U / RF433_DECODER_SAMPLE_US)))
#define RF433_MODE_REPEAT_TICKS ((uint32_t)RF433_MS_TO_SAMPLE_TICKS(500U))
uint8_t long_flag_s=0;
static volatile uint32_t rf433_sample_ticks;
static uint32_t rf433_mode_last_action_tick;
static uint8_t rf433_mode_last_key;
static uint8_t rf433_mode_action_valid;
void _433_fun(void);
@@ -422,8 +427,38 @@ static void set_click(){
}
}
static uint8_t rf433_is_mode_step_command(uint8_t command)
{
return command == Mode_add || command == Mode_dow;
}
/*
* Act immediately on the first valid mode frame. Repeated frames carrying
* the same key are accepted at most once every 500 ms. Keep this independent
* from the generic 150 ms release detector so an occasional missing RF frame
* cannot turn one physical hold into several rapid short presses.
*/
static uint8_t rf433_mode_step_ready(uint8_t command)
{
uint32_t now = rf433_sample_ticks;
if(!rf433_mode_action_valid ||
rf433_mode_last_key != command ||
(uint32_t)(now - rf433_mode_last_action_tick) >=
RF433_MODE_REPEAT_TICKS)
{
rf433_mode_last_key = command;
rf433_mode_last_action_tick = now;
rf433_mode_action_valid = 1U;
return 1U;
}
return 0U;
}
void rf433_receive(void)//RF433 sample, called every 100 us
{
rf433_sample_ticks++;
rf433_decoder_sample((RF_DATA == HIGH_LEVEL) ? 1U : 0U);
if(long_time > 0U)
@@ -473,8 +508,15 @@ void _433_fun(){
pair_deferred_receive_data = receive_data;
return;
}
if(Key_TypeDef.KEY_STATE_Click==1||KEY_STATE_re==1) return;
set_click();
if(rf433_is_mode_step_command(res_data))
{
if(!rf433_mode_step_ready(res_data)) return;
}
else
{
if(Key_TypeDef.KEY_STATE_Click==1||KEY_STATE_re==1) return;
set_click();
}
switch(res_data){
//椭圆
case ON://单击
@@ -390,7 +390,6 @@ int main(void)
#endif
wdt_init();
/* Set the broadcast address of the device. */
board_init();
xc_fmc_spi_init_oprt( );
@@ -398,6 +397,8 @@ int main(void)
fmc_spi_read();
power_restore_apply_on_boot();
/* Start the watchdog after the optional boot-time Flash update. */
wdt_init();
timer0_2_init();
bluetooth_init();
@@ -522,13 +522,18 @@ __RAM_CODE void Bridge_Service_1ms(void)
(BRIDGE_MIX_SCALE / 2U)) / BRIDGE_MIX_SCALE);
/*
* A mixed H-bridge frame has 450 us of active time after deadtime.
* Use the same 450/500 energy at both single-color endpoints of the
* continuous gradient so its total brightness does not jump there.
* Continuous CCT always uses the same 450/500 endpoint energy.
* A static color transition also reaches its single-color endpoint
* at 90%, then light_transition.c restores it to 100% over 900 ms.
*/
if (Mode == mode3 && choose_mode_falsg == 7U) {
pwm_duty = (uint16_t)(
((uint32_t)pwm_duty * BRIDGE_DUAL_ACTIVE_US +
(BRIDGE_FRAME_US / 2U)) / BRIDGE_FRAME_US);
} else if (Mode == mode0 && choose_mode_falsg <= 2U) {
pwm_duty = (uint16_t)(
((uint32_t)pwm_duty *
Light_Transition_StaticEndpointScale_Q12 + 2048U) >> 12);
}
if (output_mode == BRIDGE_MODE_SINGLE &&
@@ -289,14 +289,9 @@ void power_restore_apply_on_boot(void)
power_cycle_next_mode = (uint8_t)((mode_index + 1U) % 3U);
/*
* Save the next startup mode before timers, BLE and the H-bridge start.
* A deferred flash erase/write masks interrupts long enough to stretch
* one Timer3-controlled dual-color pulse and causes a visible flash.
* Cycle-static is also a remembered state. Start PWM, BLE and the
* H-bridge through the same path as full-memory restore, then persist
* the next static mode through the normal deferred Flash state machine.
*/
wright_user_data();
GLOBAL_INT_DISABLE();
xc_fmc_spi_flash_erase_page(USER_DATA_FLASH_ADDR);
xc_fmc_spi_flash_write_page(USER_DATA_FLASH_ADDR,
app_data, FLASH_PAGE_SIZE);
GLOBAL_INT_RESTORE();
set_TaskComps_timer(2U, POWER_POLICY_SAVE_DELAY_MS);
}
@@ -6,10 +6,19 @@ volatile uint8_t Light_Transition_FadeActive;
volatile uint8_t Light_Transition_ModeActive;
volatile uint32_t Light_Transition_W_Output_Q12;
volatile uint32_t Light_Transition_C_Output_Q12;
volatile uint16_t Light_Transition_StaticEndpointScale_Q12 = 4096U;
#define BRIGHTNESS_SMOOTH_SHIFT 4U
#define OUTPUT_SMOOTH_SHIFT 4U
#define MODE_TRANSITION_TICKS 40U
#define MODE_TRANSITION_TICKS 100U
#define CCT_RING_TRANSITION_TICKS 40U
#define STATIC_ENDPOINT_SCALE_START_Q12 3686U
#define STATIC_ENDPOINT_SCALE_MAX_Q12 4096U
#define STATIC_PRE_TRANSITION_TICKS 50U
#define STATIC_ENDPOINT_RECOVERY_TICKS 180U
#define TRANSITION_CURVE_LINEAR 0U
#define TRANSITION_CURVE_GAMMA_S 1U
#define TRANSITION_CURVE_GAMMA_OUT 2U
#define LIGHT_OUTPUT_SCALE 1000U
#define BREATH_MIN_OUTPUT (LIGHT_OUTPUT_SCALE / 100U)
#define DUAL_MIN_STABLE_CHANNEL_OUTPUT 102U
@@ -78,6 +87,29 @@ static const uint16_t power_fade_gamma_q12[101] = {
4096U
};
/*
* Symmetric Gamma 1.8 transition curve:
* q = p^1.8 / (p^1.8 + (1-p)^1.8)
*
* Unlike applying Gamma independently to W and C, q and (1-q) remain
* complementary. The transition therefore eases in and out without causing
* a brightness dip in the middle. A table keeps the 5 ms task free of
* floating-point and power calculations.
*/
static const uint16_t transition_gamma_s_q12[101] = {
0U, 1U, 4U, 8U, 13U, 20U, 29U, 39U, 50U, 63U,
77U, 93U, 110U, 130U, 150U, 173U, 197U, 223U, 251U, 281U,
312U, 345U, 381U, 418U, 457U, 498U, 541U, 586U, 633U, 681U,
732U, 784U, 839U, 895U, 953U, 1012U, 1073U, 1136U, 1200U, 1265U,
1332U, 1400U, 1469U, 1539U, 1610U, 1682U, 1754U, 1827U, 1901U, 1974U,
2048U, 2122U, 2195U, 2269U, 2342U, 2414U, 2486U, 2557U, 2627U, 2696U,
2764U, 2831U, 2896U, 2960U, 3023U, 3084U, 3143U, 3201U, 3257U, 3312U,
3364U, 3415U, 3463U, 3510U, 3555U, 3598U, 3639U, 3678U, 3715U, 3751U,
3784U, 3815U, 3845U, 3873U, 3899U, 3923U, 3946U, 3966U, 3986U, 4003U,
4019U, 4033U, 4046U, 4057U, 4067U, 4076U, 4083U, 4088U, 4092U, 4095U,
4096U
};
static uint16_t current_brightness_q12;
static uint16_t power_fade_progress_q12;
static uint16_t power_fade_remainder;
@@ -86,6 +118,13 @@ static uint8_t transition_sync_pending;
static uint16_t mode_transition_start_w;
static uint16_t mode_transition_start_c;
static uint8_t mode_transition_tick;
static uint8_t mode_transition_total_ticks;
static uint8_t mode_transition_gamma_curve;
static uint8_t static_pre_transition_active;
static uint8_t static_pre_transition_tick;
static uint16_t static_pre_transition_start_scale_q12;
static uint8_t static_endpoint_recovery_active;
static uint8_t static_endpoint_recovery_tick;
static volatile uint8_t feedback_active;
static volatile uint8_t feedback_on;
@@ -153,24 +192,54 @@ static uint16_t approach_target(uint16_t current, uint16_t target)
return current - step;
}
static uint16_t transition_gamma_s_scale(uint8_t tick, uint8_t total_ticks)
{
uint16_t index;
if(total_ticks == 0U || tick >= total_ticks) return 4096U;
index = (uint16_t)(((uint16_t)tick * 100U +
(total_ticks / 2U)) / total_ticks);
if(index > 100U) index = 100U;
return transition_gamma_s_q12[index];
}
static uint16_t transition_gamma_out_scale(uint8_t tick, uint8_t total_ticks)
{
uint16_t index;
if(total_ticks == 0U || tick >= total_ticks) return 4096U;
index = (uint16_t)(((uint16_t)tick * 100U +
(total_ticks / 2U)) / total_ticks);
if(index > 100U) index = 100U;
return (uint16_t)(4096U - power_fade_gamma_q12[100U - index]);
}
static uint16_t interpolate_mode_output(uint16_t start, uint16_t target,
uint8_t tick)
{
uint32_t delta;
uint16_t progress_q12;
uint8_t total_ticks = mode_transition_total_ticks;
if(total_ticks == 0U || tick >= total_ticks) return target;
if(mode_transition_gamma_curve == TRANSITION_CURVE_GAMMA_S)
progress_q12 = transition_gamma_s_scale(tick, total_ticks);
else if(mode_transition_gamma_curve == TRANSITION_CURVE_GAMMA_OUT)
progress_q12 = transition_gamma_out_scale(tick, total_ticks);
else
progress_q12 = (uint16_t)(
((uint32_t)tick * 4096U + (total_ticks / 2U)) / total_ticks);
if(tick >= MODE_TRANSITION_TICKS) return target;
if(target >= start)
{
delta = (uint32_t)(target - start) * tick;
delta = (uint32_t)(target - start) * progress_q12;
return (uint16_t)(start +
((delta + (MODE_TRANSITION_TICKS / 2U)) /
MODE_TRANSITION_TICKS));
((delta + 2048U) >> 12));
}
delta = (uint32_t)(start - target) * tick;
delta = (uint32_t)(start - target) * progress_q12;
return (uint16_t)(start -
((delta + (MODE_TRANSITION_TICKS / 2U)) /
MODE_TRANSITION_TICKS));
((delta + 2048U) >> 12));
}
static uint16_t effect_gamma_output(uint16_t level)
@@ -265,6 +334,53 @@ void Light_Transition_BeginModeChange(void)
mode_transition_start_w = W_PWM_duty;
mode_transition_start_c = C_PWM_duty;
mode_transition_tick = 0U;
mode_transition_total_ticks =
(choose_mode_falsg == CUSTOM_TEMPERATURE_MODE)
? CCT_RING_TRANSITION_TICKS : MODE_TRANSITION_TICKS;
if(Mode == mode0 && choose_mode_falsg <= 2U)
mode_transition_gamma_curve = TRANSITION_CURVE_GAMMA_S;
else if(Mode == mode0 &&
choose_mode_falsg == CUSTOM_TEMPERATURE_MODE)
mode_transition_gamma_curve = TRANSITION_CURVE_GAMMA_OUT;
else
mode_transition_gamma_curve = TRANSITION_CURVE_LINEAR;
if(Mode == mode0 && choose_mode_falsg <= 2U)
{
/*
* A dual-color bridge frame has only 450 us of active time, while a
* single-color hardware-PWM frame has the full 500 us. If the current
* output is single color, first fade its frame energy from 100% to
* 90% without changing color. The following mixed-light transition
* can then start at the same 450 us energy without an abrupt drop.
*/
static_pre_transition_active = 0U;
static_pre_transition_tick = 0U;
static_pre_transition_start_scale_q12 =
Light_Transition_StaticEndpointScale_Q12;
if(((mode_transition_start_w == 0U) ^
(mode_transition_start_c == 0U)) &&
Light_Transition_StaticEndpointScale_Q12 >
STATIC_ENDPOINT_SCALE_START_Q12)
{
static_pre_transition_active = 1U;
}
else
{
Light_Transition_StaticEndpointScale_Q12 =
STATIC_ENDPOINT_SCALE_START_Q12;
}
static_endpoint_recovery_active = 0U;
static_endpoint_recovery_tick = 0U;
}
else
{
Light_Transition_StaticEndpointScale_Q12 =
STATIC_ENDPOINT_SCALE_MAX_Q12;
static_pre_transition_active = 0U;
static_pre_transition_tick = 0U;
static_endpoint_recovery_active = 0U;
static_endpoint_recovery_tick = 0U;
}
Light_Transition_ModeActive = 1U;
}
@@ -304,6 +420,8 @@ void Light_Transition_Task(void)
uint16_t floor_w;
uint32_t scaled_w_q12;
uint32_t scaled_c_q12;
uint32_t scale_delta;
uint16_t endpoint_curve_q12;
uint8_t power_transitioning;
/*
@@ -322,7 +440,36 @@ void Light_Transition_Task(void)
}
if(!powered_on)
{
Light_Transition_ModeActive = 0U;
Light_Transition_StaticEndpointScale_Q12 =
STATIC_ENDPOINT_SCALE_MAX_Q12;
static_pre_transition_active = 0U;
static_pre_transition_tick = 0U;
static_endpoint_recovery_active = 0U;
static_endpoint_recovery_tick = 0U;
}
if(static_endpoint_recovery_active)
{
scale_delta =
STATIC_ENDPOINT_SCALE_MAX_Q12 -
STATIC_ENDPOINT_SCALE_START_Q12;
static_endpoint_recovery_tick++;
endpoint_curve_q12 = transition_gamma_s_scale(
static_endpoint_recovery_tick,
STATIC_ENDPOINT_RECOVERY_TICKS);
Light_Transition_StaticEndpointScale_Q12 = (uint16_t)(
STATIC_ENDPOINT_SCALE_START_Q12 +
((scale_delta * endpoint_curve_q12 + 2048U) >> 12));
if(static_endpoint_recovery_tick >= STATIC_ENDPOINT_RECOVERY_TICKS)
{
Light_Transition_StaticEndpointScale_Q12 =
STATIC_ENDPOINT_SCALE_MAX_Q12;
static_endpoint_recovery_active = 0U;
}
}
/*
* Keep APP brightness tracking while off. Power fading is a separate
@@ -428,15 +575,67 @@ void Light_Transition_Task(void)
if(Light_Transition_ModeActive && powered_on && !power_transitioning)
{
mode_transition_tick++;
W_PWM_duty =
interpolate_mode_output(mode_transition_start_w, target_w,
mode_transition_tick);
C_PWM_duty =
interpolate_mode_output(mode_transition_start_c, target_c,
mode_transition_tick);
if(mode_transition_tick >= MODE_TRANSITION_TICKS)
if(static_pre_transition_active)
{
uint16_t pre_curve_q12;
uint32_t pre_scale_delta;
static_pre_transition_tick++;
pre_curve_q12 = transition_gamma_s_scale(
static_pre_transition_tick,
STATIC_PRE_TRANSITION_TICKS);
pre_scale_delta =
static_pre_transition_start_scale_q12 -
STATIC_ENDPOINT_SCALE_START_Q12;
Light_Transition_StaticEndpointScale_Q12 = (uint16_t)(
static_pre_transition_start_scale_q12 -
((pre_scale_delta * pre_curve_q12 + 2048U) >> 12));
W_PWM_duty = mode_transition_start_w;
C_PWM_duty = mode_transition_start_c;
if(static_pre_transition_tick >= STATIC_PRE_TRANSITION_TICKS)
{
Light_Transition_StaticEndpointScale_Q12 =
STATIC_ENDPOINT_SCALE_START_Q12;
static_pre_transition_active = 0U;
}
}
else
{
mode_transition_tick++;
W_PWM_duty =
interpolate_mode_output(mode_transition_start_w, target_w,
mode_transition_tick);
C_PWM_duty =
interpolate_mode_output(mode_transition_start_c, target_c,
mode_transition_tick);
}
/*
* At low brightness, integer PWM resolution can reach the requested
* single-color endpoint before the nominal transition tick ends.
* Begin the 90%->100% envelope at that physical endpoint instead of
* waiting and creating a visible pause followed by a final lift.
*/
if(!static_pre_transition_active &&
!static_endpoint_recovery_active &&
Mode == mode0 && choose_mode_falsg <= 2U &&
((target_w == 0U && W_PWM_duty == 0U) ||
(target_c == 0U && C_PWM_duty == 0U)))
{
static_endpoint_recovery_tick = 0U;
static_endpoint_recovery_active = 1U;
}
if(!static_pre_transition_active &&
mode_transition_tick >= mode_transition_total_ticks)
{
Light_Transition_ModeActive = 0U;
if(!static_endpoint_recovery_active &&
Mode == mode0 && choose_mode_falsg <= 2U &&
(target_w == 0U || target_c == 0U))
{
static_endpoint_recovery_tick = 0U;
static_endpoint_recovery_active = 1U;
}
}
}
else if(((Mode == mode2 || Mode == mode3) && powered_on) ||
power_transitioning ||
@@ -7,6 +7,7 @@ extern volatile uint8_t Light_Transition_FadeActive;
extern volatile uint8_t Light_Transition_ModeActive;
extern volatile uint32_t Light_Transition_W_Output_Q12;
extern volatile uint32_t Light_Transition_C_Output_Q12;
extern volatile uint16_t Light_Transition_StaticEndpointScale_Q12;
#define Light_Transition_RequestOn() (Light_Transition_FadeActive = 0U)
#define Light_Transition_RequestOff() (Light_Transition_FadeActive = 1U)
File diff suppressed because it is too large Load Diff
@@ -22,44 +22,64 @@ Dialog DLL: TARMCM1.DLL V1.14.6.0
<h2>Project:</h2>
D:\workplace\工作文件\程序\新向远XC6517蓝牙芯片\PWM32EPRO\project\example\ble\ble_peripheral\mdk\ble_peripheral.uvprojx
Project File Date: 07/26/2026
Project File Date: 07/29/2026
<h2>Output:</h2>
*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'D:\Program Files\Keil_v5\ARM\ARMCC\Bin'
Build target 'ble-sdk-xip_scan'
Note: source file '..\app\src\uart.c' - object file renamed from '.\Objects\uart.o' to '.\Objects\uart_1.o'.
compiling light_transition.c...
..\app\src\pwm.h(134): warning: #1295-D: Deprecated declaration _PWM_INIT - give arg types
..\app\src\pwm.h(137): warning: #1295-D: Deprecated declaration _PWM_INIT - give arg types
void _PWM_INIT();
..\app\src\pwm.h(140): warning: #1295-D: Deprecated declaration adc_Init - give arg types
..\app\src\pwm.h(143): warning: #1295-D: Deprecated declaration adc_Init - give arg types
void adc_Init();
..\app\src\pwm.h(141): warning: #1295-D: Deprecated declaration My_ADC_Get_Value - give arg types
..\app\src\pwm.h(144): warning: #1295-D: Deprecated declaration My_ADC_Get_Value - give arg types
void My_ADC_Get_Value();
..\app\src\pwm.h(142): warning: #1295-D: Deprecated declaration gpio_pullup_input_inter_test - give arg types
..\app\src\pwm.h(145): warning: #1295-D: Deprecated declaration gpio_pullup_input_inter_test - give arg types
void gpio_pullup_input_inter_test();
..\app\src\mode.h(39): warning: #1295-D: Deprecated declaration choice_mode - give arg types
..\app\src\mode.h(43): warning: #1295-D: Deprecated declaration choice_mode - give arg types
void choice_mode();
..\app\src\mode.h(40): warning: #1295-D: Deprecated declaration set_mode - give arg types
..\app\src\mode.h(44): warning: #1295-D: Deprecated declaration set_mode - give arg types
void set_mode();
..\app\src\mode.h(41): warning: #1295-D: Deprecated declaration Start_PWM - give arg types
..\app\src\mode.h(45): warning: #1295-D: Deprecated declaration Start_PWM - give arg types
void Start_PWM();
..\app\src\mode.h(42): warning: #1295-D: Deprecated declaration Stop_PWM - give arg types
..\app\src\mode.h(46): warning: #1295-D: Deprecated declaration Stop_PWM - give arg types
void Stop_PWM();
..\app\src\mode.h(43): warning: #1295-D: Deprecated declaration Set_timing - give arg types
..\app\src\mode.h(47): warning: #1295-D: Deprecated declaration Set_timing - give arg types
void Set_timing();
..\app\src\light_transition.c: 9 warnings, 0 errors
compiling bridge_pwm.c...
..\app\src\pwm.h(137): warning: #1295-D: Deprecated declaration _PWM_INIT - give arg types
void _PWM_INIT();
..\app\src\pwm.h(143): warning: #1295-D: Deprecated declaration adc_Init - give arg types
void adc_Init();
..\app\src\pwm.h(144): warning: #1295-D: Deprecated declaration My_ADC_Get_Value - give arg types
void My_ADC_Get_Value();
..\app\src\pwm.h(145): warning: #1295-D: Deprecated declaration gpio_pullup_input_inter_test - give arg types
void gpio_pullup_input_inter_test();
..\app\src\mode.h(43): warning: #1295-D: Deprecated declaration choice_mode - give arg types
void choice_mode();
..\app\src\mode.h(44): warning: #1295-D: Deprecated declaration set_mode - give arg types
void set_mode();
..\app\src\mode.h(45): warning: #1295-D: Deprecated declaration Start_PWM - give arg types
void Start_PWM();
..\app\src\mode.h(46): warning: #1295-D: Deprecated declaration Stop_PWM - give arg types
void Stop_PWM();
..\app\src\mode.h(47): warning: #1295-D: Deprecated declaration Set_timing - give arg types
void Set_timing();
..\app\src\bridge_pwm.c: 9 warnings, 0 errors
linking...
Program Size: Code=27716 RO-data=1380 RW-data=2740 ZI-data=3700
Program Size: Code=32608 RO-data=2208 RW-data=2832 ZI-data=3856
FromELF: creating hex file...
After Build - User command #1: fromelf --bin --output=app.bin .\Objects\Xinc_ble_sdk.axf
After Build - User command #2: .\output_tool\ge_ota_scan.bat
Size of file: 29380 bytes.
all_size=29380
Size of file: 35088 bytes.
all_size=35088
dual_xip
Addr:13000
Size:0x72c4
Size:0x8910
BAddr:0x40000
Acheck:0x42b99760
Acheck:0xe2c54120
SoftVer:0x10
RomVer:0x20
LoadAddr:0x11013000
@@ -87,7 +107,7 @@ status2=1
updata file success !
已复制 1 个文件。
已复制 1 个文件。
".\Objects\Xinc_ble_sdk.axf" - 0 Error(s), 9 Warning(s).
".\Objects\Xinc_ble_sdk.axf" - 0 Error(s), 18 Warning(s).
<h2>Software Packages used:</h2>
@@ -100,7 +120,7 @@ Package Vendor: ARM
D:/Program Files/Keil_v5/ARM/Packs/ARM/CMSIS/5.9.0/Device/ARM/ARMCM0/Include
<h2>Collection of Component Files used:</h2>
Build Time Elapsed: 00:00:07
Build Time Elapsed: 00:00:09
</pre>
</body>
</html>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -42,9 +42,11 @@
".\objects\rgblight.o"
".\objects\mode.o"
".\objects\rf433.o"
".\objects\rf433_decoder.o"
".\objects\pwm.o"
".\objects\bridge_pwm.o"
".\objects\light_transition.o"
".\objects\external_key.o"
".\objects\fmc_spi.o"
--strict --scatter ".\Linker\cpu_xip_scan.scat"
--feedback fb.txt --summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols
Binary file not shown.
@@ -132,6 +132,8 @@
.\objects\arch_main.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\math.h
.\objects\arch_main.o: ..\app\src\mode.h
.\objects\arch_main.o: ..\app\src\RF433.h
.\objects\arch_main.o: ..\app\src\rf433_decoder.h
.\objects\arch_main.o: ..\app\src\external_key.h
.\objects\arch_main.o: ..\app\src\rgblight.h
.\objects\arch_main.o: ..\app\src\timer.h
.\objects\arch_main.o: ..\app\src\fmc_spi.h
File diff suppressed because one or more lines are too long
@@ -0,0 +1,63 @@
.\objects\external_key.o: ..\app\src\external_key.c
.\objects\external_key.o: ..\app\src\external_key.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_gpio.h
.\objects\external_key.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\stdbool.h
.\objects\external_key.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\stdio.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc6xxx.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc60xx.h
.\objects\external_key.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\stdint.h
.\objects\external_key.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\string.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\core_cm0.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\core_cmInstr.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\core_cmFunc.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_conf.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_cpr.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_offset.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_cprao.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_rf.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_adc.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_aotimer.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc6xxx.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_dma.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_fmc.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_fmc_cache.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_gpio.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_i2c.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_qdec.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_pwm.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_pwm_comn.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_rtc.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\core_cm0.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_spi.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_timer.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_uart.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_wdt.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\CMSIS\Device\xc_m0_register\xc_reg_pwm_timer.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_calib.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_clock.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_systick.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_pwr.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_gpio.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_aotimer.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_timer.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_rtc.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_uart.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\ringbuffer.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_dma.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_spi.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_spi_dma.h
.\objects\external_key.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\stdlib.h
.\objects\external_key.o: ..\..\..\..\..\component\ble\modules\flash\xc6xxx_fmc_spi.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_fmc_spi_dma.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_uart_dma.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_i2c.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_sw_i2c.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_wdt.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_adc.h
.\objects\external_key.o: ..\..\..\..\..\component\xc6xx_drivers\Drivers\xc_driver\xc_drv_pwm.h
.\objects\external_key.o: ..\app\src\Mode.h
.\objects\external_key.o: ..\app\src\PWM.h
.\objects\external_key.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\math.h
.\objects\external_key.o: ..\app\src\RF433.h
.\objects\external_key.o: ..\app\src\timer.h
.\objects\external_key.o: ..\app\src\timeslice.h
@@ -60,3 +60,4 @@
.\objects\fmc_spi.o: ..\app\src\PWM.h
.\objects\fmc_spi.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\math.h
.\objects\fmc_spi.o: ..\app\src\RF433.h
.\objects\fmc_spi.o: ..\app\src\timeslice.h
@@ -97,3 +97,5 @@
.\objects\ota_flash_interface.o: ..\..\..\..\..\component\ble\modules\dbg\api\dbg_trc.h
.\objects\ota_flash_interface.o: ..\app\src\ota_protocol.h
.\objects\ota_flash_interface.o: ..\app\src\fmc_spi.h
.\objects\ota_flash_interface.o: ..\app\src\PWM.h
.\objects\ota_flash_interface.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\math.h
Binary file not shown.
@@ -58,5 +58,8 @@
.\objects\rf433.o: ..\app\src\uart.h
.\objects\rf433.o: ..\app\src\mode.h
.\objects\rf433.o: ..\app\src\timer.h
.\objects\rf433.o: ..\app\src\light_transition.h
.\objects\rf433.o: ..\app\src\pwm.h
.\objects\rf433.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\math.h
.\objects\rf433.o: ..\app\src\rf433_decoder.h
.\objects\rf433.o: ..\app\src\timeslice.h
@@ -0,0 +1,5 @@
.\objects\rf433_decoder.o: ..\app\src\rf433_decoder.c
.\objects\rf433_decoder.o: ..\app\src\rf433_decoder.h
.\objects\rf433_decoder.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\stdbool.h
.\objects\rf433_decoder.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\stdint.h
.\objects\rf433_decoder.o: ..\app\src\rf433_decoder_port.h
@@ -60,6 +60,7 @@
.\objects\timeslice.o: ..\app\src\timer.h
.\objects\timeslice.o: ..\app\src\mode.h
.\objects\timeslice.o: ..\app\src\RF433.h
.\objects\timeslice.o: ..\app\src\rf433_decoder.h
.\objects\timeslice.o: ..\app\src\ota_flash_interface.h
.\objects\timeslice.o: ..\app\src\ota_protocol.h
.\objects\timeslice.o: ..\..\..\..\..\component\ble\plf\refip\src\arch\arch.h
@@ -137,3 +138,4 @@
.\objects\timeslice.o: ..\..\..\..\..\component\ble\ip\ble\hl\src\gatt\gatt_db.h
.\objects\timeslice.o: ..\..\..\..\..\component\ble\ip\ble\api\xc_gap_api.h
.\objects\timeslice.o: ..\..\..\..\..\component\ble\ip\ble\hl\api\gapc_msg.h
.\objects\timeslice.o: ..\app\src\external_key.h
@@ -63,3 +63,4 @@
.\objects\uart_1.o: ..\app\src\rgblight.h
.\objects\uart_1.o: ..\app\src\mode.h
.\objects\uart_1.o: ..\app\src\timeslice.h
.\objects\uart_1.o: ..\app\src\fmc_spi.h
@@ -128,3 +128,4 @@
.\objects\usr_server.o: ..\app\src\Mode.h
.\objects\usr_server.o: ..\app\src\PWM.h
.\objects\usr_server.o: D:\Program Files\Keil_v5\ARM\ARMCC\Bin\..\include\math.h
.\objects\usr_server.o: ..\app\src\fmc_spi.h
Binary file not shown.
@@ -1,4 +1,4 @@
;#<FEEDBACK># ARM Linker, 5060750: Last Updated: Sun Jul 26 23:18:52 2026
;#<FEEDBACK># ARM Linker, 5060750: Last Updated: Wed Jul 29 17:29:15 2026
;VERSION 0.2
;FILE aes.o
__asm___5_aes_c____REV16 <= USED 0
@@ -29,6 +29,9 @@ printf_null <= USED 0
;FILE bridge_pwm.o
__asm___12_bridge_pwm_c_5817fd17____REV16 <= USED 0
__asm___12_bridge_pwm_c_5817fd17____REVSH <= USED 0
;FILE external_key.o
__asm___14_external_key_c_af7f8d4e____REV16 <= USED 0
__asm___14_external_key_c_af7f8d4e____REVSH <= USED 0
;FILE fmc_spi.o
__asm___9_fmc_spi_c_ef98d224____REV16 <= USED 0
__asm___9_fmc_spi_c_ef98d224____REVSH <= USED 0
@@ -67,9 +70,13 @@ __asm___5_PWM_c_6441ccf7____REVSH <= USED 0
app_pwm_init <= USED 0
switch_pwm_pins <= USED 0
;FILE rf433.o
Delay_50us <= USED 0
Delay_ms <= USED 0
Lock_Pwm7xd <= USED 0
__asm___7_Rf433_c_rf_flag____REV16 <= USED 0
__asm___7_Rf433_c_rf_flag____REVSH <= USED 0
;FILE rf433_decoder.o
rf433_decoder_get_lost_count <= USED 0
;FILE rf_extrc.o
__asm___10_rf_extrc_c_e18db947____REV16 <= USED 0
__asm___10_rf_extrc_c_e18db947____REVSH <= USED 0