嵌入式蓝桥杯学习6 定时中断按键(短按 长按 双击)

前面的cubemx配置都和定时中断的一样,详情请看上文,这篇我们主要写按键相关的代码。

前面的外部中断的按键,还有直接写的按键函数都不适用于比赛,各有不同缺点。在比赛中按键又是个很重要的外设,那如何实现按键呢,请看以下的内容。

首先,新建两个文件(key.c 和 key.h)用于放置关于按键的函数。

前面我们将定时器设置为每隔10ms进行一次中断。考虑到按键抖动问题。如果连着两次10ms的判断都是低电平,就会有真正的按键被按下。

按键短按

按键读取函数

复制代码
//low return 0
//high return 1
uint8_t key_read()
{
    if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0) return 1;
    else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0) return 2;
    else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0) return 3;
    else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0) return 4;
    else return 0;
}

按键服务函数

复制代码
struct Bkeys
{
    uint8_t age;
    uint8_t flag;
}
struct Bkeys bkey[5]={0,0};
void key_serv()
{
    uint8_t key_sta=key_read();
    if(key_sta!=0)
    {
        bkey[key_sta].age++;
        if(bkey[key.sta].age>1) bkey[key_sta].flag=1;
    }
    else
    {
        for(int i=0;i<5;++)
            bkey[i].age=0;
    }
}

中断回调函数

复制代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	key_serv();
}

my_main.c

复制代码
extern struct Bkeys bkey[];
void loop()
{
    if(bkey[1].flag==1)
    {
        sprintf(text,"    KEY1   DOWN  !    ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[1].flag=0;
    }
     if(bkey[2].flag==1)
    {
        sprintf(text,"    KEY2   DOWN  !    ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[2].flag=0;
    }
}

按键长按

按键服务函数

复制代码
struct Bkeys
{
    uint8_t age;
    uint8_t short_flag;
    uint8_t long_flag;
    uint8_t press;
}
struct Bkeys bkey[5]={0,0};
void key_serv_long()
{
    uint8_t key_sta=key_read();
    if(key_sta!=0)
    {
        bkey[key_sta].age++;
        if(bkey[key.sta].age>1) bkey[key_sta].press=1;
    }
    else
    {
        for(int i=0;i<5;++)
        {
            if(bkey[i].press==1&&bkey[i].long_flag=0) bkey[i].short_flag=1;
            bkey[i].press=0;
            bkey[i].age=0;
            bkey[i].long_flag=0;
        }
    }
    if(bkey[key.sta].age>69) bkey[key_sta].long_flag=1;
}

中断回调函数

复制代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM6)
	key_serv_long();
}

my_main.c

实现步进自增功能

