今天我们使用ESP32自带的LEDC外设制作一个LED呼吸灯

目录

  • 前言
  • 一、呼吸灯是什么
  • 二、首先我们在Blink实例的基础上建立工程
    • 1.引入库添加宏定义
    • 2.修改主函数
  • 最后我们看一下呼吸灯的效果

前言

LEDC是ESP32为我们提供的一个控制LED的外设,(以下摘自乐鑫esp-idf编程指南)LED 控制模块主要用于控制 LED 的强度,虽然它也可以用于其他用途产生 PWM 信号。它有16个通道,可以产生独立的波形,可以用来驱动例如 RGB LED 设备。为了获得最大的灵活性,可以从四个高速/低速定时器之一驱动高速和低速通道。PWM 控制器还具有能力自动增加或减少占空比逐渐,允许淡出没有任何处理器干扰。总的来说,就是我们不需要像STM32那样去使用定时器的PWM输出功能来控制LED,感觉上是更方便了吧,实际上原理差不多。


废话不多说,开干

一、呼吸灯是什么

简单的来说就是通过改变阳极的电压大小从而改变LED的亮度,使它的亮度变化频率接近人的呼吸频率,那么改变阳极的电压大小有两种控制方式,第一种是通过DAC将数字量输出模拟量,改变模拟量的大小,就可以控制LED的亮灭程度;第二种方法呢就是我们在电力电子技术中学习到过的PWM(脉冲宽度调制技术),简单的改变PWM的频率或者脉宽,也可以达到控制输出电压变化的效果,这里我们采用固定频率改变脉宽的方法。

二、首先我们在Blink实例的基础上建立工程

我使用的是ESP-TOOL工具链+VS2017+VisualGDB,建立工程和点亮LED的方法在链接: [ESP32]学习笔记02.这里我就使用之前建立的工程编写代码了

1.引入库添加宏定义

要使用LEDC这个外设首先我们要引入它相关的头文件

#include "driver/ledc.h"

我们加入一些宏定义如下:

#define LEDC_LS_TIMER        LEDC_TIMER_0
#define LEDC_LS_MODE        LEDC_LOW_SPEED_MODE
#define LEDC_LS_CH0_GPIO    (17)
#define LEDC_LS_CH0_CHANNEL LEDC_CHANNEL_0

可以看到这些宏定义分别是:定时器、模式、引脚号、通道;在这里使用低速模式的原因我们可以参考ESP-IDF所提供的示例代码:

#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3{.channel    = LEDC_LS_CH0_CHANNEL,.duty       = 0,.gpio_num   = LEDC_LS_CH0_GPIO,.speed_mode = LEDC_LS_MODE,.hpoint     = 0,.timer_sel  = LEDC_LS_TIMER},{.channel    = LEDC_LS_CH1_CHANNEL,.duty       = 0,.gpio_num   = LEDC_LS_CH1_GPIO,.speed_mode = LEDC_LS_MODE,.hpoint     = 0,.timer_sel  = LEDC_LS_TIMER},

可以看到示例代码中的条件编译,这里我使用的是ESP32-S2的模组,那么S2和RISC-V架构的C3模组都是配置的低速模式,我们这里参考示例配置就行,如果你使用的是ESP32模组,那么可以使用高速模式;
接下来我们先配置好LEDC外设的通道:

ledc_channel_config_t LEDC_BLUE_CFG = { .channel = LEDC_CHANNEL_0,.duty = 0,.gpio_num = LEDC_LS_CH0_GPIO,.speed_mode = LEDC_LS_MODE,.hpoint = 0,.timer_sel = LEDC_LS_TIMER
};

这里给声明的结构体变量赋值,若不设置为全局变量,请编写函数提供可调用结构体成员的接口,后续我们改变占空比时会使用到这个声明的结构体变量;
接下来编写初始化函数和修改占空比的函数:

void LEDC_TIMER_Init(void)
{const ledc_timer_config_t ledc_timer_configstructure = { .duty_resolution = LEDC_TIMER_8_BIT,.freq_hz = 5000,.speed_mode = LEDC_LS_MODE,.timer_num = LEDC_LS_TIMER,.clk_cfg = LEDC_AUTO_CLK};ledc_timer_config(&ledc_timer_configstructure);
}
void LEDC_Init(void)
{LEDC_TIMER_Init();ledc_channel_config(&LEDC_BLUE_CFG);ledc_fade_func_install(0);
}
void LEDC_Set_Duty(uint8_t duty)
{ledc_set_duty(LEDC_BLUE_CFG.speed_mode, LEDC_BLUE_CFG.channel, duty);ledc_update_duty(LEDC_BLUE_CFG.speed_mode, LEDC_BLUE_CFG.channel);
}

可以看到,这里我提供了一个可以修改占空比的接口,这样我们就可以通过调用这个函数而不用调用之前声明的结构体变量来修改占空比了。

2.修改主函数

