OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2020|回复: 2

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

[复制链接]

22

主题

271

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
405
金钱
405
注册时间
2019-3-21
在线时间
107 小时
发表于 2019-7-5 09:50:32 | 显示全部楼层 |阅读模式
长按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

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

22

主题

271

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
405
金钱
405
注册时间
2019-3-21
在线时间
107 小时
 楼主| 发表于 2019-7-5 09:51:21 | 显示全部楼层
刚学没多久,可能代码写的不是很好,但测试过的,可以使用
回复 支持 反对

使用道具 举报

37

主题

477

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
2285
金钱
2285
注册时间
2017-8-24
在线时间
375 小时
发表于 2019-7-5 12:58:26 | 显示全部楼层
天然懒,天然呆
能吃会睡,未来可期
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-11 08:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表