2. ESP32-S3点灯
2.1 LED 灯结构组成
LED 灯(发光二极管)是一种半导体光源,主要结构包括以下部分:
- 外壳:通常由塑料或玻璃制成,用于保护内部元件。
- 发光材料:LED 最核心的部分,由特殊半导体材料制成,例如:常见的 InGaN(氮化铟镓)或 AlInGaP(铝铟镓磷)。
- 芯片:用于产生光的发光二极管芯片。
- 引线:提供电连接的金属引线。
- 焊点:将LED 芯片与引线连接在一起的焊接点。
- 电极:负责连接半导体材料与外部电路,通常由金属制成。
- 反射腔:用于增强发光效果的一个结构,将发出的光反射到正面。
2.2 LED 灯发光原理
LED(发光二极管)发光原理基于半导体特性。在半导体中,存在着两类载流子:电子(n型半导体)和空穴(p型半导体)。当n型与p型半导体材料接触时,会在交界处形成一个层结。当施加适当的电压时,层结中空穴和电子可重组并释放能量。这个能量以光子的形式释放出来,产生光。
2.3 LED 灯驱动原理
LED 驱动指的是通过稳定的电源为 LED 提供合适的电流和电压,使其正常工作点亮。LED 驱动方式主要有恒流和恒压两种。限定电流的恒流驱动是最常见的方式,因为 LED 灯对电流敏感,电流大于其额定值可能导致损坏。恒流驱动保证了稳定的电流,从而确保了 LED 安全。
LED 灯的驱动比较简单,只需要给将对应的正负极接到单片机的正负极即可驱动。LED的接法也分有两种,灌入电流和输出电流。
- 灌入电流指的是LED的供电电流是由外部提供电流,将电流灌入我们的MCU;风险是当外部电源出现变化时,会导致MCU的引脚烧坏。
- 输出电流指的是由MCU提供电压电流,将电流输出给LED;如果使用 MCU的GPIO 直接驱动 LED,则驱动能力较弱,可能无法提供足够的电流驱动 LED。
需要注意的 是 LED 灯的颜色不同,对应的电压也不同。 电流不可过大,通常需要接入220欧姆到10K欧姆左右的限流电阻 ,限流电阻的阻值越大,LED的亮度越暗。
2.4 LED灯原理图
原理图中,将LED的正极接入电源3.3V,负极接入限流电阻再到GPIO48。通过LED灯的驱动原理可以知道,我们只要控制开发板的GPIO48引脚输出低电平,即可点亮LED;
2.5 LED 灯驱动流程
2.5.1 配置IO口
关于IO口的配置,这里提供了两种方法。
方法1:
导入头文件“driver/gpio.h”
,通过设置一个结构体gpio_config_t,将IO48配置为输出模式,无上拉下拉且不支持中断。使用该方法的好处就是随心所欲,你可以按照自己的意向将对应的IO口配置为输入或输出,上拉或下拉,边沿中断或电平中断。
include "driver/gpio.h"
#define LED_PIN 48
gpio_config_t led_config = {
.pin_bit_mask = (1ULL<<LED_PIN), //配置引脚
.mode =GPIO_MODE_OUTPUT, //输出模式
.pull_up_en = GPIO_PULLUP_DISABLE, //不使能上拉
.pull_down_en = GPIO_PULLDOWN_DISABLE, //不使能下拉
.intr_type = GPIO_INTR_DISABLE //不使能引脚中断
};
gpio_config(&led_config);
2
3
4
5
6
7
8
9
10
11
关于各个参数有哪一些看以下说明:
什么是输入输出?
📌 - 输入是指将数据或信号从外部设备或其他源传递到目标设备或系统中(从外部设备传入到开发板的信号都可以叫输入)。在计算机系统中,输入通常是通过键盘、鼠标、触摸屏、传感器等外部设备向计算机发送数据或指令。
- 输出是指将数据或信号从目标设备或系统传递到外部设备或其他接收方(从开发板输出到外部设备的信号都可以叫输出)。在计算机系统中,输出通常是通过显示器、打印机、音频设备等将计算机处理的数据或结果展示给用户或其他设备。
什么是上下拉电阻?
📌 上下拉电阻(Pull-up and Pull-down resistors)是在电子电路中常用的元件,用于控制信号线的默认状态。
- 当信号线不连接到任何电源或地时,它处于开路状态,容易受到外界电磁干扰而产生不确定的电平。为了保证信号的稳定性,可以在信号线引脚上加入上拉电阻或下拉电阻。
- 上拉电阻(Pull-up resistor)连接到信号线和高电平(通常为电源电压)之间。当信号线没有连接任何外部设备时,上拉电阻将该信号线拉为高电平。当外部设备连接到该信号线并输出低电平时,由于外部设备的电流较大,上拉电阻无法抵抗这种电流,信号线就会变为低电平。
- 下拉电阻(Pull-down resistor)则连接到信号线和低电平(通常为地)之间。当信号线没有连接任何外部设备时,下拉电阻将该信号线拉为低电平。当外部设备连接到该信号线并输出高电平时,由于外部设备的电流较大,下拉电阻无法抵抗这种电流,信号线就会变为高电平。
方法2:
这是一种更为简易的配置方法。先通过gpio_reset_pin函数初始化一个IO口,然后再使用gpio_set_direction函数配置这个引脚的输入输出模式。
示例:初始化GPIO9引脚为输出模式。
#define LED_PIN 9
gpio_reset_pin(LED_PIN); //初始化LED_PIN引脚
gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT); //配置引脚为输出模式
2
3
关于使用到的函数说明:
esp_err_t gpio_reset_pin(gpio_num_t gpio_num)
:该函数是ESP32在ESPIDF中用于重置GPIO口的函数。它可以将选定的GPIO口重置为初始状态,以便后续对该IO口进行设置或用作其他用途。 函数的参数包括:
gpio_num
:要重置的GPIO口的编号。 函数的返回值是一个esp_err_t
类型的枚举值,表示函数执行的结果。如果操作成功,返回ESP_OK
;如果GPIO编号错误,返回ESP_ERR_INVALID_ARG
。
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
:该函数是ESP32在ESPIDF中用于设置GPIO口方向的函数。它可以将选定的GPIO口设置为输入模式、输出模式或双向模式。 函数的参数包括:
gpio_num
:要设置的GPIO口的编号。direction
:要设置的方向,可以是GPIO_MODE_INPUT
:输入模式;GPIO_MODE_OUTPUT
:输出模式;GPIO_MODE_INPUT_OUTPUT
:输入输出模式; 函数的返回值是一个esp_err_t
类型的枚举值,表示函数执行的结果。如果操作成功,返回ESP_OK
;如果GPIO编号或方向参数错误,返回相应的错误代码。
让我们点进gpio_reset_pin函数,看看它究竟干了些什么。
esp_err_t gpio_reset_pin(gpio_num_t gpio_num)
{
assert(GPIO_IS_VALID_GPIO(gpio_num));
gpio_config_t cfg = {
.pin_bit_mask = BIT64(gpio_num),
.mode = GPIO_MODE_DISABLE,
//for powersave reasons, the GPIO should not be floating, select pullup
.pull_up_en = true,
.pull_down_en = false,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&cfg);
return ESP_OK;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
可以看到本质上这个函数也是配置gpio_config_t结构体。
2.5.2 IO口操控
配置完IO口后,让我们再来认识一个IO口控制函数。
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
该函数是ESP32在ESPIDF中用于设置GPIO口电平的函数,可以设置IO口的高低电平。
函数的参数包括:
gpio_num
:要设置的GPIO口的编号。level
:要设置的电平值,0表示低电平,1表示高电平。 函数的返回值是一个esp_err_t
类型的枚举值,表示函数执行的结果。如果操作成功,返回ESP_OK
;如果GPIO编号错误或该GPIO口未被设置为输出模式,返回相应的错误代码。 示例:
int LED_PIN = 9;
gpio_set_level(LED_PIN, 0);//将led引脚配置为低电平
gpio_set_level(LED_PIN, 1);//将led引脚配置为高电平
2
3
什么是高低电平?
📌 高电平和低电平是指在数字电路中,电信号的电压电平高低状态。在数字电路中,信号的高电平和低电平通常对应于两个离散的电压电平值,例如在TTL(Transistor-Transistor Logic)电平标准中,低电平(L)通常被定义为在0伏到0.8伏的电压范围,而高电平(H)通常被定义为在2.4伏到5伏的电压范围。 在数字电路中,低电平和高电平通常用于代表逻辑“0”和“1”的两种状态。在逻辑电路中,当信号处于高电平时,通常表示逻辑“1“;而当信号处于低电平时,则表示逻辑”0“。这是因为数字电路中只有两种状态(1和0),而高电平和低电平恰好对应于逻辑“1”和“0”。 请注意,不同的电平标准可能会有不同的定义和规范。在不同的电路和系统中,高电平和低电平的定义可能会有所不同。
2.6 点灯验证
新建文件夹hardware,后续由自己编写的驱动代码,全部放在此处。
在文件夹hardware里,再新建一个文件夹led保存我们编写LED的.c和.h文件。
在led文件里新建两个文件【bsp_led.c】【bsp_led.h】。
在VSCode中添加的方法:在要创建文件夹或文件的地方,右键即可看到新建文件选项。
添加.c和.h文件路径
在 bsp_led.c 中编写如下代码:
#include "bsp_led.h"
//配置输出寄存器
#define GPIO_OUTPUT_PIN_SEL (1ULL<<LED_PIN)
/**
* @函数说明 LED的初始化
*
*/
void LedGpioConfig(void)
{
gpio_config_t gpio_init_struct = {0};
//配置IO为通用IO
esp_rom_gpio_pad_select_gpio(LED_PIN);
gpio_init_struct.intr_type = GPIO_INTR_DISABLE; //不使用中断
gpio_init_struct.mode = GPIO_MODE_OUTPUT; //输出模式
gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE; //使能上拉模式
gpio_init_struct.pull_down_en = GPIO_PULLDOWN_DISABLE; //失能下拉模式
gpio_init_struct.pin_bit_mask = GPIO_OUTPUT_PIN_SEL; //使用GPIO9输出寄存器
//将以上参数配置到引脚
gpio_config( &gpio_init_struct );
//设置引脚输出高电平,默认不让LED亮
gpio_set_level(LED_PIN, 1);
}
/**
* @函数说明 设置LED亮
*
*/
void LedOn(void)
{
gpio_set_level(LED_PIN, 0);
}
/**
* @函数说明 设置LED灭
*
*/
void LedOff(void)
{
gpio_set_level(LED_PIN, 1);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
在 bsp_led.h 中编写如下代码:
#ifndef _BSP_LED_H_
#define _BSP_LED_H_
#include "driver/gpio.h"
//设置LED引脚
#define LED_PIN 48
/**
* @brief LED初始化
*
*/
void LedGpioConfig(void);
/**
* @brief 设置LED亮
*
*/
void LedOn(void);
/**
* @brief 设置LED灭
*
*/
void LedOff(void);
#endif
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
在 main.c 中编写如下代码:
#include <stdio.h>
#include "hardware/led/bsp_led.h"
void app_main(void)
{
//LED初始化
LedGpioConfig();
//设置LED点亮
LedOn();
}
2
3
4
5
6
7
8
9
10
11
12
2.7 点灯效果
开发板上的标记着G48的LED灯,下载代码后将会常亮。