蓝桥杯嵌入式按键(单击、长按、双击)

配置成上拉模式

开启tim4的定时器和中断,配置成10ms方便消抖

开启中断

配置完成

代码部分:

单击:

key.c

#include "key.h"


struct keys key[4] = {0,0,0};
uchar i;
uchar time_flag;
uint time_count;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM4)
    {
        key[0].key_flag = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
        key[1].key_flag = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
        key[2].key_flag = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
        key[3].key_flag = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
        
        for(i=0;i<4;i++)
        {
            switch (key[i].key_count)
            {
                case 0:
                    if(key[i].key_flag == 0)
                    {
                        key[i].key_count = 1;
                    }
                
                break;
        
                case 1:
                    if(key[i].key_flag == 0)
                    {
                        key[i].key_count = 2;
                    }
                    else
                    {
                        key[i].key_count = 0;
                    }
                break;
                
                case 2:
                    if(key[i].key_flag == 1)
                    {
                        key[i].key_count = 0;
                        key[i].key_zhi = 1;
                    }
                break;
            }
        }
        
        if(time_flag == 1)
        {
            time_count++;
        }
    }
}

key.h

#ifndef _KEY_H_
#define _KEY_H_

#include "main.h"
#include "stdbool.h"

struct keys
{
    uchar key_count;
    bool key_flag;
    bool key_zhi;
};

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

#endif

main.c

extern struct keys key[];    //声明结构体

HAL_TIM_Base_Start_IT(&htim4);  //初始化开启定时器

key_porc函数:


void key_porc(void)
{
    if(key[0].key_zhi == 1)   //B1
    {
      
        
        key[0].key_zhi = 0;
    }
    
    if(key[1].key_zhi == 1)    //B2
    {
       

        key[1].key_zhi = 0;
    }
    
    if(key[2].key_zhi == 1)    //B3
    {


        key[2].key_zhi = 0;
    }
    
    if(key[3].key_zhi == 1)    //B4
    {
   


        key[3].key_zhi = 0;
    }

}

单击+长按

key.c

#include "key.h"

struct keys key[4]={0,0,0};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM4)
    {
        key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
        key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
        key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
        key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
        
        for(int i=0;i<4;i++)
        {
            switch (key[i].judge_sta)
            {
                case 0:
                {
                    if(key[i].key_sta==0) 
                    {
                        key[i].judge_sta=1;
                        key[i].key_time=0;
                    }
                }
                break;
                case 1:
                {
                    if(key[i].key_sta==0)
                    {
                        key[i].judge_sta=2;
                    }
                    else key[i].judge_sta=0;
                }
                break;
                case 2:
                {
                    if(key[i].key_sta==1)
                    {
                        key[i].judge_sta=0;                    
                        if(key[i].key_time<70)
                        {
                            key[i].single_flag=1;
                        }
                    }
                    else 
                    {
                        key[i].key_time++;
                        if(key[i].key_time>70)  key[i].long_flag=1;
                    }
                }
                break;
                
            }
        
        }
    }
}


key.h



#ifndef _INTERRUPT_H_
#define _INTERRUPT_H_

#include "main.h"
#include "stdbool.h"

void HAL_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

struct keys
{
    uchar judge_sta;
    bool key_sta;
    bool single_flag;
    bool long_flag;
    uint key_time;
};



#endif

单击+长按+双击

key.c


#include "key.h"

