普冉PY32系列(十三) SPI驱动WS2812全彩LED

这篇具有很好参考价值的文章主要介绍了普冉PY32系列(十三) SPI驱动WS2812全彩LED。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

  • 普冉PY32系列(一) PY32F0系列32位Cortex M0+ MCU简介
  • 普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境
  • 普冉PY32系列(三) PY32F002A资源实测 - 这个型号不简单
  • 普冉PY32系列(四) PY32F002A/003/030的时钟设置
  • 普冉PY32系列(五) 使用JLink RTT代替串口输出日志
  • 普冉PY32系列(六) 通过I2C接口驱动PCF8574扩展的1602LCD
  • 普冉PY32系列(七) SOP8,SOP10,SOP16封装的PY32F002A/PY32F003管脚复用
  • 普冉PY32系列(八) GPIO模拟和硬件SPI方式驱动无线收发芯片XN297LBW
  • 普冉PY32系列(九) GPIO模拟和硬件SPI方式驱动无线收发芯片XL2400
  • 普冉PY32系列(十) 基于PY32F002A的6+1通道遥控小车I - 综述篇
  • 普冉PY32系列(十一) 基于PY32F002A的6+1通道遥控小车II - 控制篇
  • 普冉PY32系列(十二) 基于PY32F002A的6+1通道遥控小车III - 驱动篇
  • 普冉PY32系列(十三) SPI驱动WS2812全彩LED

WS2812/WS2812B

普冉PY32系列(十三) SPI驱动WS2812全彩LED

WS2812 是一种集成了控制器的全彩LED, 常见单体尺寸为50mm * 50mm, 4个PIN, 分别是 VCC, GND, DIN, DOUT, 工作电压3.7V-5.3V, 电流16mA. 市面上出售的大都是制作成带状, 环状或矩阵的成品. 供电电压有5V和12V两种, 前者因为电压低, 如果长度较长, 每隔两三百颗需要外接电源补电.

WS2812的特点就是全彩并且是单线串行接口, 只需要一个IO就可以对彩灯实现全部控制.

接口通信格式

WS2812/WS2812B LED 使用 24 bit 数据调节 RGB 色彩, 每个 bit 都是通过(一个高电平 + 一个低电平)表示的.

普冉PY32系列(十三) SPI驱动WS2812全彩LED

根据手册

  • 0 表示为一个短的(0.35 µs)高电平加一个长的(0.90 µs)低电平
  • 1 表示为一个长的(0.90 µs)高电平加一个短的(0.35 µs)低电平
  • 单个 bit 信号周期, 高低电平时长合计为 1.25 µs
  • 发送超过 24 bit 信号后, 之前输入的信号会依次传递给串行的下一个 WS2812 LED
  • 控制器发送数据前需要保持低电平超过 50 µs(又称为 RESET), 用于通知 WS2812 开始接收数据.

根据上面的信息, 对单颗LED发送数据, 需要的时间为
\(24 × 1.25 µs + 50 µs = 80 µs\)
对于8颗LED, 需要的时间为
\(8 × 24 × 1.25 µs + 50 µs = 290 µs\)

实际的通信时间间隔要求

当传输信号时, 高低电平时间间隔如果不符合手册要求, 差距较大时LED会不工作(不亮), 在间隔接近但是不完全满足时, LED会出现显示错乱, 色彩乱跳等.

Tim “cpldcpu” 做过一系列实验 https://cpldcpu.wordpress.com/2014/01/14/light_ws2812-library-v2-0-part-i-understanding-the-ws2812/ 验证过时间间隔的边界, 发现这些要求实际上相当宽松:

  • 触发RESET只需要 9 µs (比手册要求的 50 µs 小很多)
  • 一个 bit 的周期至少需要 1.25 µs, 但是不能超过 9 µs, 因为这样容易触发RESET
  • 0 的高电平时间, 手册要求是 0.35 µs, 实际上可以短至 62.5 ns , 但是不能长于 0.50 µs
  • 1 的高电平时间, 手册要求是 0.65 µs, 实际上长度可以几乎跨越整个 bit 周期, 但是不能短于 0.625 µs

SPI驱动时的bit数选择

对于输出固定长度的电平组合, SPI是最简单的方式. 可以使用 SPI, 通过控制其中的数据值与 WS2812 通信, 而时间间隔控制则需要通过控制 SPI 的时钟以及每次发送的 bit 数量实现, 根据Controlling WS2812(B) leds using STM32 HAL SPI 的计算, 通过对比多种 bit 数的时间要求, 发现使用 bit 数越多, 兼容性越好, MCU越容易实现. 因此可以使用默认的 8bit SPI 通信.

