ESP32学习笔记2(GPIO的数字输入输出功能)
1. 普通5mm直径LED参数测定实验
以上为普通5mm直径LED,手册建议持续工作电流为20mA以内。以下,采用学生电源(带控压限流功能)通过限流电阻170欧给各色LED供电,通过缓慢加压测流和观察LED亮度的方法,确定电流、压降与亮度关系,实测该批次LED颜色与压降大致如下:
颜色 1mA状态与压降 5mA状态与压降 10mA状态与压降 15mA状态与压降 20mA状态与压降
红 1mA起亮 明亮,1.98V 明亮,2.04V 刺眼,2.08V 刺眼,2.13V
绿 1mA起亮 较亮,1.96V 亮,2.00V 亮,2.03V 亮,2.04V
黄 1mA起亮 明亮,1.96V 明亮,2.01V 刺眼,2.04V 刺眼,2.07V
蓝 1mA起亮 明亮,2.72V 明亮,2.77V 刺眼,2.85V 刺眼,2.91V
白 1mA起亮 刺眼,2.82V 明亮,2.92V 刺眼,3.01V 刺眼,3.07V
注:以上LED亮度肉眼区分为星亮、较亮、亮、明亮、刺眼5种状态,亮度依次增强。不同批次及规格LED不尽相同,供参考。
从以上实验结论可知,普通5mm直径LED在1-2mA就能观察到起亮(有些已经达到亮和明亮的程度),10mA就已经很明亮了。所以完全可以按10mA来设计LED工作电流。
ESP32可以提供3.3V的40mA输出能力,足以烧坏LED。而实测红色LED烧坏为短路状态,这可能进一步导致ESP32故障。为保证电路安全运行,请务必给LED串联限流电阻。电阻计算参考以上实验数据,约取100到200欧即可。
2. 普通数字输出功能
去掉影响闪存和仅建议用作输入的GPIO引脚,ESP32推荐用于普通IO输出功能的引脚标示如下图:
实测该ESP32控制板载LED灯的为编号为2的引脚,高有效,程序如下:
点击查看代码
#define LED 2
void setup()
{
pinMode(LED,OUTPUT);
}
void loop()
{
digitalWrite(LED,HIGH); // 同 digitalWrite(LED,1);
delay(1000);
digitalWrite(LED,LOW); // 同 digitalWrite(LED,0);
delay(1000); //亮灭时间不同以示区别
}
对于这类需要配合BOOT按键的ESP32开发板,除了正常选择开发板型号和串口、输入正确的程序外,程序下载的操作实测有2种,读者可自行尝试:
1)按住BOOT键不松手,IDE点击“编译下载”图标,待IDE完成编译、显示如下图所示的“connecting...”信息时松开BOOT键,可自动进行程序下载进程。
而后按一下RST,单片机就开始执行新程序。
2)另一种方式是仅在IDE完成编译、显示“connecting...”信息时才按一下BOOT键(注意不要过快,如按下保持2~3秒再松开),实测也可进行程序下载进行。下载完成后,需要手动完成单片机复位,单片机才开始执行新程序。
经多次尝试,尽管第2种方式多数均能实现下载,但并不稳定,可能会下载失败或多次按压BOOT才成功,因此推荐采用第1种下载操作方式。
继续用多路流水灯模块(共阴极、高有效)测定各引脚GPIO编号与程序中引脚编号的关系。如编写GPIO 0控制LED1、GPIO 13控制LED2、GPIO 23控制LED3,亮灭交替不同时间以示区别,程序如下:
点击查看代码
#define LED1 0
#define LED2 13
#define LED3 23
void setup()
{
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
pinMode(LED3,OUTPUT);
}
void loop()
{
digitalWrite(LED1,HIGH);
digitalWrite(LED2,HIGH);
digitalWrite(LED3,HIGH);
delay(2000); // 3只LED全亮2秒
digitalWrite(LED1,HIGH);
digitalWrite(LED2,LOW);
digitalWrite(LED3,LOW);
delay(2000); // LED1亮、LED2灭、LED3灭,持续2秒
digitalWrite(LED1,LOW);
digitalWrite(LED2,HIGH);
digitalWrite(LED3,LOW);
delay(1000); // LED2亮、LED1灭、LED3灭,持续1秒
digitalWrite(LED1,LOW);
digitalWrite(LED2,LOW);
digitalWrite(LED3,HIGH);
delay(200); // LED2亮、LED1灭、LED3灭,持续1秒
}
3. 普通数字输入功能
与可以作为普通数字输出的引脚数量相比,ESP32可作为普通数字输入的引脚多了G34、G35、G36和G39,这些引脚的位置及编号如下图所示:
接下来,分别测试这些引脚的普通输入、上拉输入、下拉输入以及触摸感应功能。注意,G34、G35、G36、G39四路引脚内部无上下拉电阻设计,理论上仅支持普通数字输入模式。即使声明为上拉或下拉输入功能,也不能实现预期抗干扰效果。
(1)普通输入模式
采用一组8只数字IO作为输出,另一组8路IO作为普通数字输入,通过杜邦线接高(3.3V)、低(GND)和悬空3种输入状态,控制对应LED亮灭。
点击查看代码
byte LED[8]={23,22,1,3,21,19,18,5}; // 注意:8位流水灯模块为共阳极,低有效(控制信号输出为低电平时灯亮)
byte KEY[8]={36,39,34,35,32,33,25,26};
void setup()
{
for(int i=0;i<8;i++)
{
pinMode(KEY[i],INPUT); //控制引脚均声明为普通输入模式
pinMode(LED[i],OUTPUT);
digitalWrite(LED[i],LOW);
}
delay(3000); //全亮持续3秒,表示程序正常完成初始化
for(int i=0;i<8;i++) //熄灭8只LED
digitalWrite(LED[i],HIGH);
}
void loop()
{
for(int i=0;i<8;i++)
digitalWrite(LED[i],digitalRead(KEY[i]));
}
(2)上拉输入模式
在Arduino单片机开发中,输入上拉模块通过编程实现内部上拉电阻电路的激活。这种输入上拉模式使得输入信号默认为高电平,输入为GND时才读到低电平。如此,输入量被确定在高/低2种电平之间,抗干扰能力强。
点击查看代码
byte LED[8]={23,22,1,3,21,19,18,5}; // 注意:8位流水灯模块为共阳极,低有效(控制信号输出为低电平时灯亮)
byte KEY[8]={36,39,34,35,32,33,25,26};
void setup()
{
for(int i=0;i<8;i++)
{
pinMode(KEY[i],INPUT_PULLUP); //控制引脚均声明为输入上拉模式
pinMode(LED[i],OUTPUT);
digitalWrite(LED[i],LOW);
}
delay(3000); //全亮持续3秒,表示程序正常完成初始化
for(int i=0;i<8;i++) //熄灭8只LED
digitalWrite(LED[i],HIGH);
}
void loop()
{
for(int i=0;i<8;i++)
digitalWrite(LED[i],digitalRead(KEY[i]));
}
(3)下拉输入模式
下拉输入与上拉输入的电路及功能设计恰好相反,由于输入为下拉设计,引脚悬空或接低电平时,CPU总读到低电平输入。仅当输入确定地接高电平(3.3V)时,CPU才读到高电平。
点击查看代码
byte LED[8]={23,22,1,3,21,19,18,5}; // 注意:8位流水灯模块为共阳极,低有效(控制信号输出为低电平时灯亮)
byte KEY[8]={36,39,34,35,32,33,25,26};
void setup()
{
for(int i=0;i<8;i++)
{
pinMode(KEY[i],INPUT_PULLDOWN); //控制引脚均声明为输入下拉模式
pinMode(LED[i],OUTPUT);
digitalWrite(LED[i],LOW);
}
delay(3000); //全亮持续3秒,表示程序正常完成初始化
for(int i=0;i<8;i++) //熄灭8只LED
digitalWrite(LED[i],HIGH);
}
void loop()
{
for(int i=0;i<8;i++)
digitalWrite(LED[i],digitalRead(KEY[i]));
}
(4)触摸感应功能
ESP32具备普通Arduino数字输入引脚不具备的感应输入功能,这种输入功能原理是引脚支持感应皮肤触摸引脚后引起的电荷变化,从而判定触摸动作。支持触摸功能的引脚共有10路,如图所示:
启用这些引脚的触摸输入功能的语法类似中断功能,详见以下示例程序:
点击查看代码
#define TOUCH_PIN 4 // T0触摸传感器连接到GPIO4
#define LED_PIN 23 // LED连接到GPIO23
void setup()
{
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
touchAttachInterrupt(TOUCH_PIN, touchHandler, 40); // 第3个参数为触摸传感器的阈值,该值可根据需要调整
}
void loop()
{
// 主循环中不需要做任何操作,触摸检测在后台进行
}
void touchHandler() // 触摸事件处理函数
{
static bool ledState = false; // 切换LED的状态
ledState = !ledState;
digitalWrite(LED_PIN, ledState);
Serial.println("T0 touched!"); // 打印触摸事件
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具