【前言】
RT-Spark开发板使用的LCD屏是不带触摸的,但是开发上板载了4个可供用户使用的按键,因此绑定这4个按键给LVGL做交互使用还是非常有必要的。以前还从来没有使用如何绑定,所以还是花费了一些时间进行学习,在这里做一下分享,一来方便以后查看,二来分享给有同样需求的朋友。
【硬件】
RT-Spark 星火一号开发板。
【软件】
1、RT-Thread.
2、MDK5.38
3、LVGL8.3
4、Gui-Guider。
【工程模版】
使用开发板的lvgl模版,在我前面帖子介绍的基础之上来添加功能。帖子链接为:STM32F407之GuiGuider界面移植-电子产品世界论坛 (eepw.com.cn)
【LVGL面板设计】
1、在gui_guider设计中,我添加了一个计数器的模板其界面如下:

在工程模版中,他的计数功能都已经实现好了,不在本文详细介绍,其功能就是单击两个按键,会对计数标签的数值进行加减,长按会连续的加减。
将它他生成的代码添加上一篇帖子的方法添加到工程中。就完成面板的设计工作。
【按键驱动】
按键的驱动,首先要找到原理图,找到对应的按键与MCU的连接PIN脚,以及按键按下时的电平状态。
其原理图如下所示:


从以上原理图看到,按键按下后,对地短接,低电平为按下。因此需要把按键配置为上拉输入模式。
新建bsp_kdy.c/h,并加添进工程之中,代码如下:
#include "bsp_key.h"
#include "main.h"
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_gpio.h"
#define PIN_BTN_UP GET_PIN(C, 5)
#define PIN_BTN_DOWN GET_PIN(C, 1)
#define PIN_BTN_LEFT GET_PIN(C, 0)
#define PIN_BTN_RIGHT GET_PIN(C, 4)
void key_init(void) {
rt_pin_mode(PIN_BTN_UP, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(PIN_BTN_DOWN, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(PIN_BTN_LEFT, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(PIN_BTN_RIGHT, PIN_MODE_INPUT_PULLUP);
}
uint32_t bsp_get_key(void) {
if (rt_pin_read(PIN_BTN_UP) == 0) {
return 1;
} else if (rt_pin_read(PIN_BTN_DOWN) == 0) {
return 2;
} else if (rt_pin_read(PIN_BTN_LEFT) == 0) {
return 3;
} else if (rt_pin_read(PIN_BTN_RIGHT) == 0) {
return 5;
}
return 0xFF;
}同时在bsp_key.h中把init以及键值的获取开发接口:
#ifndef __BSP_KEY_H #define __BSP_KEY_H #include "stm32f4xx.h" void key_init(void); uint32_t bsp_get_key(void); #endif
【LVGL键盘接口】
键盘驱动在lv_port_indev.c中进行初始化与键盘的获取,先上代码:
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-18 Meco Man The first version
*/
#include <lvgl.h>
#include <rtdevice.h>
#include "bsp_key.h"
static void keypad_init(void);
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
uint32_t keypad_get_key(void);
lv_indev_t * indev_keypad;
void lv_port_indev_init(void)
{
static lv_indev_drv_t indev_drv;
/*------------------
* Keypad
* -----------------*/
/*Initialize your keypad or keyboard if you have*/
keypad_init();
/*Register a keypad input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
indev_drv.read_cb = keypad_read;
indev_keypad = lv_indev_drv_register(&indev_drv);
/*Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
*add objects to the group with `lv_group_add_obj(group, obj)`
*and assign this input device to group to navigate in it:
*`lv_indev_set_group(indev_keypad, group);`*/
}
/*------------------
* Keypad
* -----------------*/
/*Initialize your keypad*/
static void keypad_init(void)
{
key_init();
/*Your code comes here*/
}
/*Will be called by the library to read the mouse*/
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
static uint32_t last_key = 0;
/*Get whether the a key is pressed and save the pressed key*/
uint32_t act_key = keypad_get_key();
if(act_key != 0) {
data->state = LV_INDEV_STATE_PR;
rt_kprintf("act_key:%d",act_key);
/*Translate the keys to LVGL control characters according to your key definitions*/
switch(act_key) {
case 1:
act_key = LV_KEY_NEXT;
break;
case 2:
act_key = LV_KEY_PREV;
break;
case 3:
act_key = LV_KEY_LEFT;
break;
case 4:
act_key = LV_KEY_RIGHT;
break;
case 5:
act_key = LV_KEY_ENTER;
break;
}
last_key = act_key;
}
else {
data->state = LV_INDEV_STATE_REL;
}
data->key = last_key;
}
/*Get the currently being pressed key. 0 if no key is pressed*/
static uint32_t keypad_get_key(void)
{
/*Your code comes here*/
uint32_t key = bsp_get_key();
if(key!=0xFF)
{
return key;
}
return 0;
}代码分析:
1、这里的代码在lvgl的输入设备驱动中都是有的,我们需要自己实现的代码只需把按键初始化的驱动放到keypad_init里面进行按键的初始化。

2、键盘的获取,在keypad_get_key这个函数中,添加我们按键键盘的获取代码,就是将bsp_get_key的键盘反馈给lvgl的按键就行了:

到此按建获取的代码就移植完成。
【按键与控件的绑定】
按键与控制的绑定,我所需要用到lvgl的groups这个组件。
在custom自定义函数中,我创建了一个用groups,并将UI组件中的两个bnt添加进组件中,同时把铵键组也添加进去。

最后把这个初始化的函数添加进UI界初始化的函数中就行了。
【运行效果】

按上下键后可以切换按键,按下右键,可以进行计数的更新。
【总结】
LVGL提供了触摸、键盘、编码器等的接口,可以非常方便的选择多种输入设备进行用户的交互。
在学习绑定按键驱动中,学习了许多的教程,起先看起来非常复杂,但是经过自己实践之后,感觉就几步就行了。
我要赚赏金