对于 PY32F002A/PY32F003/PY32F030, 因为最高频率是48MHz, 所以当SPI分频为8, 16时, 分别对应 6MHz, 3MHz, 在工作范围内; 对于 PY32F040/PY32F071/PY32F072, 最高频率是72MHz, 当SPI分频为8, 16, 32时, 分别对应 9MHz, 4.5MHz, 2.25MHz, 都在工作范围内.

SPI 驱动 WS2812

对应不同的LED数量, 需要调整下面代码中WS2812_NUM_LEDS的值, 这里使用的是一个8x8的点阵, 因此设为64. 注意这个ws2812_buffer实际上非常占内存, 对于数量超过64的LED灯带(矩阵), 需要考虑其它的实现.

头文件 ws2812_spi.h

#include "main.h"

#define WS2812_NUM_LEDS 64
#define WS2812_SPI_HANDLE Spi1Handle

#define WS2812_RESET_PULSE 60
#define WS2812_BUFFER_SIZE (WS2812_NUM_LEDS * 24 + WS2812_RESET_PULSE)

extern SPI_HandleTypeDef WS2812_SPI_HANDLE;
extern uint8_t ws2812_buffer[];

void ws2812_init(void);
void ws2812_send_spi(void);
void ws2812_pixel(uint16_t led_no, uint8_t r, uint8_t g, uint8_t b);
void ws2812_pixel_all(uint8_t r, uint8_t g, uint8_t b);

函数实现 ws2812_spi.c

#include <string.h>
#include "ws2812_spi.h"

#define WS2812_FILL_BUFFER(COLOR) \
    for( uint8_t mask = 0x80; mask; mask >>= 1 ) { \
        if( COLOR & mask ) { *ptr++ = 0xfc; } \
        else { *ptr++ = 0x80; }}

uint8_t ws2812_buffer[WS2812_BUFFER_SIZE];

void ws2812_init(void) {
    memset(ws2812_buffer, 0, WS2812_BUFFER_SIZE);
    ws2812_send_spi();
}

void ws2812_send_spi(void) {
    HAL_SPI_Transmit(&WS2812_SPI_HANDLE, ws2812_buffer, WS2812_BUFFER_SIZE, HAL_MAX_DELAY);
}

void ws2812_pixel(uint16_t led_no, uint8_t r, uint8_t g, uint8_t b) {
    uint8_t * ptr = &ws2812_buffer[24 * led_no];
    WS2812_FILL_BUFFER(g);
    WS2812_FILL_BUFFER(r);
    WS2812_FILL_BUFFER(b);
}

void ws2812_pixel_all(uint8_t r, uint8_t g, uint8_t b) {
    uint8_t * ptr = ws2812_buffer;
    for( uint16_t i = 0; i < WS2812_NUM_LEDS; ++i) {
        WS2812_FILL_BUFFER(g);
        WS2812_FILL_BUFFER(r);
        WS2812_FILL_BUFFER(b);
    }
}

使用 PY32F0 驱动 WS2812

具体的SPI初始化可以参考文章结尾的示例代码, 根据各自环境的工作频率不同, 需要控制SPI的时钟周期在工作范围之内

对于开启PLL运行在48MHz的PY32F002A/003/030, 使用8分频

static void APP_SPIConfig(void)
{
  LL_SPI_InitTypeDef SPI_InitStruct = {0};
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  //...
  /* The frequency after prescaler should be below 8.25MHz */
  SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8;
  //...
}

对于 PY32F040/071/072, 工作在HSI 24MHz, 使用4分频

static void APP_SPI_Config(void)
{
  Spi1Handle.Instance               = SPI1;
  /* The frequency after prescale should be below 8.25MHz */
  Spi1Handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  //...
}

示例代码中, 通过循环依次修改像素点的RGB值演示LED全彩效果

  ws2812_pixel_all(r, g, b);
  ws2812_send_spi();
  while (1)
  {
    i = (i + 1) % WS2812_NUM_LEDS;
    ws2812_pixel(i, r++, g++, b++);
    ws2812_send_spi();
    LL_mDelay(20);
  }

完整的示例代码通过以下链接查看

  • PY32F002A/PY32F003/PY32F030 https://github.com/IOsetting/py32f0-template/tree/main/Examples/PY32F0xx/LL/SPI/WS2812_LED
  • PY32F040/PY32F071/PY32F072 https://github.com/IOsetting/py32f0-template/tree/main/Examples/PY32F07x/HAL/SPI/WS2812_LED

注意事项

要注意自己使用的 WS2812 的供电电压是 5V 还是 12V, 不要和 PY32F0 的供电混在一起. WS2812 数量多了之后电流是很大的, 对 5V 8x8 的矩阵实测工作电流在 500mA 以上, 如果是 16x16 的矩阵, 电流会超过 2A. 这么大的电流最好单独供电.文章来源地址https://www.toymoban.com/news/detail-750231.html

参考

  • Controlling WS2812(B) leds using STM32 HAL SPI

