esp32开发板按钮程序入门

一、功能实现:

1、修改宏定义中按钮的位置。

2、在main函数里将按钮初始化。

3、修改自定义函数内容。

二、完整代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "lvgl_init.h"

#define GPIO_OUTPUT_IO_LED2    15
#define GPIO_OUTPUT_IO_LED3    2
#define GPIO_OUTPUT_IO_LED4    4
#define GPIO_OUTPUT_IO_BEEP    19
#define GPIO_OUTPUT_PIN_SEL  ((1ULL<<GPIO_OUTPUT_IO_LED2) | (1ULL<<GPIO_OUTPUT_IO_LED3) | (1ULL<<GPIO_OUTPUT_IO_LED4)| (1ULL<<GPIO_OUTPUT_IO_BEEP))

#define GPIO_INPUT_IO_SW3     37
#define GPIO_INPUT_IO_SW4     38
#define GPIO_INPUT_IO_SW5     39

#define GPIO_INPUT_PIN_SEL  ((1ULL<<GPIO_INPUT_IO_SW3) | (1ULL<<GPIO_INPUT_IO_SW4)| (1ULL<<GPIO_INPUT_IO_SW5))

#include "driver/adc.h"
#include "esp_adc_cal.h"
#include "time.h"
#include "sys/time.h"
#include "sys/unistd.h"
#include <sys/time.h>


long CurrentTime=0;
void UpdateCurrentTime(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
CurrentTime=tv.tv_sec*1000+tv.tv_usec/1000;
}

int display1=0;
int display2=0;
int display3=0;
int display4=0;
int display5=0;
int display6=0;
int display7=0;
int display8=0;
int display9=0;



typedef unsigned char u8;
typedef unsigned short u16;

#define KEY_NUM       5
#define GPIO_KEY1     14
#define GPIO_KEY2     12
#define GPIO_KEY3     0
#define GPIO_KEYEXT   19
#define GPIO_KEYEXT2   5

#define GPIO_INPUT_HW_PIN_SEL  ((1ULL<<GPIO_KEY1) | (1ULL<<GPIO_KEY2)| (1ULL<<GPIO_KEY3)| (1ULL<<GPIO_KEYEXT)| (1ULL<<GPIO_KEYEXT2))




void HardwareInit(void);
void HandleKey(void);



void OnKey1Presseds(void)
{
    display1++;
    printf("key1presseds:%d\n",display1);
    sleep(0.5);

}

void OnKey1Pressedl(void)
{
   display2++;
   printf("key1pressedl:%d\n",display2);
    
}

void OnKey1Released(void)
{
    display3++;
    printf("Key1Released:%d\n",display3);
    
}

void OnKey2Presseds(void)
{
    display4++;
    printf("key2presseds:%d\n",display4);
    sleep(0.5);
}

void OnKey2Pressedl(void)
{
    display5++;
    printf("key2pressedl:%d\n",display5);
    
}

void OnKey2Released(void)
{
    display6++;
    printf("Key2Released:%d\n",display6);
    
}

void OnKey3Presseds(void)
{
    display7++;
    printf("key3presseds:%d\n",display7);
    sleep(0.5);
}

void OnKey3Pressedl(void)
{
    display8++;
    printf("key3pressedl:%d\n",display8);
   
}

void OnKey3Released(void)
{
    display9++;
    printf("Key3Released:%d\n",display9);
    
    
}


void OnKeyEXTPresseds(void)
{
    
}

void OnKeyEXTPressedl(void)
{
    
}

void OnKeyEXTReleased(void)
{
    
}
void OnKeyEXT2Presseds(void)
{
    
}
void OnKeyEXT2Pressedl(void)
{
    
}
void OnKeyEXT2Released(void)
{
    
}

gpio_num_t KeyPinNum[]={GPIO_KEY1,GPIO_KEY2,GPIO_KEY3,GPIO_KEYEXT,GPIO_KEYEXT2,};

