收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
ESP32-C3学习 蓝牙 篇系列博文连接:
❤️
测试使用的开发板:
自己画一块ESP32-C3 的开发板(第一次使用立创EDA)(PCB到手)❤️
测试使用的开发环境:
ESP32-C3 VScode开发环境搭建(基于乐鑫官方ESP-IDF——Windows和Ubuntu双环境)❤️
基础篇系列相关博文:
ESP32-C3入门教程 基础篇(一、ADC采样)
ESP32-C3入门教程 基础篇(二、GPIO中断、按键驱动测试)
ESP32-C3入门教程 基础篇(三、UART模块 — 与Enocean无线模块串口通信)
ESP32-C3入门教程 基础篇(四、I2C总线 — 与SHT21温湿度传感器通讯)
ESP32-C3入门教程 基础篇(五、RMT应用 — SK6812全彩RGB LED灯驱动测试)
ESP32-C3入门教程 基础篇(六、TIMG 硬件定时器 与 软件定时器)
ESP32-C3入门教程 基础篇(七、LEDC — LED PWM 控制器)
ESP32-C3入门教程 基础篇(八、NVS — 非易失性存储库的使用)
一、 SK6812 LED基础介绍
SK6812 灯珠集成了 控制电路与发光电路与一体的智能外控 LED 光源。 外形与 5050 LED 灯珠是一样的。 但是与普通的 LED 不同的是,他不是简单的通过高低电平来控制亮灭, 它通过 单线就能控制 RGB 三色的亮灭,采用了一个叫 单极性归零码 数据协议的通讯方式。
1.1 SK6812 控制原理
基础介绍在使用的产品的手册中都有,这里就截取我开发板使用的产品手册中的图片来说明一下:
对于使用者来说,我们需要知道的主要是理解这个协议,然后实现手册中提到的 “0”码 和“1”码,然后每一个灯珠,是由 24 bit 的数据结构组成。
(注意这里说的 24 bit 是数据结构,举个例子, 如果我们使用SPI实现“0” 、“1” 码,SPI 总线发送一个字节,只是实现了一个 码,只是上面 24 bit 数据结构中的 1bit !后面会更加详细的说明这一点)
我们把对应需要了解的参数都截图说明(根据自己选用的产品规格书来确定具体参数):
额外添加点说明,不同比例的三原色光相加得到彩色称为相加混色,比如:
红+绿=黄
红+蓝=紫
蓝+绿=青
红+蓝+绿=白
举个例子:显示黄色,其RGB值为255, 255, 0。 那么上面的 24bit 数据结构为:
1111 1111 1111 1111 0000 0000 (其中的1和0 是上面说的 “1”码 和“0”码)
综合上面,不管使用哪一种方式,其中都是需要在 DIN 端给出符合时间要求的高低电平,才能正确的控制 SK6812:
1.2 SK6812 控制方案
知道了 SK6812 的控制原理,在开发板上面,我们使用一个IO口 连接 DIN端,作为信号的输入端,那么就需要实现 这个IO口实现符合时序的 高低电平,那么有哪些实现方式呢?
1.2.1 GPIO 翻转
最终目的是需要实现规定时间的高低电平,那么最直接想到的就是 直接把 GPIO 翻转速度设置成最大,然后直接置位 复位 GPIO 实现高低电平。 = =!
但是仔细想一下上面的时间要求是 us 级别的,那么对于不同的芯片,不仅是因为主频不同,IO口的翻转速度当然也会不同,在网络上查看到(仅供参考):
1、STM32
- 看到一篇博文直接操作寄存器222ns 采用库函数指令会延迟300ns左右,参考博文 无聊测一下IO口翻转速度 STM32F103RCT6
- 以主频为72MHz为例,指令控制GPIO翻转,最高可达18MHz。
- 直接操作寄存器,单指令周期的,407超频200M的时候,IO口刚好100M
上述事件自己通过公式算一下即可:f=1/T。(T的单位是秒(s),f的单位是赫兹(Hz))。
2、ESP32
- ESP32的IO口速度,简单查找没有找到说明。
3、ESP8266
- ESP8266的GPIO有效翻转大约须要2.5us(0.4MHz)
- ESP8266的GPIO0的翻转速度最快,配合寄存器操作可以实现
算下来,目前来说MCU的发展,还是有能够直接控制 IO 口电平实现的条件,这种简单粗暴的方式需要经过反复的测试调整,因为对于时间的控制还需要考虑很多因素。所以这里介绍一下,不过多探究。
1.2.2 SPI方式
SPI方式,SPI通讯的速度目前器件可以达到大几十Mbps,一般情况下,SPI模块的最大时钟频率为系统时钟频率的1/2。
SPI 的基础知识网上很多,在我博文《总线协议记录》也有记录。
所以通过 SPI 总线发送是比较可行的一种方式。 只要将 SPI 的时钟调整为 8MHz左右(小于等于8Mhz),这样不同的 MCU下,都可以实现。
采用 8Mhz SPI,发送一个字节所需时间1.25us,满足上面 SK6812 的24bit 数据结构 一个bit 的时间:
再根据 “1” 码 < 1us && >0.6us 的 高电平, >0.2us的低电平,得出,SPI发送一个字节 11111100b 即表示 “1” 码,0XF0。
同理可得,SPI发送字节 11000000b 即表示 “0” 码,0xC0。
那么还是按照上面原理部分举的例子,显示黄色的 24bit 数据结构为:1111 1111 1111 1111 0000 0000
那么SPI总线发送如下的24个字节数据(十六进制),就能使得LED显示为黄色:
F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 C0 C0 C0 C0 C0 C0 C0 C0
1.2.2 PWM方式
PWM 方式也是一种常见的控制高低电平的方式,通过上面我们得知,“1”码 和 “0” 码的高低电平比例为3:1. 那么就是调节占空比 ,“1”码的占空比为 75% ,“0”码的占空比为 25%。 那么剩下的只需要把 PWM 的周期设置成 SK6812 的码元周期 > 1.2us 左右。 注意占空比多少,可以根据实际情况调整。
给出2个网上的结论,仅供参考:
- cycle(周期)=1.2us,占空比=50%为1,占空比=30%为0;
(833Khz ,感觉还行) - 周期设置为3MHz,占空比 = 66% 为1,占空比=33%为0;
(0.33us周期,估计写错了,1MHZ还差不多, 1us)
关于ESP32 -C3 使用PWM 方式,不确定可不可以用,毕竟 ESP32 -C3 的PWM按照我们的博文流程我们还没有学习测试,下一篇博文写一下 ESP32 -C3 的PWM学习测试记录。
1.2.3 RMT方式(ESP32)
RMT,是ESP32 系列特有的一个红外发送和接收控制器,红外协议转化为信号,体现在IO上也就是高低电平。
将上面讲到的 “1” 码 和 “0” 码当成红外信号,也可以实现 SK6812 的控制。下面就先来了解下 ESP32-C3 的 RMT。
二、 ESP32-C3 RMT介绍
2.1 RMT 基础介绍
在乐鑫官方 ESP32-C3 芯片手册《esp32-c3_technical_reference_manual_cn》文档中对于 RMT 有详细的介绍:
在官方网站也有关于 RMT 相关API的详细介绍:乐鑫官方ESP32-C3 RMT部分说明
所以详细的资料还是可以通过上面的途径查看,这里我们需要关注的一点就是:
RMT 是如何控制 SK6812 的?
通过前面的SK6812 控制原理我们知道了,控制 SK2812 就是实现符合时间规定的高低电平,那么在ESP32-C3 芯片手册中,有提到 RMT 是如何实现此功能的,对于部分如下图:(当然如果要了解更深还是要好好查看官方的资料)
结合官网图片就能更容易理解:
2.2 RMT 使用介绍(API相关)
RMT 的使用基本步骤如下,但是本文我们是需要控制 SK6812 ,所以只需要了解发送相关的配置及使用:
首先要了解的是一个结构体,发送配置的结构体rmt_tx_config_t
:
上述结构体内容 依次是:RMT载波频率、RMT输出的电平、空闲电平状态、占空比、最大循环计数、载波使能、循环发送使能、空闲电平输出使能。
通过初始化结构体的示例,可以更好的理解:
RMT 输出结构体默认配置如下:
对于控制 SK6812,目前了解到 RMT 的输入配置就可以了。
三、 RMT 示例测试
3.1 IDF 示例测试
在 IDF 示例程序中,官方提供了控制 WS2812 的示例 RMT Transmit Example -- LED Strip
:
程序的过程比较简单,SK6812的驱动和ws2812的驱动是一样的,相关的代码在components/led_strip/src/led_strip_rmt_ws2812.c
文件中。
针对自己的开发板,然后对于示例工程,简单修改一下既可以看到效果,因为示例大家都一样,这里就使用截图表示需要修改的地方:
在示例中EXAMPLE_CHASE_SPEED_MS
太快了,闪得我眼睛有点花,把这个时间改成了300:
#define EXAMPLE\_CHASE\_SPEED\_MS (300)//
在我的开发板上面,本来确实是只有一个LED,但是为了测试,我飞线焊接了一个:
测试结果,示例的现象就是,LED不同颜色的交替闪烁,并没有渐变效果,这里上几张图勉强看看:
3.2 示例改渐变效果
最开始也没有一点一点的去分析驱动代码,示例代码也就看看 RMT 的配置,后面的 SK6812 驱动部分并没有仔细研究,所以测试是闪烁效果,后来想想还是不得劲,不渐变闪烁,这不得亮瞎眼= =!
所以还是得改改,所以看了看示例,其实也就是简单的修改(最后一个vTaskDelay(50)
不需要,这里是以前改过的代码忘了去掉了):
根据上面图示的说明,把所有时间改成如下,是基于例程基础 最平滑 最快速的渐变了:
没视频看不到= =! 上张图勉强应付一下:
四、 SK6812 驱动代码说明
2022/6/16 更新 by 矜辰所致
最近 ESP32-C3 的学习博主已经更新完了 蓝牙 GATT篇章,正准备写一篇蓝牙的小应用,计划要通过手机与开发板进行蓝牙连接,控制板子上的灯,能够渐变当然是最好了,忽然发现 SK6812 的驱动函数忘了怎么用了……
在官方示例中,给了最原始的驱动,但是感觉当时没有理解透彻,所以回过头来重新看一看。
4.1 驱动函数简析
我们在使用中,需要定义一个LED变量,比如:
static led\_strip\_t \*strip;
我们来看一看 led_strip_t
,他是 led_strip_s
结构体类型:
struct led\_strip\_s {
/\*\*
设置灯的颜色
\*/
esp\_err\_t (\*set_pixel)(led\_strip\_t \*strip, uint32\_t index, uint32\_t red, uint32\_t green, uint32\_t blue);
/\*\*
更新灯的颜色
\*/
esp\_err\_t (\*refresh)(led\_strip\_t \*strip, uint32\_t timeout_ms);
/\*\*
清除灯的颜色
\*/
esp\_err\_t (\*clear)(led\_strip\_t \*strip, uint32\_t timeout_ms);
/\*\*
删除灯这个对象
\*/
esp\_err\_t (\*del)(led\_strip\_t \*strip);
};
在示例中我们都使用到了这几个函数,简单记录一下这几个函数的说明:
设置灯的颜色:
/\*
参数含义:
灯的句柄,我们开始定义的变量
需要设置的灯的位置下标,从0开始,如果有很多灯,一般都是使用for循环赋值
红色的值
绿色的值
蓝色的值
\*/
static esp\_err\_t ws2812\_set\_pixel(led\_strip\_t \*strip,
uint32\_t index,
uint32\_t red,
uint32\_t green,
uint32\_t blue)
更新灯的值:
使用上面函数设置完LED颜色值后,需要调用ws2812_refresh
将颜色更新到灯条:
static esp\_err\_t ws2812\_refresh(led\_strip\_t \*strip, uint32\_t timeout_ms)
清除灯的颜色:
等于把等熄灭:
static esp\_err\_t ws2812\_clear(led\_strip\_t \*strip, uint32\_t timeout_ms)
SK2812设备注册函数:
另外还有一个函数需要注意,就是用来注册新的SK2812设备的函数:
led\_strip\_t \*led\_strip\_new\_rmt\_ws2812(const led\_strip\_config\_t \*config)
使用此函数来注册设备,比如:
4.2 设置指定颜色
设置指定延时,我们可以直接使用 ws2812_set_pixel
函数,对于我们定义的结构体变量,根据示例使用即可,设置指定颜色就很简单了:
上图颜色 绿色 和 红色 搞反了!set_pixel(strip, 0, 255, 0, 0)
是绿色,第二个是红色 !
红色 和 绿色 对应位置好像反了,是因为ESP-IDF 驱动中的颜色处理驱动函数是反过来的:
为了与正常的颜色值对应,改成如下即可:
当然为了对应颜色代码(比如 #0033FF 形式)我们可以简单的做几个函数处理一下:
struct WS2812\_COLOR
{
![img](https://img-blog.csdnimg.cn/img_convert/9bd823c7528abb02b0631955ee3b5d9d.png)
![img](https://img-blog.csdnimg.cn/img_convert/6b43ea160419f86412c291abb181ba0d.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**
png)
当然为了对应颜色代码(比如 #0033FF 形式)我们可以简单的做几个函数处理一下:
struct WS2812_COLOR
{
[外链图片转存中…(img-WCtwDKZc-1715870678374)]
[外链图片转存中…(img-h11w2fdS-1715870678375)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)