Arduino 入门学习笔记(十):LED_PWM实验

Arduino 入门学习笔记(十):LED_PWM实验

开发板:正点原子ESP32S3
例程源码在文章顶部可免费下载

1. LED PWM 控制器介绍

1.1 PWM 介绍

PWM(Pulse Width Modulation),简称脉宽调制,是一种将模拟信号变为脉冲信号的技术。PWM 可以控制 LED 亮度、直流电机的转速等。
PWM 的主要参数如下:

  1. PWM 频率。 PWM 频率是 PWM 信号在 1s 内从高电平到低电平再回到高电平的次数,也就是说 1s 内有多少个 PWM 周期,单位为 Hz。
  2. PWM 周期。 PWM 周期是 PWM 频率的倒数,即 T=1/f, T 是 PWM 周期, f 是 PWM 频率。如果 PWM 频率为 50Hz,也就是说 PWM 周期为 20ms,即 1s 由 50 个 PWM 周期。
  3. PWM 占空比。 PWM 占空比是指在一个 PWM 周期内,高电平的时间与整个周期时间的比例,取值范围为 0%~100%。 PWM 占空比如下图所示:
    在这里插入图片描述
    PWM 周期是一个 PWM 信号的时间:脉宽时间是指高电平时间;脉宽时间占 PWM 周期的比例就是占空比。例如,如果 PWM 周期是 10ms,而脉宽时间为 8ms,那么 PWM 占空比就是8/10=80%,此时的 PWM 信号就是占空比为 80%的 PWM 信号。 PWM 名为脉冲宽度调制,顾名思义,就是通过调节 PWM 占空比来调节 PWM 脉宽时间。
    在使用 PWM 控制 LED 时,亮 1s 后灭 1s,往复循环,就可以看到 LED 在闪烁。如果把这个周期缩小到 200ms,亮 100ms 后灭 100ms,往复循环,就可以看到 LED 灯在高频闪烁。继续把这个周期持续缩小,总有一个临界值使人眼分辨不出 LED 在闪烁,此时 LED 的亮度处于灭与亮之间亮度的中间值,达到了 1/2 亮度。 PWM 占空比和亮度的关系如下图所示:
    在这里插入图片描述

1.2 LED_PWM 控制器介绍

ESP32-S3 的 LED PWM 控制器,简写为 LEDC,用于生成控制 LED 的脉冲宽度调制信号。
LED PWM 控制器具有八个独立的 PWM 生成器(即八个通道)。每个 PWM 生成器会从四个通用定时器中选择一个,以该定时器的计数值作为基准生成 PWM 信号。 LED PWM 定时器如下图所示:
在这里插入图片描述
为了实现 PWM 输出,先需要设置指定通道的 PWM 参数:频率、分辨率、占空比,然后将该通道映射到指定引脚,该引脚输出对应通道的 PWM 信号,通道和引脚的关系所下图所示。
在这里插入图片描述

1.3 LED_PWM 函数介绍

本小节介绍到的函数可在以下文件中找到:
C:\Users\ 用户名 \AppData\Local\Arduino15\staging\packages\esp32-3.2.0\cores\esp32\esp32-hal-ledc.c
接下来,我们介绍一下本章节所用到的 LED PWM 相关函数。
第一个函数: ledcSetup 函数,该函数功能是指定 LEDC 通道的 PWM 信号频率和占空比分辨率。

double ledcSetup(uint8_t chan, double freq, uint8_t bit_num);

参数 chan 为 LEDC 通道号,取值为 0~7,共 8 个通道;
参数 freq 为待设置的 PWM 脉宽信号的频率;
参数 bit_num 为计数位数, 即 PWM 信号占空比的分辨率;
返回值: 通道 PWM 信号的频率。
第二个函数: ledcAttachPin 函数,该函数功能是将指定的 LEDC 通道绑定到指定 GPIO 引脚上,即由该引脚输出 LEDC 的 PWM 信号。

void ledcAttachPin(uint8_t pin, uint8_t chan);

参数 pin 为数字引脚编号;
参数 chan 为 LEDC 通道号,取值为 0~7,共 8 个通道;
无返回值。
第三个函数: ledcWrite 函数,该函数功能是设置指定通道输出的占空比数值。

void ledcWrite(uint8_t chan, uint32_t duty);

参数 chan 为 LEDC 通道号,取值为 0~7,共 8 个通道;
参数 duty 为待设置的 PWM 占空比数值。该数值的范围由通道初始化设置函数 ledcSetup()中的计数位数决定。例如,计数位数为 8,那么占空比设置值的范围就为 0~255。要输出占空比
50%的 PWM 信号,该参数应设置为 128。
无返回值。

