STM32 cubemx驱动ws2812b灯条
参考链接
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灯条相关推荐
- ESP32 驱动WS2812B 灯条
//WS2812 灯条 #include <Arduino.h> #include <Adafruit_NeoPixel.h>//关键是这个库 #define WS_PIN ...
- 安信可ESP-12K模组学习心得 ③ 安信可 ESP-12K 驱动 WS2812B 灯板,实现五彩斑斓的灯光效果;
一 前言 今天为大家带来的是 安信可 ESP-12K 驱动WS2812B 灯板: 二 材料 安信可 ESP-12K 开发板 x1 WS2812B 灯板一个, 杜邦线若干 接线图: ESP-12K WS ...
- JL690X(2)驱动RGB灯带
AC690X驱动WS2812(SM16703P)点亮RGB灯带 在使用AC690X系列蓝牙时,需要设计驱动几十个RGB灯带的程序,经一段时间学习后成功驱动,现在把实现过程分享给大家共同学习. 1.芯片 ...
- STM32 HAL库 PWM+DMA 驱动WS2812B彩灯(STM32F030F4P6)
谁不想拥有炫酷的小彩灯呢?WS2812B可以给你机会...... 博主使用STM32驱动WS2812B主要参考了这位佬的文章,因为需求问题,采用了Cortex-M0的stm32f030f4p6(16k ...
- STM32使用PWM+DMA方式驱动WS2812灯珠
一. 关于WS2812 WS2812 内部集成了处理芯片和3颗不同颜色的led灯(红,绿,蓝),通过单总线协议分别控制三个灯的亮度强弱,达到全彩的效果. WS2812B Datasheet 二. WS ...
- 秒上手!使用Arduino控制基于WS2812B的LED灯条
使用Arduino控制基于WS2812B的LED灯条 一.材料准备 硬件部分 1. Arduino UNO R3 开发板 2. 基于WS2812B的LED灯条 3. 杜邦线若干 软件部分 1. Ard ...
- FPGA驱动RGB灯带WS2812B
记录一下短学期做的东西 -- FPGA驱动RGB灯带WS2812B 设计目标 1.有多种模式,按键调节模式等参数: 2.模式1:红绿蓝白四色循环显示,速度.亮度可调: 3.模式2:7彩虹+白色,闪烁, ...
- STM32+ws2812灯条,点灯升级版
ws2812系列灯条,是一种可寻址的RGB LED彩灯,可以自定义颜色.点灯速度等.只需要一个IO就可以控制多个灯.ws2812系列有三根线,分别为VCC.GND.信号控制线.作为优化升级版的ws2 ...
- STM32 CubeMx(二)定时器中断和PWM呼吸灯
STM32 CubeMx(一)时钟树配置与GPIO输入输出 文章目录 1.定时器 1.1 定时器概念 1.2 定时器分类 1.3 定时器功能 1.4 配置过程和编写代码 1.5 代码分享 2.PWM产 ...
- [SPI+DMA] 驱动WS2812B显示时钟
[SPI+DMA] 驱动WS2812B显示时钟 实现原理 本人一个大学萌新,偶然间发现RGB时钟这神奇的玩意,就想试试.目前初步实现时钟显示,第一次写博客,只是为了记录自己的学习成果方便以后查看,大家 ...
最新文章
- 字典树andXOR*
- MD04读取的一些计算表
- 启明云端分享 | sigmastar SSD201开发板网口直连PC升级
- 脚本(js)控制页面输入
- 如何配置CentOS或者RedHat5.X、6.X、7.X的网络yum源
- 105款移动应用程序就此被清理下架!
- JZYZOJ1140 飞船控制站
- job用法 Java_Web App使用Quartz实现java schedule job
- 如何才能降低真机测试成本和建议所使用平台
- 内容范围:正态分布,泊松分布,多项分布,二项分布,伯努利分布
- SitePoint Podcast#165:您说的是缓存,我说的是Caché
- 什么是IP防护等级,又该如何区分
- 100kW以上 中高频感应加热电源 双DSP数字式IGBT控制板
- 通过BIOS设置启用CPU虚拟化解决VMware虚拟机不支持X86_64位linux操作系统安装问题
- matlab图像嵌入提取压缩水印,matlab中如何对数字图像进行嵌入和提取水印
- 依赖背包dp NOIP2006 vijos 1313 金明的预算方案
- 墙面有几种装修方法_墙面怎么装?四种装修方式总有一款适合你
- 一套近乎完美的公司财务流程
- linux删除文件夹(里面有文件)
- int const *和int * const以及const int * const的区别
热门文章
- 【RDMA】文档和教程和相关知识
- 计算机组成原理bzc指令,计算机组成原理课程设计-09级.ppt
- windows server 2008 安装及VS2008和VS 2008 SP1安装
- 通达信自动交易软件步骤分析
- html前端毕业设计项目,web前端毕业设计论文..doc
- 小米网页连接调用服务器,小米6浏览器远程代码执行(CVE-2019-13322)
- android逆向 网易,Android逆向——网易云音乐排行榜api(上)
- java怎么格式化日期_java 时间格式化各种方法
- java将汉字字符串转换为拼音(包含多音字)
- JVM 内存分析工具MAT