void (*pOnKeyPressedS[])(void)={OnKey1Presseds,OnKey2Presseds,OnKey3Presseds,OnKeyEXTPresseds,OnKeyEXT2Presseds};
void (*pOnKeyPressedL[])(void)={OnKey1Pressedl,OnKey2Pressedl,OnKey3Pressedl,OnKeyEXTPressedl,OnKeyEXT2Pressedl};
void (*pOnKeyReleased[])(void)={OnKey1Released,OnKey2Released,OnKey3Released,OnKeyEXTReleased,OnKeyEXT2Released};

u8 KeyPressed[]={0,0,0,0,0};
long KeyLastPressedTime[]={0,0,0,0,0};
long KeyLastReleasedTime[]={0,0,0,0,0};
u8 isSendKeyLongPressedEvent[]={0,0,0,0,0};

void HandleKey(void)
{
  for(u8 i=0;i<KEY_NUM;i++)
  {
    if(KeyPressed[i])
    {
      //已经按下
      if(CurrentTime-KeyLastPressedTime[i]>50)
      {
        //按下超过50ms
        if(gpio_get_level(KeyPinNum[i]))
        {
          //松开
          if(!isSendKeyLongPressedEvent[i])
          {
            if(pOnKeyReleased[i])
            {
              pOnKeyReleased[i]();
            }

          }
          KeyPressed[i]=0;
          KeyLastReleasedTime[i]=CurrentTime;
        }
        else
        {
          //未松开
          if(CurrentTime-KeyLastPressedTime[i]>1000)
          {
            //超过1000ms
            if(!isSendKeyLongPressedEvent[i])
            {
              //没有触发过长按则触发长按
              isSendKeyLongPressedEvent[i]=1;
              if(pOnKeyPressedL[i])
              {
                pOnKeyPressedL[i]();
              }
            }
          }
        }
      }
    } else
    {
      //未按下
      if( !gpio_get_level(KeyPinNum[i])&&(CurrentTime-KeyLastReleasedTime[i]>200))
      {
        //首次按下
               KeyPressed[i]=1;
            KeyLastPressedTime[i]=CurrentTime;
             isSendKeyLongPressedEvent[i]=0;
             if(pOnKeyPressedS[i])
             {
               pOnKeyPressedS[i]();
             }

      }
    }
  }//for
}

void HardwareInit(void)
{
    //1.IO
    gpio_config_t io_conf;

    //disable interrupt
    io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
    //bit mask of the pins, use GPIO4/5 here
    io_conf.pin_bit_mask = GPIO_INPUT_HW_PIN_SEL;
    //set as input mode
    io_conf.mode = GPIO_MODE_INPUT;
    //enable pull-up mode
    io_conf.pull_up_en = 1;
    gpio_config(&io_conf);

}
void TaskReadSW1(void *arg)
{
  uint32_t io_num;
  while (1)
  {
    vTaskDelay(10 / portTICK_RATE_MS);
  }
}

void app_main(){
  HardwareInit();
  xTaskCreate(TaskReadSW1, "TaskReadSW1", 2048, NULL, 10, NULL);
  while(1){
    
    HandleKey();
    UpdateCurrentTime();
    

    
    vTaskDelay(100/ portTICK_PERIOD_MS);
    
  }
  
}

三、代码解析

1、宏定义按钮在芯片上的位置,笔者的按钮在开发板位置是14、12、0。读者请根据自己按钮在芯片上的位置修改。

#define GPIO_KEY1     14
#define GPIO_KEY2     12
#define GPIO_KEY3     0

2、修改按钮的三个状态函数,根据自己需要修改函数,例如笔者的代码为每次实现一次按钮函数,则display++并且printf打印,因此可直观看出该自定义函数是否运行。

void OnKey1Presseds(void)
{
    display1++;
    printf("key1presseds:%d\n",display1);
    sleep(0.5);

}

void OnKey1Pressedl(void)
{
   display2++;
   printf("key1pressedl:%d\n",display2);
    
}

void OnKey1Released(void)
{
    display3++;
    printf("Key1Released:%d\n",display3);
    
}