2. 硬件设计

2.1 例程功能

实现 LED0 由暗变亮,再从亮变暗,依次循环。

2.2 硬件资源

1) LED PWM:LED-IO1

2.3 原理图

本章实验使用的 LED PWM 为 ESP32-S3 的片上资源,因此并没有相应的连接原理图。

3. 软件设计

3.1 程序流程图

下面看看本实验的程序流程图
在这里插入图片描述

3.2 程序解析

pwm 驱动代码
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。 PWM 驱动源码包括两个文件: pwm.cpp 和 pwm.h。
下面我们先解析 pwm.h 的程序。 对 LED PWM 做了相关定义。
ESP32新版本ledc库进行了修改,如果使用新版本,代码也需要进行相应修改

#define LED_PWM_PIN 1 /* PWM 信号输出的引脚 */
#define LED_PWM_CHANNEL 0 /* LED PWM 通道号 */

我们选择使用 LED PWM 的通道 0,将该通道映射到 IO1,最终 IO1 引脚会输出通道 0 的PWM 信号。
下面我们再解析 pwm.cpp 的程序,这里有两个函数 led_pwm_init 和 pwm_set_duty,其定义如下:

/**
* @brief LED PWM 初始化函数
* @param frequency: PWM 输出频率,单位 HZ
* @param resolution: PWM 占空比的分辨率 1-16,比如设置 8,分辨率范围 0~255
* @retval 无
*/
void led_pwm_init(uint16_t frequency, uint8_t resolution)
{
	ledcSetup(LED_PWM_CHANNEL, frequency, resolution);
	/* PWM 初始化,引脚和通道由 pwm.h 的 LED_PWM_PIN 和 LED_PWM_CHANNEL 宏修改 */
	ledcAttachPin(LED_PWM_PIN, LED_PWM_CHANNEL);
	/* 绑定 PWM 通道到 LED_PWM_PIN 上 */

	/* 新版本使用以下初始化代码 v3.2.0*/
	//ledcAttachChannel(LED_PWM_PIN, frequency, resolution,LED_PWM_CHANNEL);
}
/**
* @brief PWM 占空比设置
* @param duty: PWM 占空比
* @retval 无
*/
void pwm_set_duty(uint16_t duty)
{
	ledcWrite(LED_PWM_CHANNEL, duty);
	/* 改变 PWM 的占空比,通道由 pwm.h 的 LED_PWM_CHANNEL 宏修改 */
	
	/* 新版本使用以下代码 v3.2.0*/
	//ledcWriteChannel(LED_PWM_CHANNEL, duty);
}

led_pwm_init 函数是初始化 PWM 输出功能, 首先调用 ledcSetup 函数设置 LEDC 通道参数: PWM 通道、 PWM 频率和占空比的分辨率。然后调用 ledcAttachPin 函数绑定 PWM 通道到IO1 引脚。
pwm_set_duty 函数就是调用 ledcWrite 函数去完成 PWM 占空比的修改。
07_led_pwm.ino 代码
在 07_led_pwm.ino 里面编写如下代码:

#include "pwm.h"
uint16_t g_ledpwmval = 0; /* 占空比值 */
uint8_t g_dir = 1; /* 变化方向(1 增大 0 减小) */
/**
* @brief 当程序开始执行时,将调用 setup()函数,通常用来初始化变量、函数等
* @param 无
* @retval 无
*/
void setup()
{
led_pwm_init(1000, 10);/* LED PWM 初始化,PWM 输出频率为 1000HZ,占空比分辨率为 10 */
}
/**
* @brief 循环函数,通常放程序的主体或者需要不断刷新的语句
* @param 无
* @retval 无
*/
void loop()
{
	if (g_dir)
	{
	g_ledpwmval += 5;
	}
	else
	{
	g_ledpwmval -= 5;
	}
	if (g_ledpwmval > 1005)
	{
	g_dir = 0;
	}
	if (g_ledpwmval < 5)
	{
	g_dir = 1;
	}
	pwm_set_duty(g_ledpwmval);
	delay(10);
}

在 setup 函数中,调用 led_pwm_init 函数完成 PWM 输出的初始化。
在 loop 函数中, 通过简单的逻辑判断,让 g_ledpwmval 变量可从小变大,又从大变小,最终通过 pwm_set_duty 函数传递 g_ledpwmval 参数去修改占空比,达到修改 LED 亮度效果。为了让效果更为明显,添加了延时 10ms 操作。

4. 下载验证

下载代码完成后, ESP32-S3开发板上LED灯的亮度会以一个平稳的速度从最暗变到最亮,然后再从最亮变到最暗,实现呼吸灯的效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值