参考链接

ws2812 程序设计与应用(1)DMA 控制 PWM 占空比原理及实现(STM32)

ws2812b原理

  • WS2812 内部集成了处理芯片和3颗不同颜色的led灯(红,绿,蓝),通过单总线协议分别控制三个灯的亮度强弱,达到全彩的效果,每一个灯需要 8 bits(1 byte) 的数据,所以一颗 ws2812 共需要24 bits(3 bytes) 的数据。
  • ws2812 采用 PWM方式来编码,即每个PWM的周期固定为1.25us(800k),占空比为 1/3 时为 0 码,占空比为 2/3 为 1 码。另外,ws2812 复位信号为一个 不低于50us的低电平:
  • 时序

ws2812传输原理

ws2812 的特点是可以多个灯珠串联起来,这样就可以通过一个总线控制多个灯珠:

ws2812 可以将第一个24字节的时序留下,余下的往下一位传递:

可以结合波逻辑分析仪捕获的波形来理解:

上图是4个led的驱动时序,首先是一个100us的低电平复位来ws2812,接着是第一个led灯的数据,它有24个周期,分为3个部分,每一个部分是8个周期分别对应不同颜色的灯,可以看到,第一个部分都是宽占空比,所以全是1,第二个部分都是窄占空比,所以全是0,第三个部分和第一个部分同。所以第一颗led灯,是绿色和蓝色一起亮,视觉效果为青色,其它同理。

时序的数据结构是,高位到低位:

基本信息

芯片型号 系统时钟 定时器 高速总线 引脚
STM32F427IIH 180Mhz TIM8_CH2 APB2 PI6

CubeMx配置

时钟

TIM8_CH2


周期计算:
ws2812b需要800kb的周期,系统时钟是180Mhz,TIM8是挂在APB2总线上的,它的时钟也是180Mhz,
因此,有:180 * 1000 / 800 = 225 (224+1),因此自动装载值设为 224 ;

cubemx的配置到此结束。

代码部分

tim.c里添加

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{HAL_TIM_PWM_Stop_DMA(&htim8,TIM_CHANNEL_2);
}

ws2812.c里添加
参数说明:

ONE_PULSE ZERO_PULSE WS2812_DATA_LEN
149 74 334
149 =(224+1)* 2/3 74 = (224+1)* 2/3 80 + led_nums * 24
#include "ws2812b.h"
#include "tim.h"#define ONE_PULSE        (149)                           //1 码
#define ZERO_PULSE       (74)                           //0 码
#define RESET_PULSE      (80)                           //80 ,复位信号
#define LED_NUMS         (11)                            //led 数量
#define LED_DATA_LEN     (24)                           //led 长度,单个需要24bits
#define WS2812_DATA_LEN  (LED_NUMS*LED_DATA_LEN)        //ws2812灯条需要的数组长度uint16_t static RGB_buffur[RESET_PULSE + WS2812_DATA_LEN] = { 0 };void ws2812_set_RGB(uint8_t R, uint8_t G, uint8_t B, uint16_t num)
{//uint16_t* p = (RGB_buffur + RESET_PULSE) + (num * LED_DATA_LEN);for (uint16_t i = 0;i < 8;i++){//p[i]      = (G << i) & (0x80)?ONE_PULSE:ZERO_PULSE;p[i + 8]  = (R << i) & (0x80)?ONE_PULSE:ZERO_PULSE;p[i + 16] = (B << i) & (0x80)?ONE_PULSE:ZERO_PULSE;}
}
/*ws2812 初始化*/
void ws2812_init(uint8_t led_nums)
{uint16_t num_data;num_data = 80 + led_nums * 24;for(uint8_t i = 0; i < led_nums; i++){ws2812_set_RGB(0x00, 0x00, 0x00, i);}HAL_TIM_PWM_Start_DMA(&htim8,TIM_CHANNEL_2,(uint32_t *)RGB_buffur,(num_data));
}
/*全亮蓝灯*/
void ws2812_blue(uint8_t led_nums)
{uint16_t num_data;num_data = 80 + led_nums * 24;for(uint8_t i = 0; i < led_nums; i++){ws2812_set_RGB(0x00, 0x00, 0x22, i);}HAL_TIM_PWM_Start_DMA(&htim8,TIM_CHANNEL_2,(uint32_t *)RGB_buffur,(num_data));
}
/*全亮红灯*/
void ws2812_red(uint8_t led_nums)
{uint16_t num_data;num_data = 80 + led_nums * 24;for(uint8_t i = 0; i < led_nums; i++){ws2812_set_RGB(0x22, 0x00, 0x00, i);}HAL_TIM_PWM_Start_DMA(&htim8,TIM_CHANNEL_2,(uint32_t *)RGB_buffur,(num_data));
}
/*全亮绿灯*/
void ws2812_green(uint8_t led_nums)
{uint16_t num_data;num_data = 80 + led_nums * 24;for(uint8_t i = 0; i < led_nums; i++){ws2812_set_RGB(0x00, 0x22, 0x00, i);}HAL_TIM_PWM_Start_DMA(&htim8,TIM_CHANNEL_2,(uint32_t *)RGB_buffur,(num_data));
}void ws2812_example(void)
{       ws2812_set_RGB(0x00, 0x00, 0x22, 0);ws2812_set_RGB(0x00, 0x00, 0x22, 1);ws2812_set_RGB(0x00, 0x00, 0x22, 2);ws2812_set_RGB(0x00, 0x00, 0x22, 3);ws2812_set_RGB(0x00, 0x00, 0x22, 6);ws2812_set_RGB(0x00, 0x00, 0x22, 7);ws2812_set_RGB(0x00, 0x00, 0x22, 8);ws2812_set_RGB(0x00, 0x00, 0x22, 10);HAL_TIM_PWM_Start_DMA(&htim8,TIM_CHANNEL_2,(uint32_t *)RGB_buffur,(344)); //344 = 80 + 24 * LED_NUMS(11)HAL_Delay(500);
}