到了这里,关于普冉PY32系列(十三) SPI驱动WS2812全彩LED的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 普冉PY32系列(八) GPIO模拟和硬件SPI方式驱动无线收发芯片XN297LBW

    普冉PY32系列(一) PY32F0系列32位Cortex M0+ MCU简介 普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境 普冉PY32系列(三) PY32F002A资源实测 - 这个型号不简单 普冉PY32系列(四) PY32F002A/003/030的时钟设置 普冉PY32系列(五) 使用JLink RTT代替串口输出日志 普冉PY32系列(六) 通过I2C接口驱动PCF8574扩

    2024年02月08日
    浏览(77)
  • WS2812全彩RGB驱动方法

    买了一个圆形的WS2812模块玩玩,特来总结一下驱动方法,感觉对比于普通的RGB灯来说,还是有点不一样的。 踩了一些坑,也在此列出。 驱动方法其实很简单,就是发送一个24bit的数据即可,数据0和1的定义分别如下。 它没有所谓的空闲态,如果两个24bit的数据传输时间间隔相

    2024年02月12日
    浏览(43)
  • [HAL]STM32 SPI+DMA驱动WS2812

    该程序是纯手敲,非Cube生成!所有代码均注释。 源码在文章后面获取 Keyword: 单线通讯、归零码、Reset、RGB顺序 RGB一共有24bit位 -相当于驱动一个灯要24bit位 -驱动若干个灯要24* n bit位,通过Reset码决定数据终止(保持) 24bit位应该如何发送? 可见: 表示低电平需要 T0H和T0L的配

    2024年02月09日
    浏览(53)
  • STM32C0开发(1)----SPI 驱动WS2812灯珠

    本文介绍了如何使用STM32微控制器,结合STM32CubeMX配置工具和SPI通讯接口,来驱动和控制WS2812 LED灯带。这是一个集硬件连接、软件配置和编程开发于一体的综合性项目,目标是实现对LED灯带颜色和亮度的精确控制。 最近在弄ST的课程,需要样片的可以加群申请:615061293 。 ht

    2024年02月04日
    浏览(49)
  • 电子模块|外控集成 LED 光源 WS2812模块---硬件介绍和stm32驱动

    WS2812是一个集控制电路与发光电路于一体的智能外控LED光源。其外型与一个5050LED灯珠相同,每个元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路,还包含有高精度的内部振荡器和12V高压可编程定电流控制部分,有效保证了像素点光的颜色

    2024年02月10日
    浏览(50)
  • 普冉PY32系列(十二) 基于PY32F002A的6+1通道遥控小车III - 驱动篇

    普冉PY32系列(一) PY32F0系列32位Cortex M0+ MCU简介 普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境 普冉PY32系列(三) PY32F002A资源实测 - 这个型号不简单 普冉PY32系列(四) PY32F002A/003/030的时钟设置 普冉PY32系列(五) 使用JLink RTT代替串口输出日志 普冉PY32系列(六) 通过I2C接口驱动PCF8574扩

    2024年02月05日
    浏览(43)
  • LL库实现SPI MDA发送方式驱动WS2812

    1,首先打卡STM32CubeMX,配置一下工程,这里使用的芯片是STM32F030F4P6。   时钟 SPI外设  SPI DMA 下载接口,这个不配置待会下程序后第二次就不好下载调试了。  工程配置,没啥说的  选择生成所有文件  将驱动都改为LL库 然后直接点击 General Code 2,初始化dma:  这里卡了一会

    2024年02月12日
    浏览(41)
  • STM32作品设计:蓝牙彩灯V1.4(WS2812全彩、声控、光控、人体红外、小科语音控制、手机APP、蓝牙无线升级)

    @ biliblil视频链接:https://www.bilibili.com/video/BV14L411V78b/ 资料可联系作者:2809786963 实物链接:https://m.tb.cn/h.5hxssok?tk=vEQCWYHTKs0 CZ0001 1、手机APP控制亮度、颜色 2、多种显示模式:闪烁、渐变、呼吸、流水 3、拾音灯模式(随音起舞) 4、手机设置:光控模式、声控模式、声光控模式

    2024年02月11日
    浏览(92)
  • (STM32笔记5)ws2812驱动开发

    ws2812 需要开发的外设:ws2812 开发环境:MDK 开发板:stm32最小系统板 杜邦线无数 一、原理阐述 (一) 这个ws2812有很多种,一个小灯、灯带,矩形像素屏等等。 这些都是DIN连接输入,DOUT连接输出,另外两个引脚是GNE和VCC   (二) 数据传输原理: 第1个WS2812B灯珠接收到了第1个

    2024年01月19日
    浏览(45)
  • 【雕爷学编程】Arduino动手做(86)---4*4位 WS2812 全彩模块4

    37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)

    2024年02月15日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包