代码如下:

 int i = 0;LEDC_Init();while (1){for (; i < 240; i++){LEDC_Set_Duty(i);usleep(5000);}for (; i > 0; i--){LEDC_Set_Duty(i);usleep(5000);}}

可以看到这里我使用的是usleep做延时函数,每个单位表示延时1微秒,那么这里的写入的5000参数表示延时5ms,相比freertos提供的vtaskdelay函数只能提供毫秒级延时,usleep可以提供微秒级延时,这对于后面我们操作其他传感器总线写时序帮助很大,使用usleep函数记得包含头文件:

#include "unistd.h"

最后我们看一下呼吸灯的效果

ps:此底板是我自己制作的,可将乐鑫ESP32-S2-Saola-1开发板直接插上使用;

[ESP32]学习笔记03相关推荐

  1. ESP32 单片机学习笔记 - 03 - MCPWM脉冲输出/PCNT脉冲计数

    ESP32 单片机学习笔记 - 03 - MCPWM脉冲输出/PCNT脉冲计数 前言,继续上一篇的内容.因为上一篇刚好实验了iic和spi,形成一对.接下来讲pwm另起一篇. 目录 ESP32 单片机 ...

  2. ESP32学习笔记(20)——SPI(从机)接口使用

    一.SPI简介 SPI(Serial Peripheral Interface) 协议是由摩托罗拉公司提出的通讯协议,即串行外围设备接口,是一种高速全双工的通信总线.它被广泛地使用在 ADC.LCD ...

  3. ESP32学习笔记(19)——SPI(主机)接口使用

    一.SPI简介 SPI(Serial Peripheral Interface) 协议是由摩托罗拉公司提出的通讯协议,即串行外围设备接口,是一种高速全双工的通信总线.它被广泛地使用在 ADC.LCD ...

  4. Git 的安装与初次使用 —— Git 学习笔记 03

    Git 的安装与初次使用 -- Git 学习笔记 03 Git 的安装与初次使用 -- Git 学习笔记 03 安装 Git 在 Linux 上安装 在 Windows 上安装 初次运行 Git 前的 ...

  5. JavaWeb黑马旅游网-学习笔记03【登陆和退出功能】

    Java后端 学习路线 笔记汇总表[黑马程序员] JavaWeb黑马旅游网-学习笔记01[准备工作] JavaWeb黑马旅游网-学习笔记02[注册功能] JavaWeb黑马旅游网-学习笔记03[登陆和 ...

  6. HTML/CSS学习笔记03【CSS概述、CSS选择器、CSS属性、CSS案例-注册页面】

    w3cschool菜鸟教程.CHM(腾讯微云):https://share.weiyun.com/c1FaX6ZD HTML/CSS学习笔记01[概念介绍.基本标签.表单标签][day01] HTML ...

  7. JDBC学习笔记03【JDBC事务管理、数据库连接池、JDBCTemplate】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  8. MySQL学习笔记03【数据库表的CRUD操作、数据库表中记录的基本操作、客户端图形化界面工具SQLyog】

    MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...

  9. Scala学习笔记03:操作符

    Scala学习笔记03:操作符 一.scala中操作符与方法的等价性 scala中操作符即方法.方法即操作符.scala中操作符其实是普通方法调用的另一种表现形式,运算符的使用其实就是隐含地调用对应的 ...

最新文章

  1. java反序列化weblogic_[Todo]Java反序列化-weblogic
  2. TCP之三次握手四次挥手
  3. python sys.argv 默认值
  4. linux asm 磁盘管理,asm磁盘管理篇
  5. superset可视化-world map
  6. spring 面向接口编程_Spring面向方面的编程
  7. 7-2 地下迷宫探索 (30 分)(C语言实现)
  8. 酷狗直播联手腾讯游戏破圈“组团” 游戏直播正版化杀入重量级玩家
  9. linux中安装wine运行windows程序
  10. 课程设计——企业网络项目搭建(下)
  11. windows 10字体突然变小变细,模糊
  12. C语言实现飞机订票系统
  13. js生成二维码的几种方法
  14. roundcube邮箱手机端_在手机上使用便签软件敬业签怎么将便签内容导出到邮箱?...
  15. 金蝶K3案例实验实际成本前台操作
  16. JavaBean为什么需要序列化?
  17. 2020年中国各省GDP简析
  18. Loadrunner11安装及globa-10000配置
  19. 跨专业考清华大学的计算机,18级学长跨考清华大学计算机考研经验分享
  20. 软件开发常见英文单词

热门文章

  1. 《2020/07/24》数仓理论
  2. 手机页面radio和checkbox反应慢
  3. Vue/uni-app倒计时
  4. 【转】保护SSD,设置Chrome浏览器临时文件夹到ramdisk分区
  5. 【面试记录】云和恩墨一面
  6. linux3.4.2内核移植详解(六):基于UVC的USB摄像头内核配置
  7. 运用CRM挽回老客户
  8. 可视化HTML编辑器 KindEditor
  9. War3 局域网开局地图校验机制分析
  10. EDI在服装行业的应用