1.项目需求
通过平台3--带显示屏的、基于RP2040的多功能嵌入式编程学习、硬件调试平台,完成任务:基于RP2040的LVGL图形化控制终端。
制作一个车速表。
2.需求分析
最开始用的micropython,发现刷屏太卡了,cmakelists又太难写了,于是换用arduino平台。
搭建平台也踩了一些坑。
3.实现的方式
(参考原理图)
主板引脚情况:
屏幕接口:
LCD_RST IO0
LCD_DC IO1
LCD_SCL IO2
LCD_SDA IO3
LCD_CS IO4
两个按键:
KEY_M IO5
KEY_S IO6
拨轮开关:
KEY_L IO7
KEY_OK IO8
KEY_R IO9
侧面有12个插针,分别对应:
GND 3V3
IO20 5V
IO21 IO25
IO22 IO26
IO23 IO27
IO24 IO28
其中I2C接口(此项目不需要用到):
I2C_SDA IO20
I2C_SCL IO21
项目的设计思路和原理:
lvgl由于以前没有用过,于是首先通过官方的最简单例子“hello lvgl”来点亮屏幕。
然后通过gui-guider去设计自己的GUI,这一步需要一些UI设计。
然后生成C代码导出,并移植到arduino里面,当运行没有问题后,最后加入按键控制功能。
lvgl自带的并没有按键控制,而是触摸屏控制。
如果实现按键控制有两种方法:
(1)把按键动作模拟成触摸屏点击事件,csdn上面有一些参考,但是这种方法实现起来有点麻烦,
有点像是舍近求远,看不出来这种方法有什么优势。
(2)其实读取按键是很简单的事情,可以直接读取按键的电平就可以了。
实现的步骤:
开发过程:
(1)通过tft-espi修改参数驱动屏幕
(2)移植lvgl简单案例点亮屏幕
(3)用NXP的GUI-guider设计界面
(4)用产生的ui代码导入到arduino中
GUI-guider设计的UI:
- 代码及说明
遇到的主要难题及解决方法
(1)arduino pico有两个库,一个是基于mbed os的,另外一个是arduino-pico和mbed没有关系,注意不要下载那个mbed os的,那个版本没有elf转uf2的工具,工具还要自己网上找,编译速度也比较慢。
(2) lvgl需要安装lv_arduino库,gui-guider生成的代码移植到arduino中时厚注意头文件路径,需要逐个导入才行。
头文件包含GUI-guider的文件以及全局变量:
#include "custom.h"
#include "events_init.h"
#include "gui_guider.h"
lv_ui guider_ui;
初始化时必须的一些函数,主要用于tft和lvgl的初始化,可以参考lvgl官方给的例程
lv_init();
#if USE_LV_LOG != 0
lv_log_register_print_cb(my_print); /* register print function for debugging */
#endif
tft.begin(); /* TFT init */
tft.setRotation(0); /* Landscape orientation */
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = 240;
disp_drv.ver_res = 240;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
setup_ui(&guider_ui);
events_init(&guider_ui);
custom_init(&guider_ui);
操作逻辑:
拨码开关控制指针的增加和减少,并且设定一个开关按键控制码表的自动运行。
如果开关按键按下,码表通过一些虚拟数值自动运行,如果按键关闭,码表停止运行。
//random speed
if(run_flag !=0 )
{
if(gauge_val>150)
{
gauge_val -=10;
}
else if(gauge_val<30)
{
gauge_val +=10;
}
else
{
gauge_val += 5;
}
delay(500);
}
lv_gauge_set_value(guider_ui.screen_gauge2,0,gauge_val);
lv_task_handler(); /* let the GUI do its work */
if(digitalRead(buttonPin_add)== LOW)
{
delay(50);
{
if(digitalRead(buttonPin_add)== LOW)
{
if(gauge_val<160)
gauge_val += 5;
}
}
}
if(digitalRead(buttonPin_sub)== LOW)
{
delay(50);
{
if(digitalRead(buttonPin_sub)== LOW)
{
if(gauge_val>5)
gauge_val -= 5;
}
}
}
if(digitalRead(buttonPin_onoff)== LOW)
{
delay(100);
{
if(digitalRead(buttonPin_onoff)== LOW)
run_flag = ~run_flag ;
}
}