给大家分享一个按键程序,,,,,,,,,,,,,

2019-07-20 23:11发布

长按K2,led闪烁;松手再次长按,led熄灭;
双击K2,控制led亮灭


keyboard.c
#include "keyboard.h"
#include "led.h"
#include "LCD.h"
#include "HT1621B.h"

extern uint32_t tick1ms;
Key_Value k2_value;

/*K2按键短按标志位*/
bool k2_shortpress_happen = 0;
/*K2按键长按标志位*/
bool k2_longpress_happen = 0;
/*K2按键双击标志位*/
bool k2_doublepress_happen = 0;


/*led闪烁标志位,主函数检测到此标志位为1时,led闪烁,否则,led闪烁*/
bool led_flash_flag = 0;
/*led亮灭标志位,主函数检测到此标志位为1时,led点亮,否则,led熄灭*/
bool LED_FLASH_FLAG = 0;


/*1亮0灭*/
bool led_flag = 0;
/*1亮0灭*/
bool LED_FLAG = 0;

volatile unsigned int led_flash_timing = 0; /*led闪烁时间间隔*/
volatile unsigned int key_scan_timing = 0; /*按键轮询时间间隔*/
volatile unsigned int key_timing = 0;    /*按键按下时间,小于1.5S,按键为短按;时间大于1.5S,按键为长按*/
volatile unsigned int key_doublepress_timing = 0;  /*记录两次短按之间的时间间隔*/

void keyboard_init(void)     //PA1 --> K2
{
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);  
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOA,&GPIO_InitStructure);
}

/*按键键值扫描函数*/
void keyboard_Scan(void)
{
/*当K2按键按下*/
  if(K2==0)         
  {
    if(k2_shortpress_happen==0)
    {
      k2_shortpress_happen = 1;    //开始一次按键键值扫描
      key_timing = 0;             //按键按下计时变量清0,开始计时,此值每1ms加1;
    }

    if(k2_shortpress_happen==1)
    {
      if(key_timing > 1500)          //按键按下时间大于1.5S,表示长按
      {
        k2_value.long_press = 1;
        k2_shortpress_happen = 0;    //按键短按标志位置0
      }
    }
  }

/*当K2按键抬起*/
  if(K2==1)
  {
    if(k2_shortpress_happen==1)   //按键抬起后,k1_shortpress_happen等于1,说明按键为短按
    {
      k2_shortpress_happen = 0;
      if(k2_doublepress_happen==0)
      {
        k2_doublepress_happen = 1;    //按键双击标志位置1,等待确认按键是否为双击
        key_doublepress_timing = 0;  //开始计时,1ms加1
      }
      else
      {
        if(key_doublepress_timing < 500)  //第一次短按后,在500ms内发生第二次短按,表示双击
        {
          k2_doublepress_happen = 0;
          k2_value.double_press = 1;   
        }
      }
    }
    else
      if(k2_doublepress_happen == 1)
      {
        if(key_doublepress_timing > 500)  //第一次短按后,在500ms内未发生第二次短按,表示短按
        {
          k2_doublepress_happen = 0;
          k2_value.short_press = 1;
        }
      }
      else
        if(k2_longpress_happen==1)
        {
          k2_longpress_happen = 0;
        }
  }
}

/*按键事件处理函数, 根据键值进行相应的事件处理*/
void keyboard_Func(void)
{
              /*短按*/
  if(k2_value.short_press == 1)
  {
    k2_value.short_press = 0;
    //
  }

             /*长按*/
  if(k2_value.long_press == 1)
  {
    k2_value.long_press = 0;
    led_flash_flag = !led_flash_flag;
  }

            /*双击*/
  if(k2_value.double_press == 1)
  {
    k2_value.double_press = 0;
    LED_FLASH_FLAG = !LED_FLASH_FLAG;
  }
}

/******短按K2,*******
*******长按K2,LED闪烁********
*******双击K2,LED灯自行控制亮灭*/
void keyboard_Run(void)
{
  if(tick1ms - key_scan_timing > 10)   //10ms扫描一次键盘
  {
    key_scan_timing = tick1ms;
    keyboard_Scan();
    keyboard_Func();
  }

  if(LED_FLASH_FLAG==1)   //双击控制led亮灭
  {
    LED_FLAG = !LED_FLAG;

    if(LED_FLAG==1)
    {
      LED_ON();
    }
    else
    {
      LED_OFF();
    }
  }


  if(tick1ms - led_flash_timing > 250)    //长按led闪烁
  {
    led_flash_timing = tick1ms;
    if(led_flash_flag==1)
    {
      led_flag = !led_flag;

      if(led_flag==1)
      {
        LED_ON();
      }
      else
      {
        LED_OFF();
      }
    }

    else    //当没有按键事件需要处理时,熄灭led灯
    {
      LED_OFF();
    }
  }
}



keyboard.h
#ifndef __keyboard_h_
#define __keyboard_h_

#include "stm32f0xx.h"
#include "base.h"

#define K2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)

void keyboard_init(void);
void keyboard_Scan(void);
void keyboard_Func(void);
void keyboard_Run(void);

typedef struct Key
{
  bool short_press;      //短按
  bool long_press;      //长按
  bool double_press;    //双击
}Key_Value;
extern Key_Value k2_value;;

#endif

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。