3、Arduino_esp32 GPIO使用


注: 本文章内容是基于arduino框架进行esp32的开发。
开发环境搭建可以参考上一篇文章:2、搭建ESP32开发环境

1、GPIO简介

GPIO是为控制其中使用相对较多的外设之一,GPIO通常用于实现输出电平信号与读取引脚的电平状态。在实际使用中通常用于控制像led灯这类器件和读取按键按键是否按下灯。ESP32上的GPIO外设支持中断。

2、GPIO模式

**(1)输入模式:**在此模式下,GPIO将用于读取相应引脚的数字状态。例如用于读取引脚状态判断按键是否按下。
**(2)输出模式:**在输出模式下,GPIO会通过控制引脚输出数字状态来驱动外部设备。例如用于点亮LED、控制数码管灯。

3、Arduino框架下ESP32的GPIO相关函数

(1)pinMode:用于设置对应引脚的GPIO工作模式。
函数原型:

void pinMode(uint8_t pin, uint8_t mode);
/*
参数说明:
pin:GPIO管脚编号。
mode:GPIO管脚的工作模式。(INPUT、OUTPUT、INPUT_PULLDOWN、INPUT_PULLUP)
*/

宏说明:

模式宏意义
INPUT将GPIO设置为无上拉或下拉(高阻抗)的输入。
OUTPUT将GPIO设置为输出模式。
INPUT_PULLDOWN将GPIO设置为具有内部下拉功能的输入。(在引脚悬空时读取为低电平状态)
INPUT_PULLUP将GPIO设置为具有内部上拉功能的输入。(在引脚悬空时读取为高电平状态)。

ESP32 SoC系列通过45kR电阻器支持内部上拉和下拉,当将GPIO模式配置为INPUT模式时,可以启用该功能。如果未定义上拉或下拉模式,引脚将保持在高阻抗模式。
(2)digitalWrite:当使用pinMode配置引脚为OUTPUT时用于控制此GPIO引脚输出状态,设置为高或低。

函数原型:

void digitalWrite(uint8_t pin, uint8_t val);
/*
参数说明:
pin:GPIO管脚编号。
val:GPIO管脚输出电平状态。(HIGH、LOW)
*/

宏说明:

电平状态宏意义
HIGH设置引脚输出高电平
LOW设置引脚输出低电平

(2)digitalRead:用于读取被配置为输入模式(INPUT or INPUT_PULLDOWN or INPUT_PULLUP)引脚的状态。
此函数将所选引脚的逻辑状态返回为高(HIGH)或低(LOW)。
函数原型:

int digitalRead(uint8_t pin);
/*
参数说明:
pin:GPIO管脚编号。
*/

(3)attachInterrupt:用于将中断连接到相应的引脚。
函数原型:

attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode);
/*
参数说明:
pin:GPIO管脚编号。
handler:中断函数
mode:中断模式
*/

宏说明:

中断模式宏意义
DISABLED失能中断
RISING上升沿触发
FALLING下降沿触发
CHANGE上升沿和下降沿都触发
ONLOW低电平触发
ONHIGH高电平触发
ONLOW_WE
ONHIGH_WE

(4)attachInterruptArg:用于使用参数将中断附加到定义的管脚。
函数原型:

attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void * arg, int mode);
/*
参数说明:
pin:GPIO管脚编号。
handler:中断函数
arg:指向中断参数的指针。
mode:中断模式
*/

(5)detachInterrupt:从断开特定引脚的中断。
函数原型:

detachInterrupt(uint8_t pin);
/*
参数说明:
pin:GPIO管脚编号。
*/

4、GPIO使用例子

(1)GPIO输入输出模式

#include <Arduino.h>

#define PIN_LED    12
#define PIN_BUTTON 2

#define BUTTON_DOWN LOW     //按键按下
#define BUTTON_UP   HIGH    //按键松开

uint8_t stateLED = 0;
void setup() {
  // put your setup code here, to run once:
  pinMode(PIN_LED, OUTPUT);           //设置LED灯了解的引脚为输出模式
  pinMode(PIN_BUTTON,INPUT_PULLUP);   //设置按键对应的引脚为上拉输入模式
}

void loop() {
  // put your main code here, to run repeatedly:
  if( digitalRead(PIN_BUTTON)==BUTTON_DOWN )       //读取按键对应引脚的状态,用于判断按键是否按下
  {
    stateLED = !stateLED;
    digitalWrite(PIN_LED,stateLED);
    while(digitalRead(PIN_BUTTON)==BUTTON_DOWN);   //保证一次按下只改变一直LED灯的状态
  }
}

(2)GPIO中断

#include <Arduino.h>

struct Button {//按键结构体
    const uint8_t PIN;           //按键对应引脚标号    
    uint32_t KeyPresses_count;   //按键按下次数记录
    bool Key_state;              //按键是否按下
};

//定义两个按键
Button button1 = {23, 0, false};
Button button2 = {18, 0, false};

//按键1的中断函数
void ARDUINO_ISR_ATTR isr(void* arg) {
    Button* s = static_cast<Button*>(arg);
    s->KeyPresses_count += 1;
    s->Key_state = true;
}

//按键2的中断函数
void ARDUINO_ISR_ATTR isr() {
    button2.KeyPresses_count += 1;
    button2.Key_state = true;
}

void setup() {
    Serial.begin(115200);          //配置串口
    pinMode(button1.PIN, INPUT_PULLUP);            //配置按键1对应的引脚为上拉输入模式
    attachInterruptArg(button1.PIN, isr, &button1, FALLING);  //给按键2对应引脚连接中断(带参数的中断函数)
    pinMode(button2.PIN, INPUT_PULLUP);            //配置按键2对应的引脚为上拉输入模式
    attachInterrupt(button2.PIN, isr, FALLING);    //给按键2对应引脚连接中断
}

void loop() {
    if (button1.Key_state) //按键1如果按下通过串口打印按键1累计被按下的次数
    {
        Serial.printf("Button 1 has been pressed %u times\n", button1.KeyPresses_count);
        button1.Key_state = false;
    }
    if (button2.Key_state) //按键2如果按下通过串口打印按键2累计被按下的次数
    {
        Serial.printf("Button 2 has been pressed %u times\n", button2.KeyPresses_count);
        button2.Key_state = false;
    }
    static uint32_t lastMillis = 0;
    /*
      millis():用来获取Arduino开机后运行的时间长度,该时间长度单位是毫秒,
      最长可记录接近50天左右的时间。如果超出记录时间上限,记录将从0重新开始。
    */
    if (millis() - lastMillis > 10000)//
    {
      lastMillis = millis();
      detachInterrupt(button1.PIN);
    }
}
如有不对之处,欢迎大家指正 
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程先生w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值