[MCU] 【兆易GD32H759I-EVAL】按键输入测试

TL-LED   2024-5-17 20:16 楼主

通过FreeRTOS移植 MultiButton来测试按键的输入。

 

一、下载源码

 

下载MultiButton源码地址:https://github.com/0x1abin/MultiButton

 

二、硬件电路部分

 

2.1、三个按键电路

001.png

2.2、复用端口选择

PF8端口复用触摸屏和按键输入,通过JP42来选择。

002.png

 

三、程序部分

 

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);
	}
}

 

四、运行结果

 

操作按键,串口打印输出内容:

003.png

 

五、附件

 

源代码:
gd32h759_freertos_prj_20240517.rar (3.15 MB)
(下载次数: 1, 2024-5-17 20:14 上传)

回复评论 (2)

这个开源的按键驱动,非常优秀,感谢楼主的精彩分享!
点赞  2024-5-18 06:35

PF8端口复用触摸屏和按键输入,通过JP42来选择这款感觉开发板规划不太好

在爱好的道路上不断前进,在生活的迷雾中播撒光引
点赞  2024-5-18 11:15
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复