DMA+PWM驱动彩色RGB灯
前言
现在带IC的彩灯虽然有 SK6812 、WS2812 等不同信号,但是其控制逻辑基本是完全兼容的,本文所描述相关控制参数来源于 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 灯的刷新频率。
开始具体配置
在考虑余量的情况下进行配置
- 考虑稳定性我们将单个 bit 数据的时间控制为 1.25us 而不是最小的 1.2us ,以提升硬件上升和下降沿一定容错空间,如果硬件布局较差,走线较长可以适当加长。
- 时钟频率为 84Mhz ,在此预分频设置为0即不分频,重装载值设置为105。
- T0H 不妨设置比较值 27 则0码高电平持续时间为 1.25us*(27/105)=0.3214us 。
- T1H 不妨设置比较值 60 则1码高电平持续时间为 1.25us*(60/105) = 0.7142us 。
- 如下定时器配置。
- 如下PWM配置。
- 把能关的中断关了,不需要定时器中断。
- 生成程序。
- 在初始化最后关闭不必要的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);
- 定义宏定义和变量。
#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];
- 设置每个灯的颜色。
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;
- 数据转换成 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;}
}
- 确认配置好之后,在合适的位置加入启动程序(相关初始化程序完成之后),由于 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灯相关推荐
- 基于STM32的PWM驱动LED呼吸灯
一,PWM基本原理 所谓PWM,就是脉冲宽度调制技术,其具有两个很重要的参数:频率和占空比.频率,就是周期的倒数:占空比,就是高电平在一个周期内所占的比例.如当周期T=T1+T2:T1为高电平时间,T ...
- [MM32生态]【MM32+模块】系列:03、RGB灯控制
在上一篇中我们介绍了LED灯,它是一个单色的灯,比如红色.蓝色.黄色.或者绿色等等:而本篇中的RGB灯是一个彩色灯,一个RGB灯包含了红.绿.蓝这三元色,可以通过对红绿蓝亮度的比例调节来实现显示彩色的 ...
- 【基于 STM32CubeMX + PWM + DMA驱动SW2812b全彩RGB灯】
基于 STM32CubeMX + PWM + DMA驱动SW2812b全彩RGB灯 STM32CubeMX配置: 工程源码: END 以上就是相关配置,最需要注意的就是时钟以及pre数值以及芯片时钟频 ...
- STM32F427库函数配置DMA驱动TIM5 PWM驱动WS2812B单总线全彩RGB
STM32F427库函数配置DMA驱动TIM5 PWM驱动WS2812B单总线全彩RGB 系列文章传送门: STM32F4多路PWM DMA控制千颗WS2812/SK6812配置过程全解析 STM32 ...
- pwm一个时间单位_RK3308——RGB调色灯三路PWM驱动
10.1 硬件基础 在我们的开发板上集成了一颗RGB灯组,引脚连接着主控的三路PWM输出,因此我们可以通过三路PWM输出进行调色的功能,硬件原理图如下: 10.2 内核设备树 我们把设备树补丁文件放在 ...
- WS2812灯珠(三)-- STM32 PWM+DMA方式驱动
WS2812灯珠(三)-- STM32 PWM+DMA方式驱动 文章目录 WS2812灯珠(三)-- STM32 PWM+DMA方式驱动 一.理论 二.代码实践 一.理论 PWM输出就是对外输出脉宽( ...
- 嵌入式linux系统RGB调色灯三路PWM驱动
1 硬件基础 在我们的开发板上集成了一颗RGB灯组,引脚连接着主控的三路PWM输出,因此我们可以通过三路PWM输出进行调色的功能,硬件原理图如下: 2 内核设备树 我们把设备树补丁文件放在目录:~/s ...
- FPGA驱动RGB灯带WS2812B
记录一下短学期做的东西 -- FPGA驱动RGB灯带WS2812B 设计目标 1.有多种模式,按键调节模式等参数: 2.模式1:红绿蓝白四色循环显示,速度.亮度可调: 3.模式2:7彩虹+白色,闪烁, ...
- 驱动RGB灯带MCU阐述
驱动RGB灯带MCU推荐 本文仅分享个人工作中积累的经验,无任何商业行为,若有更好的方案欢迎交流共同进步. 一.RGB灯带驱动IC简介 市面上存在多种RGB驱动IC,比如:WS2812,YX1903B ...
最新文章
- Java如何优雅的实现时间控制
- 【12c新特性】安装12c Standalone Grid Infrastructure
- 全球顶级语音技术比赛中获双料冠军,这家中国公司靠什么?
- 【计算机网络】数据链路层 : CSMA/CD 协议 ( 载波监听多点接入 / 碰撞检测 协议 | 单程端到端传播时延 | 截断二进制指数规避算法 | 计算示例 | 最小帧长问题 )★
- sizeof运算求结构体大小
- 6700设置上网教程
- 请问为什么像cellspacing=0和bgcolor=red的属性在style里面不起作用呢?
- 进程间通信(6) 邮槽
- JS-Object 对象的相关方法
- Kotlin 系列(二) 基本语法(1)
- 【转】详细图解Vmware与主机间共享文件的方法
- Yii2框架之旅(六)
- linux忘记root密码怎么修改密码和多台linux相互使用密钥连接
- 无基础学python能干什么-为什么推荐你学Python?IT界大牛告诉你学会以后可以干什么...
- Ubuntu做Tomcat服务:insserv: warning: script 'tomcat' missing LSB tags and overrides
- MsChart控件在VC++中的使用(VS2013+MFC+对话框)
- 中国内地最高电影票房收入列表
- usb摄像头android录像软件,USB摄像头app
- 钱钟书论“反者道之动”
- 举个栗子!Tableau 技巧(183):快速实现部分类别的排序
热门文章
- win10 2016企业版激活,遇到非核心版本的计算机问题
- Spring Boot熟稔于心的20个常识
- PotPlayer 高逼格无边框的本地播放器
- 游戏思考13:关于MMORPG游戏服务器的种类及作用(以后会同步更新github,持续更新系列,目前有20个服务器说明,22/10/20)
- u盘有图标计算机显示没有,电脑没插u盘却显示u盘图标是怎么回事?
- 鸿蒙十大凶兽排名,上古十大神兽|上古十大洪荒神兽|上古十大神兽资料大全【图文】...
- 8个成语接龙首尾相连_八拜为交成语接龙
- python 期货现货差价监测_期货现货价差小工具——天勤量化(TqSdk)
- nvenc硬件编码相关设置
- 铁死亡(Ferroptosis )最新研究进展(2022年)