Featured image of post HAL_按键-MultiButton使用记录

HAL_按键-MultiButton使用记录

HAL_按键-MultiButton使用记录

  • MultiButton 是一个开源的轻量的按键判断的函数 如下使该函数的开源链接:

    0x1abin/MultiButton: Button driver for embedded system (github.com)

    如何使用这个库里面已经是写的很清楚了

    事件 说明
    PRESS_DOWN 按键按下,每次按下都触发
    PRESS_UP 按键弹起,每次松开都触发
    PRESS_REPEAT 重复按下触发,变量repeat计数连击次数
    SINGLE_CLICK 单击按键事件
    DOUBLE_CLICK 双击按键事件
    LONG_PRESS_START 达到长按时间阈值时触发一次
    LONG_PRESS_HOLD 长按期间一直触发

本人自己再封装了一遍两个按键

button.c文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include "button.h"

enum Button_IDs
{
	start_key,
	Estop_key,
};

struct Button btn1;
struct Button btn2;
static void BTN1_PRESS_DOWN_Handler(void *btn)
{
	 printf("BTN1_PRESS_DOWN_Handler\r\n");
}

static void BTN2_PRESS_DOWN_Handler(void *btn)
{
   printf("BTN2_PRESS_DOWN_Handler\r\n");
}

static uint8_t read_button_GPIO(uint8_t button_id)
{
	// you can share the GPIO read function with multiple Buttons
	switch (button_id)
	{
	case start_key:
		return HAL_GPIO_ReadPin(start_GPIO_Port, start_Pin);
	case Estop_key: 
		return HAL_GPIO_ReadPin(Estop_GPIO_Port, Estop_Pin);
	default:
		return 0;
	}
}
// 按键注册
void button_register()
{  // 按键初始化
	button_init(&btn1, read_button_GPIO, 0, start_key);
  button_init(&btn2, read_button_GPIO, 0, Estop_key);
   // 绑定到回调函数
  button_attach(&btn1, SINGLE_CLICK, BTN1_PRESS_DOWN_Handler);
	button_attach(&btn2, SINGLE_CLICK, BTN2_PRESS_DOWN_Handler);

	button_start(&btn1);
	button_start(&btn2);
}

button.h文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#ifndef __BUTTON_H_
#define __BUTTON_H_

#include "global.h"

#include "multi_button.h"

void button_register();

#endif

值得注意的是注意源函数里面有个类似“心跳“的东西

1
void button_ticks(void);

你得5ms执行一下 可以放while主循环里面

1
2
3
4
5
while (1)
 {
    button_ticks();
    HAL_Delay(5);
 }

也可以放在定时器中断里面

1
2
3
4
5
6
7
8
  void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  {
    //5ms
    if (htim->Instance == TIM7) //
    {
       button_ticks();
    }
  }

还有一点就是需要再执行主函数之前把按键注册什么函数初始化一遍

1
button_init(&btn1, read_button_GPIO, 0, start_key);

第三个参数是按键高电平还是低电平有效


多个按键的话 推荐使用下面的方式

把回调判断放在一个函数里面

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include "multi_button.h"
#include "bsp_key.h"
#include "My_button.h"

enum Button_IDs
{
    btn1_id,  
    btn2_id,   
    BUTTONS_NUM,
};

struct Button btn1;  
struct Button btn2;   

static  uint8_t read_button_GPIO(uint8_t button_id)
{
   
    switch (button_id)
    {
    case btn1_id:
        return HAL_GPIO_ReadPin(Key1_GPIO_PORT, Key1_GPIO_PIN);  
    case btn2_id:
        return HAL_GPIO_ReadPin(Key2_GPIO_PORT, Key2_GPIO_PIN);     
    default:
        return 0;
    }
}
static void Buttons_Callback(void *button)
{
    PressEvent btn_event_val;
    btn_event_val = get_button_event((struct Button *)button);
    //  FAN_DW 按键 触发事件处理
    if ((struct Button *)button == &btn1)
    {
        if (btn_event_val == SINGLE_CLICK)
        {
           
        } 
    }
    // UV_KEY 按键 触发事件 
    else if ((struct Button *)button == &btn2)
    {
        if (btn_event_val == SINGLE_CLICK)
        {
           
            
        }
        
    }
}
void My_button_init_attach_start(void)
{
    button_init(&btn1, read_button_GPIO, 0, btn1_id);
    button_init(&btn2, read_button_GPIO, 0, btn2_id);

    button_attach(&btn1, SINGLE_CLICK, Buttons_Callback);
    button_attach(&btn1, LONG_PRESS_HOLD, Buttons_Callback);
    button_attach(&btn2, SINGLE_CLICK, Buttons_Callback);
    button_attach(&btn2, LONG_PRESS_HOLD, Buttons_Callback);

    button_start(&btn1);
    button_start(&btn2);
}

为了多个按键更容易定义对接到指定的引脚

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
enum Button_IDs{
	btn1_id,
	btn2_id,
  BUTTONS_NUM
};
struct Button buttons[BUTTONS_NUM] = {0};
// struct Button btn1;
// struct Button btn2;

uint8_t read_button_GPIO(uint8_t button_id)
{
	// you can share the GPIO read function with multiple Buttons
	switch(button_id)
	{
		case btn1_id:
			return HAL_GPIO_ReadPin(Key1_GPIO_PORT, Key1_GPIO_PIN);
		case btn2_id:
			return HAL_GPIO_ReadPin(Key2_GPIO_PORT, Key2_GPIO_PIN);
		default:
			return 0;
	}
}

void Buttons_Callback(void *button)
{
    PressEvent btn_event_val;
    btn_event_val = get_button_event((struct Button *)button);
//
    if((struct Button *)button == &buttons[btn1_id])
    {
        if(btn_event_val == SINGLE_CLICK)
        {
        	count=0;
        }
				else if(btn_event_val == LONG_PRESS_HOLD){
//				 LED2_TOGGLE(); 
					count++;
					
				}

    }
    else if((struct Button *)button == &buttons[btn2_id])
    {
        if(btn_event_val == PRESS_DOWN)
        {
            LED3_TOGGLE();
        }
    }
   

}



    button_init(&buttons[btn1_id], read_button_GPIO, 0, btn1_id);
		button_init(&buttons[btn2_id], read_button_GPIO, 0, btn2_id);

		button_attach(&buttons[btn1_id], SINGLE_CLICK,  Buttons_Callback);
		button_attach(&buttons[btn1_id], LONG_PRESS_HOLD,  Buttons_Callback);
		button_attach(&buttons[btn1_id], LONG_PRESS_START,  Buttons_Callback);
		button_attach(&buttons[btn2_id], PRESS_DOWN,  Buttons_Callback);
	

		button_start(&buttons[btn2_id]);
		button_start(&buttons[btn1_id]);

 
最后更新于 Apr 11, 2025 16:18 +0800
世界是你们
使用 Hugo 构建
主题 StackJimmy 设计