前言

现在带IC的彩灯虽然有 SK6812WS2812 等不同信号,但是其控制逻辑基本是完全兼容的,本文所描述相关控制参数来源于 SK6812 ,原于带 IC 芯片的 RGB 可以通过串联来实现数据的传输,使得其在PCB布线时变得更为简单。

SK6812 时序


驱动方案

在此不难看出 RGB 灯的时序并不复杂,在此主要有以下几种驱动方式可供参考。

  • 直接用 GPIO 反转,利用延时模拟时序

    • 相对比较简单。
    • 由于有延时函数存在及其浪费MCU运行资源。
  • 利用 DMA + SPI 模拟时序
    • 配置好之后驱动基本交给硬件处理了,由DMA进行数据搬运。
    • MCU 只需要进行颜色相关的逻辑处理,可以最大程度节省 MCU 运行资源。
  • 利用 DMA + TIM 方式模拟时序
    • 配置相对比较复杂,配置好之后驱动基本交给硬件处理,由 DMA 进行数据搬运。
    • MCU 只需要进行颜色相关的逻辑处理,可以最大程度节省 MCU 运行资源。
  • 方案对比
    • 显然第一种方案是不可取的,于是需要在第二和第三种方案进行一个取舍,这个就主要看各位的 MCU 硬件接口资源了,一般而言 SPI 接口更少( SPI 可以接很多的模块以及驱动屏幕等等),定时器 TIM 更多,同时一个定时器 TIM 最多可以控制四条灯带,因此个人感觉使用DMA+TIM 方案会更加节省硬件资源。

STM32 CubeMx 配置 DMA + PWM

LLQ-82 这一款机械键盘中有80颗 RGB 灯,在此将灯分为了三组以节省总的刷新时间

  • 如果按80颗灯进行串联控制,刷新周期至少大于 1.2us*80*24+80us = 2.384ms
  • 如果把80颗灯分成三组,其中最多的一组分28个(为方便键盘布局和控制)则刷新周期至少应大于
    1.2us*80*24+80us = 0.906ms
  • 如此可以提高 RGB 灯的刷新频率。

开始具体配置

在考虑余量的情况下进行配置

  1. 考虑稳定性我们将单个 bit 数据的时间控制为 1.25us 而不是最小的 1.2us ,以提升硬件上升和下降沿一定容错空间,如果硬件布局较差,走线较长可以适当加长。
  2. 时钟频率为 84Mhz ,在此预分频设置为0即不分频,重装载值设置为105。
  3. T0H 不妨设置比较值 27 则0码高电平持续时间为 1.25us*(27/105)=0.3214us
  4. T1H 不妨设置比较值 60 则1码高电平持续时间为 1.25us*(60/105) = 0.7142us
  5. 如下定时器配置。
  6. 如下PWM配置。
  7. 把能关的中断关了,不需要定时器中断。
  8. 生成程序。
  9. 在初始化最后关闭不必要的DMA中断,避免资源 MCU 运行资源浪费。
// 关闭DMA半传输中断
__HAL_DMA_DISABLE_IT(&hdma_spi1_tx, DMA_IT_HT);
__HAL_DMA_DISABLE_IT(&hdma_tim4_ch1, DMA_IT_HT);
__HAL_DMA_DISABLE_IT(&hdma_tim4_ch2, DMA_IT_HT);
__HAL_DMA_DISABLE_IT(&hdma_tim4_ch3, DMA_IT_HT);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
__HAL_DMA_DISABLE_IT(&hdma_usart1_tx, DMA_IT_HT);
__HAL_DMA_DISABLE_IT(&hdma_usart3_rx, DMA_IT_HT);
__HAL_DMA_DISABLE_IT(&hdma_usart3_tx, DMA_IT_HT);
  1. 定义宏定义和变量。