uchar judge_state[4]={0},double_click_time[4]={0},key_state[4]={0},double_click_timerEN[4]={0},
single_key_flag[4]={100},double_key_flag[4]={0},long_key_flag[4]={0};
uint key_time[4]={0};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//回调函数
{
    if(htim->Instance==TIM3)//定时器3的事件
    {
        key_state[0]=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
        key_state[1]=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
        key_state[2]=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
        key_state[3]=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
        for(int i=0;i<4;i++)
        {
            switch (judge_state[i])
            {
                case 0:
                {
                    if(key_state[i]==0)//按键按下
                    {
                    judge_state[i]=1;
                    key_time[i]=0;
                    }
                break;
                }
                case 1://消抖过程
                {
                    if(key_state[i]==0)
                    {
                    judge_state[i]=2;
                    }
                    else judge_state[i]=0;//未按下
                break;
                }
                case 2:
                {
                    if((key_state[i]==1)&&key_time[i]<70)//等待松开过程,且非长按键
                    {
                        if(double_click_timerEN[i]==0) //可能双击按键的第一次,进入计时
                        {
                        double_click_timerEN[i]=1;
                        double_click_time[i]=0;
                        }
                        else //在计时范围内又按了一次
                        {
                        double_key_flag[i]=1;//双击情况
                        double_click_timerEN[i]=0;
                        }
                        judge_state[i]=0;
                    }
                    else if(key_state[i]==1&&key_time[i]>=70) judge_state[i]=0;//松开且是长按键
                    else 
                    {
                    if (key_time[i]>=70)long_key_flag[i]=1;//长按键
                    key_time[i]++;//长按键计时?还没松开
                    }
                break;
                }
            }
            if(double_click_timerEN[i]==1)//延时确认是否双击
            {
                double_click_time[i]++;
                if(double_click_time[i]>=35) 
                {
                single_key_flag[i]=1;//按键1单次按下
                double_click_timerEN[i]=0;
                }
            }
        }
    }
}

main.c
extern uchar single_key_flag[4],long_key_flag[4],double_key_flag[4];

key.h



#ifndef _INTERRUPT_H_
#define _INTERRUPT_H_

#include "main.h"
#include "stdbool.h"

void HAL_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

struct keys
{
    uchar judge_sta;
    bool key_sta;
    bool single_flag;
    bool long_flag;
    uint key_time;
};



#endif

key_porc函数


         if(single_key_flag[0]==1)//1被单次按下
        {
          
            
            single_key_flag[0]=0;//用完标记
        }

        if(long_key_flag[0]==1)//700ms长按键
        {

            long_key_flag[0]=0;
        }

        if(double_key_flag[0]==1)//双击判断
        {
         
            double_key_flag[0]=0;
        }

        if(single_key_flag[1]==1)//2被单次按下
        {
         
            single_key_flag[1]=0;//用完标记
        }

        if(long_key_flag[1]==1)//700ms长按键
        {
        
            long_key_flag[1]=0;
        }

        if(double_key_flag[1]==1)//双击判断
        {
          
            double_key_flag[1]=0;
        }

        if(single_key_flag[2]==1)//3被单次按下
        {
          

            single_key_flag[2]=0;//用完标记
        }

        if(long_key_flag[2]==1)//700ms长按键
        {

            long_key_flag[2]=0;
        }


        if(double_key_flag[2]==1)//双击判断
        {
          
            double_key_flag[2]=0;
        }


        if(single_key_flag[3]==1)//4被单次按下
        {
           

            single_key_flag[3]=0;//用完标记
        }

        if(long_key_flag[3]==1)//700ms长按键
        {
         

            long_key_flag[3]=0;
        }

        if(double_key_flag[3]==1)//双击判断
        {
         

            double_key_flag[3]=0;
        }

以上就是蓝桥杯嵌入式按键的所有内容。

  • 8
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
STM32是一种嵌入微控制器,具有灵活的输入输出引脚。使用STM32可以方便地实现按键单击双击按功能。 实现按键单击功能的方法是,在程序中通过轮询检测按键引脚的电平状态。当检测到按键引脚的电平从高变低时,就可以认为发生了按键单击事件。在处理事件的代码中可以执行相应的操作,比如控制LED灯亮起或熄灭。 要实现按键双击功能,可以利用计时器和中断。当按键引脚由高电平变为低电平时,启动计时器,并设置一个适当的时间阈值。在计时器中断中断中,检查按键引脚的电平状态,如果在规定的时间内再次检测到低电平,就可以认为发生了双击事件。在处理双击事件的代码中,可以执行相应的操作,如切换LED灯的状态。 要实现按键按功能,也可以利用计时器和中断。当按键引脚由高电平变为低电平时,启动计时器,并设置一个较的时间阈值。在计时器中断中,检查按键引脚的电平状态,如果在规定的时间内仍然保持低电平,就可以认为发生了按事件。在处理按事件的代码中,可以执行相应的操作,如控制LED灯持续亮起或熄灭,或者是执行其他功能。 总结来说,通过对STM32的输入输出引脚进行轮询检测,并结合计时器和中断的使用,可以实现按键单击双击按功能。这种灵活和可编程性是STM32在嵌入系统中广泛应用的原因之一。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值