通过FreeRTOS移植 MultiButton来测试按键的输入。
一、下载源码
下载MultiButton源码地址:https://github.com/0x1abin/MultiButton
二、硬件电路部分
2.1、三个按键电路
2.2、复用端口选择
PF8端口复用触摸屏和按键输入,通过JP42来选择。
三、程序部分
3.1、配置按键输入
void init_key(void)
{
rcu_periph_clock_enable(KEY1_GPIO_CLK);
rcu_periph_clock_enable(KEY2_GPIO_CLK);
rcu_periph_clock_enable(KEY3_GPIO_CLK);
gpio_mode_set(KEY1_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, KEY1_PIN);
gpio_mode_set(KEY2_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, KEY2_PIN);
gpio_mode_set(KEY3_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, KEY3_PIN);
button_init(&btn1, read_button_GPIO, 0, btn1_id);
button_init(&btn2, read_button_GPIO, 0, btn2_id);
button_init(&btn3, read_button_GPIO, 0, btn3_id);
button_start(&btn1);
button_start(&btn2);
button_start(&btn3);
}
3.2、按键端口定义
key.h
#ifndef __KEY_H
#define __KEY_H
#include "stdint.h"
enum Button_IDs {
btn1_id,
btn2_id,
btn3_id,
};
#define KEY1_PIN GPIO_PIN_0
#define KEY1_GPIO_PORT GPIOA
#define KEY1_GPIO_CLK RCU_GPIOA
#define KEY2_PIN GPIO_PIN_13
#define KEY2_GPIO_PORT GPIOC
#define KEY2_GPIO_CLK RCU_GPIOC
#define KEY3_PIN GPIO_PIN_8
#define KEY3_GPIO_PORT GPIOF
#define KEY3_GPIO_CLK RCU_GPIOF
void init_key(void);
void key_hdl(void);
uint8_t read_button_GPIO(uint8_t button_id);
#endif
3.3、按键功能处理
三个按键分别处理的按下、松开和长按动作。
void key_hdl(void)
{
//key1
if(btn1_event_val != get_button_event(&btn1))
{
btn1_event_val = get_button_event(&btn1);
if(btn1_event_val == PRESS_DOWN) {
printf("KEY1 PRESS_DOWN! \r\n");
} else if(btn1_event_val == PRESS_UP) {
//do something
} else if(btn1_event_val == LONG_PRESS_HOLD) {
//do something
}
}
//key2
else if(btn2_event_val != get_button_event(&btn2))
{
btn2_event_val = get_button_event(&btn2);
if(btn2_event_val == PRESS_DOWN) {
//do something
} else if(btn2_event_val == PRESS_UP) {
printf("KEY2 PRESS_UP! \r\n");
} else if(btn1_event_val == LONG_PRESS_HOLD) {
//do something
}
}
//key3
else if(btn3_event_val != get_button_event(&btn3))
{
btn3_event_val = get_button_event(&btn3);
if(btn3_event_val == PRESS_DOWN) {
//do something
} else if(btn3_event_val == PRESS_UP) {
//do something
} else if(btn3_event_val == LONG_PRESS_HOLD) {
printf("KEY3 LONG_PRESS_HOLD! \r\n");
}
}
}
3.4、key.c
#include "main.h"
struct Button btn1;
struct Button btn2;
struct Button btn3;
static PressEvent btn1_event_val;
static PressEvent btn2_event_val;
static PressEvent btn3_event_val;
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 gpio_input_bit_get(KEY1_GPIO_PORT, KEY1_PIN);
case btn2_id:
return gpio_input_bit_get(KEY2_GPIO_PORT, KEY2_PIN);
case btn3_id:
return gpio_input_bit_get(KEY3_GPIO_PORT, KEY3_PIN);
default:
return 0;
}
}
void init_key(void)
{
rcu_periph_clock_enable(KEY1_GPIO_CLK);
rcu_periph_clock_enable(KEY2_GPIO_CLK);
rcu_periph_clock_enable(KEY3_GPIO_CLK);
gpio_mode_set(KEY1_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, KEY1_PIN);
gpio_mode_set(KEY2_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, KEY2_PIN);
gpio_mode_set(KEY3_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, KEY3_PIN);
button_init(&btn1, read_button_GPIO, 0, btn1_id);
button_init(&btn2, read_button_GPIO, 0, btn2_id);
button_init(&btn3, read_button_GPIO, 0, btn3_id);
button_start(&btn1);
button_start(&btn2);
button_start(&btn3);
}
void key_hdl(void)
{
//key1
if(btn1_event_val != get_button_event(&btn1))
{
btn1_event_val = get_button_event(&btn1);
if(btn1_event_val == PRESS_DOWN) {
printf("KEY1 PRESS_DOWN! \r\n");
} else if(btn1_event_val == PRESS_UP) {
//do something
} else if(btn1_event_val == LONG_PRESS_HOLD) {
//do something
}
}
//key2
else if(btn2_event_val != get_button_event(&btn2))
{
btn2_event_val = get_button_event(&btn2);
if(btn2_event_val == PRESS_DOWN) {
//do something
} else if(btn2_event_val == PRESS_UP) {
printf("KEY3 PRESS_UP! \r\n");
} else if(btn1_event_val == LONG_PRESS_HOLD) {
//do something
}
}
//key3
else if(btn3_event_val != get_button_event(&btn3))
{
btn3_event_val = get_button_event(&btn3);
if(btn3_event_val == PRESS_DOWN) {
//do something
} else if(btn3_event_val == PRESS_UP) {
//do something
} else if(btn3_event_val == LONG_PRESS_HOLD) {
printf("KEY3 LONG_PRESS_HOLD! \r\n");
}
}
}
3.5、fun_task.c
创建按键任务,并处理按键功能。
#include "main.h"
#define START_TASK_PRO 1
#define START_STK_SIZE 128
TaskHandle_t StartTask_Handler;
#define TASK1_PRIO 4
#define TASK1_STK_SIZE 128
static TaskHandle_t Task1Task_Handler = NULL;
#define TASK2_PRIO 3
#define TASK2_STK_SIZE 128
static TaskHandle_t Task2Task_Handler = NULL;
#define KEY_PRIO 6
#define KEY_STK_SIZE 128
static TaskHandle_t KeyTask_Handler = NULL;
void start_task(void *pvParameters);
void gui_task(void *pvParameters);
void task1(void *pvParameters);
void task2(void *pvParameters);
void task_key_hdl(void *pvParameters);
void task_create(void)
{
//start_task
xTaskCreate((TaskFunction_t )start_task,
(const char* )"start_task",
(uint16_t )START_STK_SIZE,
(void* )NULL,
(UBaseType_t )START_TASK_PRO,
(TaskHandle_t* )&StartTask_Handler);
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL();
//task1
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1Task_Handler);
//task2
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2Task_Handler);
//KEY
xTaskCreate((TaskFunction_t )task_key_hdl,
(const char* )"task_key_hdl",
(uint16_t )KEY_STK_SIZE,
(void* )NULL,
(UBaseType_t )KEY_PRIO,
(TaskHandle_t* )&KeyTask_Handler);
taskEXIT_CRITICAL();
vTaskDelete(StartTask_Handler);
}
//task1
void task1(void *pvParameters)
{
while (1)
{
//printf("task1 run ...\r\n");
vTaskDelay(200);
}
}
//task2
void task2(void *pvParameters)
{
while (1)
{
//printf("task2 run ...\r\n");
vTaskDelay(100);
}
}
//task_key_hdl
void task_key_hdl(void *pvParameters)
{
uint8_t ct=0;
init_key();
while (1)
{
key_hdl();
ct++;
if(ct>4)
{
ct=0;
button_ticks();
}
vTaskDelay(1);
}
}
四、运行结果
操作按键,串口打印输出内容:
五、附件