ws2812b.h 里加入

#ifndef  WS2812B_H
#define WS2812B_H
#include "type.h"
#include "stdint.h"void ws2812_set_RGB(uint8_t R, uint8_t G, uint8_t B, uint16_t num);void ws2812_example(void);
extern void ws2812_blue(uint8_t led_nums);
extern void ws2812_red(uint8_t led_nums);
extern void ws2812_green(uint8_t led_nums);#endif

main.c里加入

 ...ws2812_init(11);while (1){ws2812_blue(8);HAL_Delay(500);ws2812_red(8);HAL_Delay(500);ws2812_green(8);HAL_Delay(500);}...

演示效果:


更新

type.h

#ifndef _TYPE_H
#define _TYPE_H#include "stm32f4xx_hal.h"
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdbool.h>typedef uint8_t   u8;
typedef uint16_t    u16;
typedef uint32_t    u32;typedef int8_t      s8;
typedef int16_t     s16;
typedef int32_t     s32;typedef volatile uint8_t    vu8;
typedef volatile uint16_t   vu16;
typedef volatile uint32_t   vu32;typedef volatile int8_t    vs8;
typedef volatile int16_t    vs16;
typedef volatile int32_t    vs32;typedef union{s8       s8_fmt[8];  //for angle and omegau8         u8_fmt[8];  //for angle and omegachar   ch_fmt[8];  //s16       s16_fmt[4];u16      u16_fmt[4];s32  s32_fmt[2];u32  u32_fmt[2];float    f32_fmt[2];double   d64_fmt;
}data_convert_ut;   //for diaobi gyro#endif

