本篇学习 LVGL 的事件添加,教给大家如何添加事件并且最终完成一个电子木鱼(小美苦苦哀求而我略微出手)。2024 年的第一项运动——敲木鱼,敲电子木鱼,品赛博人生。顺便净化一下心灵且累积功德。祝大家 2024 积德累功,功成名就。
先新建一个工程,具体步骤就不展示了。
咱们直接进入 UI 设计界面,这里我用到了两个组件,一个是图片按钮,一个是文本框。先添加一个图片按钮,这就需要一张木鱼图,大家可以添加自己喜欢的任意图案。大小比例记得调整,需要注意的是,这里建议准备两张一模一样的图片,区别在于他们的大小,一张大图一张小图,大图添加在释放后的图片,小图添加在按下时图片,就达成我们敲下去的变化效果。我这里准备了一张大木鱼图还有一张小木鱼图。
添加一个文本框,先固定好位置,在右侧的文本输入“功德 +1”字样,注意字体选择 simsun 才可以显示中文。据此,所需要的组件已经添加成功了。
接下来我们添加图片按键的事件。需要实现的效果是,在按下图片(木鱼)时将“功德 +1"的文本框向上移动,在释放图片(木鱼)时将”功德 +1“隐藏。这样的效果就是点击时会出现”功德 +1“飘出来的效果。
1.点击左侧 imgbtn_1,图片按钮
2.点击手指图标事件设置。这里我们可以看到有许多事件的添加,我们只需要配置两个事件,Pressed(按下)和 Released(释放)。
3.点击 Pressed(按下),在组件里选中 label_1,也就是我们的文本框,在 Animation 选项下勾选移动,设置需要移动的坐标,也就是我们按下后的最后 lable_1 移动的最终位置,这里我的最终位置 x 坐标伟 206,y 坐标为 25,动画效果选择 linear 线性,持续时间为 50ms,也就是整个移动过程的持续时间。
4.返回上一层,点击 Released,一样在组件里选中 lable_1,首先在 General 下勾选可视化,选择隐藏,也就是我们释放按钮后会隐藏文本框。
5.其次在 Animation 下勾选移动,将我们按下图片后的文本框移动回原来的位置,也就是一开始的坐标位置,x 坐标 206,y 坐标 45,动画选择 linear 线性,持续时间 0 秒也就是瞬间移动。这样我们在按下图片时 Y 轴移动文本框 20 个像素,然后在释放图片时会将文本框移动回原来的位置并且隐藏。就可以实现”功德 +1“飘出来的效果。
记得运行一下看一下模拟器的效果。同时也会生成我们需要的工程文件。
创建新的工程文件方法在上篇教程中已经输出给大家,但是我发现在 main 中的 while(1)进行刷屏的速率会卡住,目前原因暂不明,所以还是建议使用 FreeRTOS 加一个刷新 LVGL 屏幕的任务。 将我们上次没移植的文件,也就是 lv_user_config 的.c 和.h 文件一并放进来,文件可以在 AiPi-Radar-WakeUp 下的 components 下的 UI 复制过来,方法不在赘述。由于本次刷新 LVGL 需要 FreeRTOS,所以我们还需要复制 config 下的 FreeRTOSConfig.h,一并放在我们的工程目录下,同时修改 proj.conf 文件,添加 set(CONFIG_FREERTOS 1),开启 RTOS。
其次将我们所有的文件通过 CMakeLists.txt 添加编译。这里附上我的 CMake。
然后在 Main 里面添加一个任务,先附上我的完整 mian 供大家参考。
#include "board.h"
#include "bflb_gpio.h"
#include "bflb_l1c.h"
#include "bflb_mtimer.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "lv_conf.h"
#include "lvgl.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"
#include "gui_guider.h"
#include "custom.h"
#include "lcd.h"
#include "lv_user_config.h"
//该变量必须是全局变量
lv_ui guider_ui;
int main(void)
{
board_init();
printf("lvgl case\r\n");
/* lvgl init */
lv_log_register_print_cb(lv_log_print_g_cb);
lv_init();
//显示器初始化
lv_port_disp_init();
//外部输入初始化(Touch触摸)
lv_port_indev_init();
//设计小组件的UI布局
setup_ui(&guider_ui);
custom_init(&guider_ui);
printf("lvgl success\r\n");
//es8388芯片初始化
es8388_voice_init();
//创建一个任务,lvgl的刷新任务,该任务函数在lv_user_config.c中
xTaskCreate(lvgl_tick_task, (char*)"lvgl", 1024, NULL, 1, NULL);
//开启任务调度
vTaskStartScheduler();
while (1) {
vTaskDelay(5000/portTICK_RATE_MS);
}
}
光有点击的画面还不行,电子木鱼的灵魂在于敲击的声音,主打一个灵魂洗涤。
这里为了方便大家,我将 8388 的驱动也移植到了 commponents,修改了部分配置文件。驱动的原理是 I2S 驱动 8388 芯片,然后将音频文件烧录至 flash 中,然后再接口中通过 dma 输出音频文件。
这里我已经找到一个音频文件,是 wav 的格式,采样率是 44100。
首先将音频文件放进去,然后修改 flash_prog_cfg.ini 将音频文件烧录进 flash 中,可以参考我截图中方法,起始地址可以参考 flash 教学博文中,这里我选择 0x230000,如果是烧录多个文件的话,记得计算文件大小,确保他们的地址空间不重复。
添加一个 muyu_8388_pcm.h 文件,定义木鱼音频的起始地址和大小。这里初始化函数在 8388_pcm.c 中已经有,我们只需要编写一个 voice_MuYu 的函数。
修改 8388_pcm.c 文件,编写一个播放函数,这个函数也是调用 play_voice 这个接口,参数为音频文件的地址和大小。同时修改 i2s 的初始化,采样率是 44100。
主函数中记得将 8388 芯片初始化。
修改我们的 LVGL 工程中的 events_init.c,这个文件是我们的事件控制文件,添加我们的 muyu_8388_pcm.h 头文件,在 Pressed 事件中加入播放音频的接口。
由于论坛限制,后续会附上 B 站视频链接,这里先贴上动图。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。