复制代码
extern struct Bkeys bkey[];
void loop()
{
    static uint16_t temp;
    if(bkey[1].short_flag==1)
    {
        sprintf(text,"    KEY1   DOWN  !    ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[1].short_flag=0;
    }
     if(bkey[2].short_flag==1)
    {
        sprintf(text,"    KEY2   DOWN  !    ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[2].short_flag=0;
    }
    if(bkey[1].long_flag==1)
    {
        sprintf(text,"    KEY1   LONG  !  %d  ",temp);
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        temp++;
    }
     if(bkey[2].long_flag==1)
    {
        sprintf(text,"    KEY2   LONG  !   %d ",temp);
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        temp++;
    }
}

实现按超过2s后松开

按键服务函数
复制代码
struct Bkeys
{
    uint8_t age;
    uint8_t short_flag;
    uint8_t long_flag;
    uint8_t press;
}
struct Bkeys bkey[5]={0,0};
void key_serv_long()
{
    uint8_t key_sta=key_read();
    if(key_sta!=0)
    {
        bkey[key_sta].age++;
        if(bkey[key.sta].age>1) bkey[key_sta].press=1;
    }
    else
    {
        for(int i=0;i<5;++)
        {
            if(bkey[key.sta].age>69) bkey[key_sta].long_flag=1;
            if(bkey[i].press==1&&bkey[i].long_flag=0) bkey[i].short_flag=1;
            bkey[i].press=0;
            bkey[i].age=0;
        }
    }
    
}

extern struct Bkeys bkey[];
void loop()
{
    static uint16_t temp;
    if(bkey[1].short_flag==1)
    {
        sprintf(text,"    KEY1   DOWN  !    ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[1].short_flag=0;
    }
     if(bkey[2].short_flag==1)
    {
        sprintf(text,"    KEY2   DOWN  !    ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[2].short_flag=0;
    }
    if(bkey[1].long_flag==1)
    {
        sprintf(text,"    KEY1   LONG  !   ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[1].long_flag=0;
    }
     if(bkey[2].long_flag==1)
    {
        sprintf(text,"    KEY2   LONG  !  ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[2].long_flag=0;
    }
}

按键双击

按键服务函数

复制代码
struct Bkeys
{
    uint8_t age;
    uint8_t short_flag;
    uint8_t long_flag;
    uint8_t press;
    uint8_t double_ageEN;
    uint8_t double_age;
    uint8_t double_flag;
}
struct Bkeys bkey[5]={0,0};
void key_serv_double()
{
    uint8_t key_sta=key_read();
    if(key_sta!=0)
    {
        bkey[key_sta].age++;
        if(bkey[key.sta].age>1) bkey[key_sta].press=1;
    }
    else
    {
        for(int i=0;i<5;++)
        {
            if(bkey[i].double_ageEN=1&&bkey[i].press==1)
            {
                bkey[i].double_flag=1;
                bkey[i].double_age=0;
                bkey[i].double_ageEN=0;
            }
            if(bkey[i].press==1&&bkey[i].long_flag==0) bkey[i].double_ageEN=1;
            if(bkey[i].double_ageEN==1) bkey[i].double_age++;
            if(bkey[i].double_ageEN==1&&bkey[i].double_age>20)
            {
                bkey[i].short_flag=1;
                bkey[i].double_age=0;
                bkey[i].double_ageEN=0;
            }
            bkey[i].press=0;
            bkey[i].age=0;
        }
    }
    
}

中断回调函数

复制代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM6)
	key_serv_double();
}

my_main.c

复制代码
extern struct Bkeys bkey[];
void loop()
{
    static uint16_t temp;
    if(bkey[1].short_flag==1)
    {
        sprintf(text,"    KEY1   DOWN  !    ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[1].short_flag=0;
    }
     if(bkey[2].short_flag==1)
    {
        sprintf(text,"    KEY2   DOWN  !    ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[2].short_flag=0;
    }
    if(bkey[1].long_flag==1)
    {
        sprintf(text,"    KEY1   LONG  !  %d  ",temp);
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        temp++;
    }
     if(bkey[2].long_flag==1)
    {
        sprintf(text,"    KEY2   LONG  !   %d ",temp);
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        temp++;
    }
    if(bkey[1].double_flag==1)
    {
        sprintf(text,"    KEY1   DOUBLE  !  ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[1].double_flag=0;
    }
     if(bkey[2].double_flag==1)
    {
        sprintf(text,"    KEY2   DOUBLE !  ");
        LCD_DisplayStringLine(Line8,(uint8_t*)text);
        bkey[2].double_flag=0;
    }
}
相关推荐
心中有国也有家4 分钟前
AtomGit Flutter 鸿蒙客户端:ModalBottomSheet 实战
android·javascript·学习·flutter·华为·harmonyos
tyqtyq2223 分钟前
求职信生成:AI 智能求职信撰写系统的鸿蒙实现
人工智能·学习·华为·生活·harmonyos
老吴胡编29 分钟前
eknife 2026.07.10 v0.0.6 更新 —— 支持文件加解密
嵌入式硬件·个人开发
MartinYeung533 分钟前
[论文学习]PrivacyLens:评估语言模型在行动中的隐私规范意识
人工智能·学习·语言模型
bobuddy44 分钟前
Zeta 变换器电路
嵌入式硬件
凉、介2 小时前
Virtio 系列(一):框架概览
笔记·学习·嵌入式·虚拟化·virtio
浅止菌2 小时前
性能瓶颈找不到?ftrace+perf组合拳,5分钟定位内核问题
嵌入式硬件
小心亦新3 小时前
STM32学习12--串口2收发数据包
学习
ACP广源盛139246256733 小时前
IX9104 PCIe5.0 交换芯片@ACP#国产高端 AI PC 全搭配方案
大数据·人工智能·分布式·单片机·嵌入式硬件
Starmoon_dhw3 小时前
题解:P17078 夏日甜点
c++·学习·算法·图论