#define BSP_WS2812_TERO 27
#define BSP_WS2812_ONE_ 68#define BSP_WS2812_MAX_NUM 28 //每组定时器通道下的RGB灯数量
#define BSP_WS2812_R_OFFSET 1 //红色偏移量
#define BSP_WS2812_G_OFFSET 2 //绿色偏移量
#define BSP_WS2812_B_OFFSET 0 //蓝色偏移量// TIM 中设置传输 bit 数据耗时 1.25us
#define BSP_WS2812_RGB_BITS_NUM     3*8
// 附加4个灯的时长,所有BIT设置为0码,进行复位逻辑 4*1.25*24 = 120us
#define BSP_WS2812_RGB_DATA_LEN     (BSP_WS2812_MAX_NUM+4)
#define BSP_WS2812_RGB_DMA_NUM      (BSP_WS2812_RGB_BITS_NUM*BSP_WS2812_RGB_DATA_LEN)
#define BSP_WS2812_KEYBOARD_NUM     80typedef union
{uint32_t color_u32;uint8_t color_u8[4];
} bsp_color_struct;// 颜色设置
bsp_color_struct keyboard_color[3][BSP_WS2812_MAX_NUM];
// pwm 占空比数值为uint16_t 类型,DMA传输时只能以半字输出,pixelBuffer应为uint16_t 类型
static uint16_t timCh1DmaBuffer[BSP_WS2812_RGB_DATA_LEN][3*8];
static uint16_t timCh2DmaBuffer[BSP_WS2812_RGB_DATA_LEN][3*8];
static uint16_t timCh3DmaBuffer[BSP_WS2812_RGB_DATA_LEN][3*8];
  1. 设置每个灯的颜色。
board_rgb[k].color.color_u8[BSP_WS2812_R_OFFSET] = (uint8_t)r;
board_rgb[k].color.color_u8[BSP_WS2812_G_OFFSET] = (uint8_t)g;
board_rgb[k].color.color_u8[BSP_WS2812_B_OFFSET] = (uint8_t)b;
  1. 数据转换成 DMA buffer 需要的格式,即可自动更新。
// 更新DMA缓冲区数据内容
for(n=0; n< BSP_WS2812_MAX_NUM; n++)
{for(i = 0; i < 3*8; ++i){timCh1DmaBuffer[n][i] = ((keyboard_color[0][i].color_u32<< i) & 0x800000) ? BSP_WS2812_ONE_ : BSP_WS2812_TERO;timCh2DmaBuffer[n][i] = ((keyboard_color[1][i].color_u32<< i) & 0x800000) ? BSP_WS2812_ONE_ : BSP_WS2812_TERO;timCh3DmaBuffer[n][i] = ((keyboard_color[2][i].color_u32<< i) & 0x800000) ? BSP_WS2812_ONE_ : BSP_WS2812_TERO;}
}
  1. 确认配置好之后,在合适的位置加入启动程序(相关初始化程序完成之后),由于 DMA 模式配置为了 Circular 模式(循环传输模式),故只需要调用一次启动 DMA 传输即可。
// 启动DMA传输
HAL_TIM_PWM_Start_DMA(&htim4, TIM_CHANNEL_1, (uint32_t *)timCh1DmaBuffer, BSP_WS2812_RGB_DMA_NUM);
HAL_TIM_PWM_Start_DMA(&htim4, TIM_CHANNEL_2, (uint32_t *)timCh2DmaBuffer, BSP_WS2812_RGB_DMA_NUM);
HAL_TIM_PWM_Start_DMA(&htim4, TIM_CHANNEL_3, (uint32_t *)timCh3DmaBuffer, BSP_WS2812_RGB_DMA_NUM);

DMA+PWM驱动彩色RGB灯