void OnKey2Presseds(void)
{
    display4++;
    printf("key2presseds:%d\n",display4);
    sleep(0.5);
}

void OnKey2Pressedl(void)
{
    display5++;
    printf("key2pressedl:%d\n",display5);
    
}

void OnKey2Released(void)
{
    display6++;
    printf("Key2Released:%d\n",display6);
    
}

void OnKey3Presseds(void)
{
    display7++;
    printf("key3presseds:%d\n",display7);
    sleep(0.5);
}

void OnKey3Pressedl(void)
{
    display8++;
    printf("key3pressedl:%d\n",display8);
   
}

void OnKey3Released(void)
{
    display9++;
    printf("Key3Released:%d\n",display9);
    
    
}


void OnKeyEXTPresseds(void)
{
    
}

void OnKeyEXTPressedl(void)
{
    
}

void OnKeyEXTReleased(void)
{
    
}
void OnKeyEXT2Presseds(void)
{
    
}
void OnKeyEXT2Pressedl(void)
{
    
}
void OnKeyEXT2Released(void)
{
    
}

3、按钮的初始化与处理。在理解了该代码之后可知若实现短按必然实现释放,若想要实现长按则必然提前实现短按,因此如果只是一个按键的处理则只需要修改该按钮的短按函数,若一个按键想要实现两个功能则要修改该按钮的长按与释放函数。

void HandleKey(void)
{
  for(u8 i=0;i<KEY_NUM;i++)
  {
    if(KeyPressed[i])
    {
      //已经按下
      if(CurrentTime-KeyLastPressedTime[i]>50)
      {
        //按下超过50ms
        if(gpio_get_level(KeyPinNum[i]))
        {
          //松开
          if(!isSendKeyLongPressedEvent[i])
          {
            if(pOnKeyReleased[i])
            {
              pOnKeyReleased[i]();
            }

          }
          KeyPressed[i]=0;
          KeyLastReleasedTime[i]=CurrentTime;
        }
        else
        {
          //未松开
          if(CurrentTime-KeyLastPressedTime[i]>1000)
          {
            //超过1000ms
            if(!isSendKeyLongPressedEvent[i])
            {
              //没有触发过长按则触发长按
              isSendKeyLongPressedEvent[i]=1;
              if(pOnKeyPressedL[i])
              {
                pOnKeyPressedL[i]();
              }
            }
          }
        }
      }
    } else
    {
      //未按下
      if( !gpio_get_level(KeyPinNum[i])&&(CurrentTime-KeyLastReleasedTime[i]>200))
      {
        //首次按下
               KeyPressed[i]=1;
            KeyLastPressedTime[i]=CurrentTime;
             isSendKeyLongPressedEvent[i]=0;
             if(pOnKeyPressedS[i])
             {
               pOnKeyPressedS[i]();
             }

      }
    }
  }//for
}

void HardwareInit(void)
{
    //1.IO
    gpio_config_t io_conf;

    //disable interrupt
    io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
    //bit mask of the pins, use GPIO4/5 here
    io_conf.pin_bit_mask = GPIO_INPUT_HW_PIN_SEL;
    //set as input mode
    io_conf.mode = GPIO_MODE_INPUT;
    //enable pull-up mode
    io_conf.pull_up_en = 1;
    gpio_config(&io_conf);

}

4、时间更新函数

long CurrentTime=0;
void UpdateCurrentTime(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
CurrentTime=tv.tv_sec*1000+tv.tv_usec/1000;
}

5、最简单的main函数:将按钮初始化之后,在while(1)循环里,反复实现HandleKey()函数,因此只要按钮按下,便会打印出相对应的按钮的变量的增加。

void app_main(){
  HardwareInit();
  xTaskCreate(TaskReadSW1, "TaskReadSW1", 2048, NULL, 10, NULL);
  while(1){
    
    HandleKey();
    UpdateCurrentTime();
    

    
    vTaskDelay(100/ portTICK_PERIOD_MS);
    
  }
  
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值