ESP32 + ESP-IDF |GPIO 03 - 定时器轮询按钮的状态,控制LED亮或者灭

一、前言


前面两个章节使用了GPIO的输出功能,本章节介绍如何使用ESP32上GPIO的输入功能。

通过一个简单的实验来学习这个功能:

1、开启一个定时器(上一章节学习了),定时器以每100ms的周期来轮询gpio26的电平(按钮被按下 = 电平0,按钮没有被按下 = 电平1)。

2、当按钮被按下时,gpio27输出电平0,让led亮起来。当按钮没有被按下时,gpio27输出电平1,让led熄灭了。

实验视频:
在这里插入图片描述
ESP-IDF打印出来的信息:
在这里插入图片描述
这个实验的代码只是演示GPIO的输入功能,并不能用于实际项目上,在实际的项目上应该加上软件滤波的代码。

二、VSCODE + ESP-IDF


2.1、快速创建项目

按照第一章节的方式创建一个sample_project的模版。

2.2、选择串口通道,ESP芯片型号

还是按照第一章节的方式来选择串口通道与ESP芯片信号

三、电路


在这里插入图片描述
1、gpio26设置输出模式,当gpio26设置电平0时,led灯亮起来。反之,LED就熄灭了。
2、gpio27设置输入模式与设置上拉模式,当按钮按下时,gpio27被拉至电平0。反之,gpio27被内部电阻上拉至电平1。

四、代码


4.1、头文件

在这里插入图片描述
跟上一章节一样。

4.2、全局变量

在这里插入图片描述
增加一个变量buttom_state,用于保存按钮的状态。

4.3、app_main( )函数

在这里插入图片描述

扫描二维码关注公众号,回复: 14267451 查看本文章
  • 函数gpio_set_direction( )将gpio27设置为输入模式。
  • 函数gpio_set_pull_mode( )将gpio27设置为上拉模式。

4.4、定时器回调函数

在这里插入图片描述

  • 函数gpio_set_level( )获取gpio27的电平状态。

4.5、实验代码

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "esp_timer.h"

/* 定时器1回调函数 */
void timer1_Callback(void *arg);
/* 用于保存按钮的状态 */
uint16_t buttom_state = 0;  

static const char *TAG = "a buttom contorl a LED";
static esp_timer_handle_t timer1_handler;  /* 定时器1的句柄 */

/* 定时器1的参数 */
static esp_timer_create_args_t timer_Once_Obj = {
    
    
    .name = "Timer_NUM_1",          /* 定时器的名称 */
    .arg = NULL,                    /* 传递给回调函数的参数 */
    .callback = &timer1_Callback,   /* 回调函数 */
};

void app_main(void)
{
    
    
    ESP_LOGI(TAG, "Example configured to blink GPIO LED!");

    /* 复位GPIO的状态 */
    gpio_reset_pin(26);
    gpio_reset_pin(27);

    /* 设置GPIO27为输入模式 */
    gpio_set_direction(27,GPIO_MODE_INPUT);
    /* 设置GPIO27为上拉模式 */
    gpio_set_pull_mode(27,GPIO_PULLUP_ONLY);
    /* 设置GPIO26为输出模式 */
    gpio_set_direction(26,GPIO_MODE_OUTPUT);

    /* 初始化定时器 */
    esp_timer_init(); 

    /* 创建定时器1 */
    esp_timer_create(&timer_Once_Obj,&timer1_handler);

    /* 启动定时器1(周期性) */
    esp_timer_start_periodic(timer1_handler,100 * 1000);

    while(1)
    {
    
    
        vTaskDelay(300 / portTICK_PERIOD_MS);   /* 延时300ms */
    }

}

/* 定时器1回调函数 */
void timer1_Callback(void *arg)
{
    
    
    buttom_state = gpio_get_level(27);   /* 获取gpio的电平状态,gpio=0时,表示按钮被按下,gpio=1时,表示按钮没有被按下 */
    ESP_LOGI(TAG, "the state of buttom is %d",buttom_state);

    /* 如果按钮被按下,LED亮起来 */
    if(0 == buttom_state)
        gpio_set_level(26,0);
    /* 否则LED熄灭 */
    else
        gpio_set_level(26,1);    

}

五、相关API


5.1、gpio_set_direction( )

在这里插入图片描述

5.2、gpio_set_pull_mode( )

在这里插入图片描述

5.3、gpio_get_level( )

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wallace89/article/details/124071373