STM32 cubemx驱动ws2812b灯条相关推荐

  1. ESP32 驱动WS2812B 灯条

    //WS2812 灯条 #include <Arduino.h> #include <Adafruit_NeoPixel.h>//关键是这个库 #define WS_PIN   ...

  2. 安信可ESP-12K模组学习心得 ③ 安信可 ESP-12K 驱动 WS2812B 灯板,实现五彩斑斓的灯光效果;

    一 前言 今天为大家带来的是 安信可 ESP-12K 驱动WS2812B 灯板: 二 材料 安信可 ESP-12K 开发板 x1 WS2812B 灯板一个, 杜邦线若干 接线图: ESP-12K WS ...

  3. JL690X(2)驱动RGB灯带

    AC690X驱动WS2812(SM16703P)点亮RGB灯带 在使用AC690X系列蓝牙时,需要设计驱动几十个RGB灯带的程序,经一段时间学习后成功驱动,现在把实现过程分享给大家共同学习. 1.芯片 ...

  4. STM32 HAL库 PWM+DMA 驱动WS2812B彩灯(STM32F030F4P6)

    谁不想拥有炫酷的小彩灯呢?WS2812B可以给你机会...... 博主使用STM32驱动WS2812B主要参考了这位佬的文章,因为需求问题,采用了Cortex-M0的stm32f030f4p6(16k ...

  5. STM32使用PWM+DMA方式驱动WS2812灯珠

    一. 关于WS2812 WS2812 内部集成了处理芯片和3颗不同颜色的led灯(红,绿,蓝),通过单总线协议分别控制三个灯的亮度强弱,达到全彩的效果. WS2812B Datasheet 二. WS ...

  6. 秒上手!使用Arduino控制基于WS2812B的LED灯条

    使用Arduino控制基于WS2812B的LED灯条 一.材料准备 硬件部分 1. Arduino UNO R3 开发板 2. 基于WS2812B的LED灯条 3. 杜邦线若干 软件部分 1. Ard ...

  7. FPGA驱动RGB灯带WS2812B

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

  8. STM32+ws2812灯条,点灯升级版

    ws2812系列灯条,是一种可寻址的RGB  LED彩灯,可以自定义颜色.点灯速度等.只需要一个IO就可以控制多个灯.ws2812系列有三根线,分别为VCC.GND.信号控制线.作为优化升级版的ws2 ...

  9. STM32 CubeMx(二)定时器中断和PWM呼吸灯

    STM32 CubeMx(一)时钟树配置与GPIO输入输出 文章目录 1.定时器 1.1 定时器概念 1.2 定时器分类 1.3 定时器功能 1.4 配置过程和编写代码 1.5 代码分享 2.PWM产 ...

  10. [SPI+DMA] 驱动WS2812B显示时钟

    [SPI+DMA] 驱动WS2812B显示时钟 实现原理 本人一个大学萌新,偶然间发现RGB时钟这神奇的玩意,就想试试.目前初步实现时钟显示,第一次写博客,只是为了记录自己的学习成果方便以后查看,大家 ...

最新文章

  1. 字典树andXOR*
  2. MD04读取的一些计算表
  3. 启明云端分享 | sigmastar SSD201开发板网口直连PC升级
  4. 脚本(js)控制页面输入
  5. 如何配置CentOS或者RedHat5.X、6.X、7.X的网络yum源
  6. 105款移动应用程序就此被清理下架!
  7. JZYZOJ1140 飞船控制站
  8. job用法 Java_Web App使用Quartz实现java schedule job
  9. 如何才能降低真机测试成本和建议所使用平台
  10. 内容范围:正态分布,泊松分布,多项分布,二项分布,伯努利分布
  11. SitePoint Podcast#165:您说的是缓存,我说的是Caché
  12. 什么是IP防护等级,又该如何区分
  13. 100kW以上 中高频感应加热电源 双DSP数字式IGBT控制板
  14. 通过BIOS设置启用CPU虚拟化解决VMware虚拟机不支持X86_64位linux操作系统安装问题
  15. matlab图像嵌入提取压缩水印,matlab中如何对数字图像进行嵌入和提取水印
  16. 依赖背包dp NOIP2006 vijos 1313 金明的预算方案
  17. 墙面有几种装修方法_墙面怎么装?四种装修方式总有一款适合你
  18. 一套近乎完美的公司财务流程
  19. linux删除文件夹(里面有文件)
  20. int const *和int * const以及const int * const的区别

热门文章

  1. 【RDMA】文档和教程和相关知识
  2. 计算机组成原理bzc指令,计算机组成原理课程设计-09级.ppt
  3. windows server 2008 安装及VS2008和VS 2008 SP1安装
  4. 通达信自动交易软件步骤分析
  5. html前端毕业设计项目,web前端毕业设计论文..doc
  6. 小米网页连接调用服务器,小米6浏览器远程代码执行(CVE-2019-13322)
  7. android逆向 网易,Android逆向——网易云音乐排行榜api(上)
  8. java怎么格式化日期_java 时间格式化各种方法
  9. java将汉字字符串转换为拼音(包含多音字)
  10. JVM 内存分析工具MAT