【RP2040】香瓜树莓派RP2040之自定义的短按、双击、长按按键

本文最后修改时间:2022年09月15日 11:02

一、本节简介

本节介绍如何编写一个可以自己选择引脚的短按、双击、长按三种方式的按键驱动。

二、实验平台

1、硬件平台

1)树莓派pico开发板

①树莓派pico开发板*2

②micro usb数据线*2

2)电脑

2、软件平台

1)VS CODE

三、版权声明

1)作者:甜甜的大香瓜

2)声明:喝水不忘挖井人,转载请注明出处。

3)纠错/业务合作:[email protected]

4)香瓜嵌入式之树莓派群:512598061

5)本文出处:原创连载资料《简单粗暴学树莓派》

6)完整开源资料下载地址(电脑端打开):

opengua.taobao.com

四、实验前提

1、在进行本文步骤前,请先阅读以下章节:

1)《简单粗暴学树莓派》的“第一章至第二章”章节

2、在进行本文步骤前,请先实现以下章节:

1)《简单粗暴学树莓派》的《香瓜树莓派pico之新建工程》章节。

五、硬件原理图

【RP2040】香瓜树莓派RP2040之自定义的短按、双击、长按按键_第1张图片

 

【RP2040】香瓜树莓派RP2040之自定义的短按、双击、长按按键_第2张图片

也就是:。

引脚号

功能

状态变化

17

按键

按键按下之前是高电平,按下之后是低电平

六、实验步骤

1、在VS CODE工程的GUA_CODE文件夹下,添加驱动GUA_Key.c

//**********************************************************************

//name:         GUA_Key.c

//author:       opengua   

//changetime:   2022.09.06

//**********************************************************************

#include "pico/stdlib.h"

#include "GUA_Key.h"

/*********************macro definition************************/

//trigger level

#define GUA_KEY_TRIGGER                         0                                

//removing jitter

#define GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT   (40000)     //10ms     

#define GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT    (40000*250) //2.5s     

#define GUA_KEY_SHORT_INTERVAL                  (10000000)  //1s

#define GUA_KEY_GET_VALUE                       gpio_get(GUA_KEY_PIN)

/*********************Internal variables************************/ 

static uint32_t sGUA_Key_DisappearsShakes_TriggerCount = 0;              //count value

//**********************************************************************

//name:         GUA_Key_Scan

//parameter:    none

//return:       GUA_KEY_STATUS_IDLE or

//              GUA_KEY_STATUS_TRIGGER_SHORT or

//              GUA_KEY_STATUS_TRIGGER_LONG or

//              GUA_KEY_STATUS_NO_LOOSEN

//author:       opengua   

//changetime:   2022.09.06

//**********************************************************************

uint8_t GUA_Key_Scan(void)     

{      

  uint32_t nGUA_TimeOut = 0;   

  

  //TRIGGER

  if(GUA_KEY_GET_VALUE == GUA_KEY_TRIGGER)  

  { 

    //If the last key was a long key end, the release must be detected before the next count can begin

    if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)

    {

      return GUA_KEY_STATUS_NO_LOOSEN;

    }

    //count

    sGUA_Key_DisappearsShakes_TriggerCount++;   

   

    //Determine if the count is sufficient

    while(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT) 

    { 

      //When a release or timeout is detected, it is processed

      if((GUA_KEY_GET_VALUE != GUA_KEY_TRIGGER) || (sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)) 

      { 

        //long press 2.5S

        if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT) 

        {           

          return GUA_KEY_STATUS_TRIGGER_LONG;                          

        }                

        //short press

        else 

        {      

          //The timeout count is cleared to zero

          nGUA_TimeOut = 0;

           

          //Check whether there is a connection

          while((GUA_KEY_GET_VALUE != GUA_KEY_TRIGGER))

          {       

            //If the button is not pressed and times out, it indicates that there is only one button

            if(nGUA_TimeOut++ > GUA_KEY_SHORT_INTERVAL)

            {

              //The count is cleared to zero

              sGUA_Key_DisappearsShakes_TriggerCount = 0;

             

              return GUA_KEY_STATUS_TRIGGER_SHORT;

            }                    

          }

         

          //Determine if the count is sufficient

          while(GUA_KEY_GET_VALUE == GUA_KEY_TRIGGER)

          {

            //Start counting

            sGUA_Key_DisappearsShakes_TriggerCount++;

            //When a release or timeout is detected, it is processed

            if((GUA_KEY_GET_VALUE != GUA_KEY_TRIGGER) || (sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)) 

            {             

              //when long press 2.5S

              if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT) 

              {           

                //Clear up counter

                sGUA_Key_DisappearsShakes_TriggerCount = 0;

                return GUA_KEY_STATUS_TRIGGER_LONG;                          

              }                

              //when short press

              else 

              {   

                //Clear up counter

                sGUA_Key_DisappearsShakes_TriggerCount = 0;

               

                return GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT;                 

              } 

            }                         

          }

         

          //Clear up counter

          sGUA_Key_DisappearsShakes_TriggerCount = 0;

               

          return GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT;         

        } 

      } 

     

      //Continue counting to determine the length of the button

      sGUA_Key_DisappearsShakes_TriggerCount++;         

    }    

  } 

  //no press

  else 

  { 

    sGUA_Key_DisappearsShakes_TriggerCount = 0;  

  } 

   

  return GUA_KEY_STATUS_IDLE;   

}  

