[RISC-V MCU 应用开发] 使用多模SOC CH585的SPI驱动WS2812

[复制链接]
 楼主| 神奇小子996 发表于 2025-2-8 11:25 | 显示全部楼层 |阅读模式
众所周知,WS2812 是一种集成了控制电路和 RGB LED 的智能灯珠,可以通过单线传输数据控制多个灯珠的颜色和亮度。使用 MCU 的 SPI 接口驱动 WS2812,可以实现更高效、灵活的控制。
主要应用场景包括:
1. LED 灯带和灯条:家居装饰,商业照明,景观照明
2. LED 点阵屏:信息显示,广告宣传,创意展示
3. LED 灯具:智能灯泡,台灯、落地灯, 氛围灯
4. 玩具模型:为玩具模型添加炫酷的灯光效果

使用 SPI 驱动 WS2812 的优势:

更高的刷新率: SPI 接口的传输速率比单总线更高,可以实现更流畅的灯光效果。
更灵活的控制: SPI 接口可以更方便地与其他外设通信,实现更复杂的控制逻辑。
更低的 CPU 占用率:SPI 接口通常由硬件实现,可以减轻 CPU 的负担。

CH573系列/583系列/592系列MCU,在使用SPI模拟WS2812波形时,MISO-PA15引脚上的实时电平,会影响MOSI-PA14引脚上的空闲电平状态,故建议SPI驱动WS2812的场景下,固定PA15的电平,不要接其他外设
异常场景:当PA15引脚上为高电平时,PA14一组波形输出完,空闲态也变为高电平,会影响WS2812识别下一组波形的起始值
2415967a6cd9c79004.png

最近比较火的多模无线SOC CH585系列,实测SPI0已改良,PA14在输出一组DMA波形后,空闲电平始终为低电平,驱动不受PA15实时电平的影响,释放出PA15可以接其他外设。使能SPI后,PA14的GPIOset/reset接口失效,空闲电平固定为低电平;失能SPI后可以正常输出拉高/拉低PA14。
驱动WS2812主要函数:

  1. /*
  2. * 将GRB灰度转换为通过SPI的DMA发出的比特流。每个WS2812灯珠需要12个字节来驱动。
  3. * uint8_t *grb_pdest:  SPI缓存数组
  4. * uint8_t *grb_psrc:   GRB灰度
  5. * uint16_t len:        灯珠数量
  6. * */
  7. void grb_scale_2_spi_buff(uint8_t *pdest_grb, uint8_t *psrc_grb, uint16_t len)
  8. {
  9.     memset(pdest_grb, 0, len*3*4);     //数组清零
  10. //  G/R/B驱动中的一个编码位用4个SPI位表示。每种色彩8个编码位,需要4字节。驱动G/R/B共24个位,故需要SPI波形中的96个位即12个字节来表示。
  11.     for(uint16_t i=0; i<len; i++)
  12.     {
  13.         for(uint8_t j=0; j<3; j++)  //G/R/B三种色彩轮流配置
  14.         {
  15.             for(uint8_t k=0; k<4; k++)  //每种色彩8位灰度,用4个字节表示
  16.             {
  17.                 for(uint8_t m=0; m<2; m++)  //每个字节包含两个ws2812编码位
  18.                 {
  19.                     if( psrc_grb[3*i + j] & (0x80 >> (2*k + m)) )
  20.                     {
  21.                         pdest_grb[3*4*i + 4*j +k] |= (GRB_CODE_1 >> (m*4));
  22.                         //PRINT("1 ");
  23.                     }
  24.                     else
  25.                     {
  26.                         pdest_grb[3*4*i + 4*j +k] |= (GRB_CODE_0 >> (m*4));
  27.                         //PRINT("0 ");
  28.                     }
  29.                 }
  30.                 //PRINT("%x ", spi_grb_buff[3*4*i + 4*j +k]);
  31.             }
  32.         }
  33.         //PRINT("\n");
  34.     }
  35.     //PRINT("\n");
  36. }


yangbeioften 发表于 2025-4-18 08:44 | 显示全部楼层
有CH585 SPI 驱动w25q128的例程吗,我读取ID都失败,也就是说SPI接收引脚如何配置
SirenSong 发表于 2025-6-22 11:07 | 显示全部楼层
yangbeioften 发表于 2025-4-18 08:44
有CH585 SPI 驱动w25q128的例程吗,我读取ID都失败,也就是说SPI接收引脚如何配置 ...

是的 我也想看下例程,最好是有配置说明,硬件spi速度还是快的
yangbeioften 发表于 2025-8-14 17:04 | 显示全部楼层
SirenSong 发表于 2025-6-22 11:07
是的 我也想看下例程,最好是有配置说明,硬件spi速度还是快的

我的是虚焊了
暗夜幽灵骑士 发表于 2025-8-21 21:25 | 显示全部楼层
能不能把 DMA 设成循环模式,让 SPI 一直跑,省掉中断延迟?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

19

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

7

主题

19

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部