当前位置: 首页 > news >正文

ESP32S3:参考官方提供的led_strip组件使用 SPI + DMA 方式驱动WS2812 RGB灯的实现思路 (实现各个平台移植使用该方式)

目录

    • 引言
    • 使用SPI + DMA 方式实现思路分析
      • 1. 查看WS2812的datasheet手册
      • 2. 根据官方的led_strip组件的方式,自己手把手实现一遍
      • 3.完整的程序(实现霓虹灯效果)

引言

  参考官方提供的led_strip组件使用 SPI + DMA 方式驱动WS2812 RGB灯的实现思路,只有明白实现的思路,方能将其移植到各个平台使用),至于官方提供的led_strip组件我就不在此分析了,大家可以通过终端输入 idf.py add-dependency "espressif/led_strip^2.0.0" 命令下载该组件源码。

使用SPI + DMA 方式实现思路分析

1. 查看WS2812的datasheet手册

  通过手册,了解如何驱动ws2812 RGB灯模块的。下面是我从手册中截取的内容:
在这里插入图片描述
划红线提到,ws2812支持多个级联,每个ws2812会截取24bit数据,其他数据会往下发送给下一级的ws2812,如此类推。这种情况datasheet手册中有提到,如下图所示:
在这里插入图片描述
而datasheet中提到关于每个bit数据0码和1码的时序波形要求,如下图所示:
在这里插入图片描述

2. 根据官方的led_strip组件的方式,自己手把手实现一遍

  首先需要知道,官方提供的led_strip组件使用的SPI频率为2.5MHz,也是每个bit占用的时间是400ns=0.4us,而led_strip组件是使用3个SPI的bit数据表示一个ws2812的bit数据的,也就是说led_strip组件发送一个ws2812的bit数据的时间是3个SPI bit的时间(3x0.4us=1.2us),可以看出led_strip组件发送的一个ws2812的bit数据的时间并不满足>=1.25us,其实大家不要太在意这个,使用3个SPI bit表示一个ws2812的bit数据是经过大量测试验证,是可行、可靠的。如果大家觉得担心,是可以用一个字节的SPI数据来表示一个ws2812的bit数据的,那么8 x (spi clock) >= 1.25 , 也就是spi clock >=0.156us SPI时钟频率带6.4MHz才可行。
  废话不多说,下面是我使用官方提供的led_strip组件使用的SPI频率为2.5MHz方式画的发送一个GRB数据的时序波形图:
在这里插入图片描述
  通过我提供的时序波形图,大家也应该对使用2.5MHz,3个SPI表示一个ws2812的bit数据有清晰的认识了,ws2812的1码通过SPI发送3个bit数据110表示,而ws2812的0码通过SPI发送3个bit数据100表示;也可知道一个ws2812的GRB数据有三个字节,每个字节表示一种颜色,而一种也是需要3字节的SPI数据去实现。那么怎么将这3字节的数据转成将要发送的SPI数据呢?实现代码如下:
在这里插入图片描述
上图的程序已经有很详细的注解了,这里就不再讲解了。

3.完整的程序(实现霓虹灯效果)

/*#######################################################################################################*/
/*                      start   使用ESP32S3 SPI的API函数做的WS2812 LED灯带驱动程序)                      */
/*#######################################################################################################*/
/*** @file spi_ws2812.c* @brief 使用SPI控制WS2812 LED的ESP32-S3优化实现* @note 基于ESP-IDF v5.1 开发,硬件平台:ESP32-S3*/
#include "driver/spi_master.h"
#include "soc/spi_periph.h"
#include "hal/spi_hal.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"/* 宏定义 ----------------------------------------------------------------*/
//   #define TAG "WS2812"                                // 日志标签
#define STRIP_LED_GPIO_PIN       48                 // WS2812数据引脚(必须支持SPI MOSI功能)
#define STRIP_LED_NUMBERS        1                  // LED数量
#define SPI_HOST                 SPI2_HOST          // 使用的SPI控制器(ESP32-S3 SPI2支持高速传输)
#define SPI_CLOCK_SPEED_HZ       (2.5 * 1000 * 1000)// SPI时钟频率(需匹配WS2812时序要求)
#define SPI_DMA_CHANNEL          SPI_DMA_CH_AUTO    // 自动选择DMA通道
#define SPI_TRANS_QUEUE_SIZE     4                  // SPI传输队列深度
#define BYTES_PER_PIXEL          3                  // 每个像素的字节数(GRB格式)
#define BITS_PER_COLOR_BIT       3                  // 每个颜色位对应的SPI数据位数/* 全局变量 --------------------------------------------------------------*/
static uint8_t *pixel_buf = NULL;                   // LED数据缓冲区(DMA要求内存对齐)
static spi_device_handle_t spi_device;              // SPI设备句柄/* 函数声明 --------------------------------------------------------------*/
static void ws2812_encode_color(uint8_t color, uint8_t *buffer);/*** @brief SPI控制器初始化* @note 配置SPI总线参
http://www.lryc.cn/news/541894.html

相关文章:

  • Http模块及练习
  • 计算机视觉行业洞察--影像行业系列第一期
  • C语言番外篇(3)------------>break、continue
  • 【NLP 31、预训练模型的发展过程】
  • sqlclchery面对复杂的sql语句怎么办
  • C++/JavaScript ⭐算法OJ⭐下一个排列
  • 《Mycat核心技术》第17章:实现MySQL的读写分离
  • Windows 11 使用容器(Docker Podman)
  • 代码审计入门学习之sql注入
  • 2024信息技术、信息安全、网络安全、数据安全等国家标准合集共125份。
  • element ui的select选择框
  • 文档检索服务平台
  • 使用FastAPI进行可视化部署
  • 设计模式 之 工厂模式(简单工厂模式、工厂方法模式、抽象工厂模式)(C++)
  • 3、Kubernetes 集群部署 Prometheus 和 Grafana
  • 【C语言】第八期——指针
  • 如何在 Mac 上安装并配置 JDK 环境变量
  • 【git-hub项目:YOLOs-CPP】本地实现05:项目移植
  • LeetCode 热题 100 206. 反转链表
  • 2025年02月21日Github流行趋势
  • WebXR教学 03 项目1 旋转彩色方块
  • 深入解析JVM垃圾回收机制
  • 【简单】209.长度最小的子数组
  • 细说 Java 引用(强、软、弱、虚)和 GC 流程(二)
  • CSS通过webkit-scrollbar设置滚动条样式
  • Win10配置VSCode的C/C++编译环境
  • 数据结构与算法再探(七)查找-排序
  • 【C语言】指针(5)
  • 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(2)
  • PLC通讯