【蓝桥杯嵌入式】长短按 按键

        在上一章节“【蓝桥杯嵌入式】状态机按键”中使用的按键程序中,按键间具有优先性(如B1按下后,B2~B4的按下将不会被识别),同时不支持双键、长短按。在这一章节中,我们升级一下,采用独立的按键检测,并实现下长短按。

一、按键的独立化

        我们针对每一个按键都进行了独立的状态检测和处理,定义了一个结构体,一个数组用来存储按键的不同信息。

typedef enum 
{
    IDLE,               // 未按下,空闲状态
    PRESSED_READY,      // 按下,待执行相应功能
    PRESSED_FINISH,     // 按下,功能已执行,等待松开按键回到空闲状态
    PRESSED_COUNT       // 按下,处于计时状态(用于长短按)
} ButtonState;          // 按键状态

// 定义一个函数类型
typedef void (*Function)(void);

typedef struct
{
    GPIO_TypeDef *port;         // 按键对应的GPIO端口
    uint16_t pin;               // 按键对应的引脚
    ButtonState key_state;      // 按键的状态(空闲、按下、计时等)
    unsigned char long_mode;    // 按键长按模式(用于标记长按模式,1为长短按键)
    unsigned int pressed_time;  // 按键按下的持续时间(用于长按计时)
    Function keyFunction;       // 按键短按功能对应的函数指针
    Function keyFunctionLong;   // 按键长按功能对应的函数指针
} key_GPIO;                     // 按键对应信息

// 按键对应的IO口信息及功能回调函数
key_GPIO key[4];

函数指针允许我们将函数的地址存储在结构体的成员中,以便在需要时调用相应的函数。我们定义了函数指针类型Function ,用于存储按键的短按功能和长按功能对应的函数地址。在初始化 key_GPIO 结构体数组时,为每个按键的 keyFunctionkeyFunctionLong 成员赋值为相应的函数名。这样,每个按键的结构体中就包含了对应的函数指针,可以根据按键的状态调用相应的功能函数。

// 按键对应的IO口信息及功能回调函数
key_GPIO key[4] = {
    {GPIOB,GPIO_PIN_0,IDLE,0,0,function_B1},
    {GPIOB,GPIO_PIN_1,IDLE,0,0,function_B2},
    {GPIOB,GPIO_PIN_2,IDLE,0,0,function_B3},
    {GPIOA,GPIO_PIN_0,IDLE,1,0,function_B4,function_B4_long}
};

按键的功能与上一章节基本一致,只是把B4按键改成了一个长短按键,短按:翻转LD7状态,长按:熄灭LD1~LD7。

// 按键B1的功能实现
void function_B1()
{
    led_addr = led_addr | 0x03; // 更新LED位置
    led_disp(led_addr);         // 控制LED显示
}

// 按键B2的功能实现
void function_B2()
{
    led_addr = led_addr | 0x0C; // 更新LED位置
    led_disp(led_addr);         // 控制LED显示
}

// 按键B3的功能实现
void function_B3()
{
    led_addr = led_addr ^ 0x30; // 更新LED位置
    led_disp(led_addr);         // 控制LED显示
}

// 按键B4的功能实现
void function_B4()
{
    led_addr = led_addr ^ 0x40; // 更新LED位置
    led_disp(led_addr);         // 控制LED显示
}

// 按键B4长按的功能实现
void function_B4_long()
{
    led_addr = led_addr & 0x80; // 更新LED位置
    led_disp(led_addr);         // 控制LED显示
}

二、状态机程序

与之前的状态机类似,检测都是满足一定条件就进入下一个状态

检测按键当前的状态(key_state):

  • 如果是空闲状态(IDLE),检测是否有按键按下,若有则将状态切换为 PRESSED_READY
  • 如果是按下待执行状态(PRESSED_READ
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值