gd32 按键扫描

主控芯片:GD32F303CBT6

1、按键扫描结构体

首先定义一个结构体

typedef struct 
{ 
  u32 gpio_periph;
  u32 pin;
  u8  Last_Status;   //上个工作模式
  u8  Key_Status;    //工作模式 
  u8  Key_Down_OK;   //按下
  u8  Key_Long_Up;   //松开
  u8  Key_Single_Up; //松开过
  u8  Key_Press_Type; //按键类型,短按、长按
  u8  Key_Single_Cnt;  //连续单击计数  
  u16 Key_Single_TimeSet; //短按时间阈值
  u16 Key_Long_TimeSet;   //长按时间阈值
  u16 Key_SP_Long_TimeSet;//更长时间阈值
  u16 Key_SP2_Long_TimeSet;//更长时间阈值  
  u32 KFilter;	//按下计数
  u32 UP_KFilter;	//松开计数 
}Button_Scan_Class;
extern Button_Scan_Class   IOT_Switch; //按键

 2、按键初始化

void Button_Scan_Init_Config(void)
{ 
    memset(&IOT_Switch, 0 ,sizeof(IOT_Switch));

    //按键时间阈值设定 IOT
    IOT_Switch.Key_Single_TimeSet  = KEY_50MS_TIME_SET; 
    IOT_Switch.Key_Long_TimeSet    = KEY_2S_TIME_SET;
    IOT_Switch.Key_SP_Long_TimeSet = KEY_5S_TIME_SET;
    IOT_Switch.Key_Status = Standby_status;

    //按键引脚定义   
    IOT_Switch.gpio_periph = KEY_GPIO;
    IOT_Switch.pin = KEY_GPIO_PIN;
       
    rcu_periph_clock_enable(RCU_GPIOB); 
    gpio_init(KEY_GPIO,   GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, KEY_GPIO_PIN);    //RESET  

}

按键设定的阈值时间,由自己定义需要多长。这里定义为短按50毫秒,长按2秒,长按5秒。

3、按键扫描函数

void  Button_Scan_State(Button_Scan_Class* Str_Key, u8* beep_status)
{
	if(RESET==gpio_input_bit_get(Str_Key->gpio_periph,Str_Key->pin)) //判断是否按下
	{
        if(Str_Key->Key_Single_Up ==1) 
        {
            Str_Key->Key_Single_Up =0;
            Str_Key->KFilter=0;
        }
			  if(Str_Key->KFilter++>2 && Str_Key->UP_KFilter >= 3) //按下开始计数
        {
            Str_Key->Key_Down_OK = 1;  // 按键按下标志位
					  Str_Key->UP_KFilter = 0;
        }
        //Str_Key->Key_Long_Up = 0;
		}
	else if(Str_Key->Key_Down_OK == 1) //确认按下按键
	{		
        Str_Key->Key_Single_Up =1;      
        if(Str_Key->UP_KFilter == 0) Str_Key->Key_Single_Cnt++;     
        if(Str_Key->UP_KFilter < 50) Str_Key->UP_KFilter++;
        else Str_Key->Key_Long_Up = 1; 
	}
    else
    {
        Str_Key->KFilter = 0;
	    if(Str_Key->UP_KFilter < 50) Str_Key->UP_KFilter++;
    }

	 if(Str_Key->Key_Long_Up==1)
	 {
       if(Str_Key->KFilter > Str_Key->Key_SP_Long_TimeSet)//5S长按
       {
           Str_Key->Key_Press_Type  = KEY_SP_LONG_MODE; 
       }
       else if(Str_Key->KFilter > Str_Key->Key_Long_TimeSet) //2S长按
       {
           Str_Key->Key_Press_Type  = KEY_LONG_MODE;
       }
       else if(Str_Key->KFilter > Str_Key->Key_Single_TimeSet) //短按
       {
           if(Str_Key->Key_Single_Cnt==1) Str_Key->Key_Press_Type  = KEY_Single_MODE; 
       }
       Str_Key->Key_Single_Cnt=0;
       Str_Key->KFilter     = 0;
       Str_Key->Key_Long_Up = 0;
       Str_Key->Key_Down_OK = 0;
	 }
	 else if(Str_Key->Key_Down_OK) //长按按键未松开需要蜂鸣器报警
	 {
       if(Str_Key->KFilter == Str_Key->Key_SP_Long_TimeSet)//5S长按
       {
           *beep_status  = KEY_SP_LONG_MODE;
       }
       else if(Str_Key->KFilter == Str_Key->Key_Long_TimeSet) //2S长按
       {
           *beep_status  = KEY_LONG_MODE;
       }
       else if(Str_Key->KFilter == Str_Key->Key_Single_TimeSet) //短按
       {
			*beep_status  = KEY_Single_MODE;
	    }
	 }

}

按键扫描函数大体分为两部分,一部分是是否按下按键的判断, 一部分是按键时间的判断。

按键时间超过2秒,5秒,给蜂鸣器一个事件标志位,用蜂鸣器的声响来判断目前是否按了2秒或者5秒。

4、按键处理函数

u32 Button_Scan_Status(void)
{
    u32 key_status=0;
    u8 beep_status=0;
    Button_Scan_State(&IOT_Switch,&beep_status);


    if(IOT_Switch.Key_Press_Type ==KEY_Single_MODE)       key_status |=IOT_Single_EVENT;
    else if(IOT_Switch.Key_Press_Type ==KEY_LONG_MODE)    key_status |=IOT_LONG_EVENT;
    else if(IOT_Switch.Key_Press_Type ==KEY_SP_LONG_MODE) key_status |=IOT_SP_LONG_EVENT; 

    if(beep_status ==KEY_Single_MODE)           key_status |=BEEP_ON_EVENT1; //蜂鸣器1声
    else if(beep_status ==KEY_LONG_MODE)        key_status |=BEEP_ON_EVENT2; //蜂鸣器2声
    else if(beep_status ==KEY_SP_LONG_MODE)     key_status |=BEEP_ON_EVENT3; //蜂鸣器3声

    
    //清除按键标志位
    IOT_Switch.Key_Press_Type =0;
    
    return key_status;
}

在按键处理函数中,对刚才的按键时间标志位和蜂鸣器标志位做出判断。之后返回让上层应用进行处理。

5、按键执行函数

void Button_Iot_Handle(u32 key_mode)
{   
    if((key_mode & IOT_Single_EVENT) == IOT_Single_EVENT)
    {
		printf("key single\r\n");
    }
    else if((key_mode & IOT_LONG_EVENT)  == IOT_LONG_EVENT)
    {  
        printf("key long\r\n");
    } 
    else if((key_mode & IOT_SP_LONG_EVENT)  == IOT_SP_LONG_EVENT)
    {
        printf("key sp long\r\n");

    } 
}

 此处key_mode为上一步按键处理函数所返回的值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一叶舞澎湃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值