Test the key input by porting MultiButton through FreeRTOS.
1. Download source code
Download MultiButton source code address:
2. Hardware circuit part
2.1. Three button circuits
2.2. Multiplexing port selection
PF8 port multiplexes touch screen and key input, which is selected through JP42.
3. Procedure
3.1. Configure key input
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 port definition
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. Button function processing
The three buttons handle press, release and long press actions respectively.
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
Create a key task and handle key functions.
#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);
}
}
4. Operation Results
Press the buttons, and the serial port prints out the following content:
V. Attachments
|