//**********************************************************************

//name:         GUA_Key_Init

//parameter:    none

//return:       none

//author:       opengua   

//changetime:   2022.09.06

//**********************************************************************

void GUA_Key_Init(void)

{

  gpio_init(GUA_KEY_PIN);

  gpio_set_dir(GUA_KEY_PIN, GPIO_IN);

  gpio_pull_up(GUA_KEY_PIN);

}

2、在VS CODE工程的GUA_CODE文件夹下,添加驱动头文件GUA_Key.h

//**********************************************************************

//name:         GUA_Key.h

//author:       opengua   

//changetime:   2022.09.06

//**********************************************************************

#ifndef _GUA_KEY_H_

#define _GUA_KEY_H_

/*********************macro definition************************/

#define GUA_KEY_PIN                             17      //key pin

//trigger transitions 

#define GUA_KEY_STATUS_IDLE                     0       //no press

#define GUA_KEY_STATUS_TRIGGER_SHORT            1       //short press

#define GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT     2       //double press

#define GUA_KEY_STATUS_TRIGGER_LONG             3       //long press 2.5S

#define GUA_KEY_STATUS_NO_LOOSEN                4       //no loosen

/*********************external function************************/

uint8_t GUA_Key_Scan(void); 

void GUA_Key_Init(void);

#endif

3、将新写的驱动文件新添加到可执行

【RP2040】香瓜树莓派RP2040之自定义的短按、双击、长按按键_第3张图片

4、修改main.c

//**********************************************************************

//name:         main.c

//author:       opengua   

//changetime:   2022.09.06

//**********************************************************************

#include "pico/stdlib.h"

#include "GUA_Led.h"

#include "GUA_Key.h"

/*********************Internal variables************************/

/*********************Internal function************************/

static void GUA_Init(void);

//**********************************************************************

//name:         GUA_Init

//parameter:    none

//return:       none

//author:       opengua   

//changetime:   2022.09.06

//**********************************************************************

static void GUA_Init(void)

{

    //LED

    GUA_Led_Init();

    GUA_Led_Set(GUA_LED_SET_LOW);

    //KEY

    GUA_Key_Init();

}

//**********************************************************************

//name:         main

//parameter:    none

//return:       none

//author:       opengua   

//changetime:   2022.09.06

//**********************************************************************

void main(void)

{

      uint8_t nGUA_Ret;

    GUA_Init();

    while(1)

    {

           //key scan

           nGUA_Ret = GUA_Key_Scan();

                           

           //If a button is pressed, deal with it

           if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_SHORT)

           {   

                 GUA_Led_Set(GUA_LED_SET_HIGH);       

                 sleep_ms(100);

                 GUA_Led_Set(GUA_LED_SET_LOW);

                 sleep_ms(100);                        

           }

           else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT)

           {   

                 GUA_Led_Set(GUA_LED_SET_HIGH);       

                 sleep_ms(100);

                 GUA_Led_Set(GUA_LED_SET_LOW);

                 sleep_ms(100);  

                 GUA_Led_Set(GUA_LED_SET_HIGH);       

                 sleep_ms(100);

                 GUA_Led_Set(GUA_LED_SET_LOW);

                 sleep_ms(100);                                               

           }

           else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_LONG)

           {   

                 GUA_Led_Set(GUA_LED_SET_HIGH);       

                 sleep_ms(100);

                 GUA_Led_Set(GUA_LED_SET_LOW);

                 sleep_ms(100);  

                 GUA_Led_Set(GUA_LED_SET_HIGH);       

                 sleep_ms(100);

                 GUA_Led_Set(GUA_LED_SET_LOW);

                 sleep_ms(100);       

                 GUA_Led_Set(GUA_LED_SET_HIGH);       

                 sleep_ms(100);

                 GUA_Led_Set(GUA_LED_SET_LOW);

                 sleep_ms(100);                                         

           }                                

    }

}

七、实验结果

编译并仿真,设置断点分别在按键的三种情况(短按、双击、长按),

1、当短按0~3秒内1次,会被识别为短按。

2、当短按后在1秒内再次短按,则会被识别为双击。

3、当长按3秒以上(即使不松开)也会被识别为长按。

因此,实验成功。

 

 

你可能感兴趣的:(树莓派RP2040,单片机)