Skip to content

流程图

┌─────────────────────┐
│  ws2812_buf[][]      │  ← 用户设置的 LED 颜色缓存 (GRB)
│  每个 LED 3 个字节   │
└─────────┬───────────┘
          │ 遍历每个 LED、每个颜色字节

┌─────────────────────┐
│  拆字节成 bit       │
│  for bit = 7..0      │
└─────────┬───────────┘
          │ 转换成 PWM 高低电平占空比

┌─────────────────────┐
│  ws2812_dma_buf[]    │  ← DMA 缓冲区
│  每个 bit 对应一个   │
│  PWM 高低电平值      │
└─────────┬───────────┘
          │ 填充 Reset 信号 (0)

┌─────────────────────┐
│  DMA 控制器          │
│  DMA_SetCurrDataCounter(idx) │
│  DMA_Cmd(ENABLE)     │
└─────────┬───────────┘
          │ 通过定时器 TIM 输出 PWM

┌─────────────────────┐
│  WS2812 LED 灯带     │
│  每个 LED 接收 24 bit│
│  更新颜色显示        │
└─────────────────────┘

PWM配置

pwm的本质是CNT和CCR进行比较,当CNT<CCR时输出高电平,当CNT>CCR时输出低电平。从在一整个周期内,获得高电平和低电平的不同的占比。

定时器计数器 CNT 的计数

  • 假设你用的是 72MHz 的时钟,分频器 PSC=0
  • 那么 CNT 每 1/72 MHz = 13.9ns 增加 1。
  • ARR=89(周期寄存器),所以 CNT 会从 0 → 89,再回到 0,形成一个周期。
  • 这个过程需要 90 个时钟周期,所以整个 PWM 周期就是 90 / 72MHz ≈ 1.25µs,刚好是 WS2812 协议的一个 bit 时间。

比较过程

PWM 模式 1 的规则:

  • 如果 CNT < CCRn → 输出高电平(有效电平)。
  • 如果 CNT ≥ CCRn → 输出低电平(无效电平)。

举例:

  • ARR=89
  • CCR=60
    • 当 CNT 从 0 → 59 时,高电平。
    • 当 CNT 从 60 → 89 时,低电平。 → 占空比 = 60/90 ≈ 66%。
  • CCR=30
    • 当 CNT 从 0 → 29 时,高电平。
    • 当 CNT 从 30 → 89 时,低电平。 → 占空比 = 30/90 ≈ 33%。

DMA配置

DMA把ws2812_dma_buf的数据转运到TIM3 的 CCR3 寄存器,去生成PWM波形