DMA+PWM驱动彩色RGB灯相关推荐

  1. 基于STM32的PWM驱动LED呼吸灯

    一,PWM基本原理 所谓PWM,就是脉冲宽度调制技术,其具有两个很重要的参数:频率和占空比.频率,就是周期的倒数:占空比,就是高电平在一个周期内所占的比例.如当周期T=T1+T2:T1为高电平时间,T ...

  2. [MM32生态]【MM32+模块】系列:03、RGB灯控制

    在上一篇中我们介绍了LED灯,它是一个单色的灯,比如红色.蓝色.黄色.或者绿色等等:而本篇中的RGB灯是一个彩色灯,一个RGB灯包含了红.绿.蓝这三元色,可以通过对红绿蓝亮度的比例调节来实现显示彩色的 ...

  3. 【基于 STM32CubeMX + PWM + DMA驱动SW2812b全彩RGB灯】

    基于 STM32CubeMX + PWM + DMA驱动SW2812b全彩RGB灯 STM32CubeMX配置: 工程源码: END 以上就是相关配置,最需要注意的就是时钟以及pre数值以及芯片时钟频 ...

  4. STM32F427库函数配置DMA驱动TIM5 PWM驱动WS2812B单总线全彩RGB

    STM32F427库函数配置DMA驱动TIM5 PWM驱动WS2812B单总线全彩RGB 系列文章传送门: STM32F4多路PWM DMA控制千颗WS2812/SK6812配置过程全解析 STM32 ...

  5. pwm一个时间单位_RK3308——RGB调色灯三路PWM驱动

    10.1 硬件基础 在我们的开发板上集成了一颗RGB灯组,引脚连接着主控的三路PWM输出,因此我们可以通过三路PWM输出进行调色的功能,硬件原理图如下: 10.2 内核设备树 我们把设备树补丁文件放在 ...

  6. WS2812灯珠(三)-- STM32 PWM+DMA方式驱动

    WS2812灯珠(三)-- STM32 PWM+DMA方式驱动 文章目录 WS2812灯珠(三)-- STM32 PWM+DMA方式驱动 一.理论 二.代码实践 一.理论 PWM输出就是对外输出脉宽( ...

  7. 嵌入式linux系统RGB调色灯三路PWM驱动

    1 硬件基础 在我们的开发板上集成了一颗RGB灯组,引脚连接着主控的三路PWM输出,因此我们可以通过三路PWM输出进行调色的功能,硬件原理图如下: 2 内核设备树 我们把设备树补丁文件放在目录:~/s ...

  8. FPGA驱动RGB灯带WS2812B

    记录一下短学期做的东西 -- FPGA驱动RGB灯带WS2812B 设计目标 1.有多种模式,按键调节模式等参数: 2.模式1:红绿蓝白四色循环显示,速度.亮度可调: 3.模式2:7彩虹+白色,闪烁, ...

  9. 驱动RGB灯带MCU阐述

    驱动RGB灯带MCU推荐 本文仅分享个人工作中积累的经验,无任何商业行为,若有更好的方案欢迎交流共同进步. 一.RGB灯带驱动IC简介 市面上存在多种RGB驱动IC,比如:WS2812,YX1903B ...

最新文章

  1. Java如何优雅的实现时间控制
  2. 【12c新特性】安装12c Standalone Grid Infrastructure
  3. 全球顶级语音技术比赛中获双料冠军,这家中国公司靠什么?
  4. 【计算机网络】数据链路层 : CSMA/CD 协议 ( 载波监听多点接入 / 碰撞检测 协议 | 单程端到端传播时延 | 截断二进制指数规避算法 | 计算示例 | 最小帧长问题 )★
  5. sizeof运算求结构体大小
  6. 6700设置上网教程
  7. 请问为什么像cellspacing=0和bgcolor=red的属性在style里面不起作用呢?
  8. 进程间通信(6) 邮槽
  9. JS-Object 对象的相关方法
  10. Kotlin 系列(二) 基本语法(1)
  11. 【转】详细图解Vmware与主机间共享文件的方法
  12. Yii2框架之旅(六)
  13. linux忘记root密码怎么修改密码和多台linux相互使用密钥连接
  14. 无基础学python能干什么-为什么推荐你学Python?IT界大牛告诉你学会以后可以干什么...
  15. Ubuntu做Tomcat服务:insserv: warning: script 'tomcat' missing LSB tags and overrides
  16. MsChart控件在VC++中的使用(VS2013+MFC+对话框)
  17. 中国内地最高电影票房收入列表
  18. usb摄像头android录像软件,USB摄像头app
  19. 钱钟书论“反者道之动”
  20. 举个栗子!Tableau 技巧(183):快速实现部分类别的排序

热门文章

  1. win10 2016企业版激活,遇到非核心版本的计算机问题
  2. Spring Boot熟稔于心的20个常识
  3. PotPlayer 高逼格无边框的本地播放器
  4. 游戏思考13:关于MMORPG游戏服务器的种类及作用(以后会同步更新github,持续更新系列,目前有20个服务器说明,22/10/20)
  5. u盘有图标计算机显示没有,电脑没插u盘却显示u盘图标是怎么回事?
  6. 鸿蒙十大凶兽排名,上古十大神兽|上古十大洪荒神兽|上古十大神兽资料大全【图文】...
  7. 8个成语接龙首尾相连_八拜为交成语接龙
  8. python 期货现货差价监测_期货现货价差小工具——天勤量化(TqSdk)
  9. nvenc硬件编码相关设置
  10. 铁死亡(Ferroptosis )最新研究进展(2022年)