CH585的SPI驱动WS2812
链接: https://pan.baidu.com/s/1Su5dgmVWLre5kH2fYiGwQQ?pwd=wch6
CH573系列/583系列/592系列MCU,在使用SPI模拟WS2812波形时,MISO-PA15引脚上的实时电平,会影响MOSI-PA14引脚上的空闲电平状态,故建议SPI驱动WS2812的场景下,固定PA15的电平,不要接其他外设。
异常场景:当PA15引脚上为高电平时,PA14一组波形输出完,空闲态也变为高电平,会影响WS2812识别下一组波形的起始值。
CH585系列,实测SPI0已改良,PA14在输出一组DMA波形后,空闲电平始终为低电平,驱动不受PA15实时电平的影响,释放出PA15可以接其他外设。使能SPI后,PA14的GPIOset/reset接口失效,空闲电平固定为低电平;失能SPI后可以正常输出拉高/拉低PA14。
驱动WS2812主要函数:
/* * 将GRB灰度转换为通过SPI的DMA发出的比特流。每个WS2812灯珠需要12个字节来驱动。 * uint8_t *grb_pdest: SPI缓存数组 * uint8_t *grb_psrc: GRB灰度 * uint16_t len: 灯珠数量 * */ void grb_scale_2_spi_buff(uint8_t *pdest_grb, uint8_t *psrc_grb, uint16_t len) { memset(pdest_grb, 0, len*3*4); //数组清零 // G/R/B驱动中的一个编码位用4个SPI位表示。每种色彩8个编码位,需要4字节。驱动G/R/B共24个位,故需要SPI波形中的96个位即12个字节来表示。 for(uint16_t i=0; i<len; i++) { for(uint8_t j=0; j<3; j++) //G/R/B三种色彩轮流配置 { for(uint8_t k=0; k<4; k++) //每种色彩8位灰度,用4个字节表示 { for(uint8_t m=0; m<2; m++) //每个字节包含两个ws2812编码位 { if( psrc_grb[3*i + j] & (0x80 >> (2*k + m)) ) { pdest_grb[3*4*i + 4*j +k] |= (GRB_CODE_1 >> (m*4)); //PRINT("1 "); } else { pdest_grb[3*4*i + 4*j +k] |= (GRB_CODE_0 >> (m*4)); //PRINT("0 "); } } //PRINT("%x ", spi_grb_buff[3*4*i + 4*j +k]); } } //PRINT("\n"); } //PRINT("\n"); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具