RP2350-GEEK
说明
| ||||||||||||||||||||||
| ||||||||||||||||||||||
产品概述
RP2350-GEEK 是一款微雪 (Waveshare) 为极客设计的开发板,板载USB-A公口、1.14寸LCD屏幕、Mirco SD卡槽等外设,使用不同固件可以提供 SWD 接口、UART 接口和 I2C 接口,可以为你的项目提供无限可能
产品特性
- 采用 Raspberry Pi 官方自主设计的 RP2350 微控制器芯片
- 独特的双核、双架构,搭载了双核 ARM Cortex-M33 处理器和双核 Hazard3 RISC-V 核处理器,运行频率均高达 150MHz 灵活时钟
- 内置 520KB 的 SRAM 和 16MB 的片上 Flash
- 板载 1.14 英寸 240×135 像素的 65K 彩色 IPS LCD 显示屏
- 板载 3PIN SWD 接口,用于连接被调试的目标板
- 标准 CMSIS-DAP 接口,可用于调试大部分基于 ARM 的微控制器
- 适用 OpenOCD 和其他支持 CMSIS-DAP 的调试工具
- 采用树莓派同类型的 3PIN 调试接口规范
- 板载 3PIN UART 接口,可用于实现 USB 串口转接器的功能
- 板载 4PIN I2C接口,可用于测试目标板
- 配备塑料外壳以及相关连接线材
- 使用开源固件,升级固件更方便
尺寸图
Pico快速上手
固件下载
| ||
|
基础介绍
MicroPython系列
安装Thonny IDE
为了方便在电脑上使用MicroPython开发Pico/Pico2板,建议下载Thonny IDE
- 下载Thonny IDE并按照步骤安装,安装包均为Windows版本,其他版本请参考Thonny官网
- 安装完成之后,第一次要配置语言和主板环境,由于我们是为了使用Pico/Pico2,所以注意主板环境选择Raspberry Pi 选项
- 配置Micrpython环境及选择Pico/Pico2端口
- 先将Pico/Pico2接入电脑,左键点击Thonny右下角的配置环境选项--》选择configture interpreter
- 在弹出的窗口栏中选择MicroPython(Raspberry Pi Pico),同时选择对应的端口
烧录固件
- 点击ok后返回到Thonny主界面,下载对应的固件库并烧录到设备中,然后点击停止按钮,在Shell窗口中即可显示当前使用到的环境
- 注意:烧录Micropython官方提供的Pico2固件可能导致无法识别设备,请使用下方或程序包中的固件
- Pico/Pico2在windows下载固件库方法: 按住BOOT键后连接电脑后,松开BOOT键,电脑会出现一个可移动磁盘,将固件库复制进去即可
- RP2040/RP2350在windows下载固件库方法: 连接电脑后,同时按下BOOT键跟RESET键,先松开RESET键再松开BOOT键,电脑会出现一个可移动磁盘,将固件库复制进去即可(用Pico/Pico2的方式也可以)
讲解视频
【MicroPython】machine.Pin类函数详解
【MicroPython】machine.PWM类函数详解
【MicroPython】machine.ADC类函数详解
【MicroPython】machine.UART类函数详解
【MicroPython】machine.I2C类函数详解
【MicroPython】machine.SPI类函数详解
【MicroPython】rp2.StateMachine类函数详解
C/C++系列
对于 C/C++,建议使用 Pico VS Code 进行开发,这是一款 Microsoft Visual Studio Code 扩展,旨在让您在为 Raspberry Pi Pico 系列开发板创建、开发和调试项目时更加轻松。无论您是初学者还是经验丰富的专业人士,此工具都可以帮助您自信而轻松地进行 Pico 开发。下面我们介绍如何安装该扩展并使用。
- 官网教程:https://www.raspberrypi.com/news/pico-vscode-extension/
- 本教程适用于树莓派Pico、Pico2与本公司开发的RP2040、RP2350系列开发板
- 开发环境默认以 Windows11 为例,其他环境请参考官网教程进行安装
安装VSCode
-
首先,点击下载 pico-vscode 程序包,解压并打开程序包,双击安装 VSCode
注意:如果已安装 vscode 注意检查版本是否为 v1.87.0 或更高版本
安装扩展
-
点击扩展,选择从 VSIX 安装
-
选择 vsix 后缀的软件包,点击安装
-
随后 vscode 会自动安装 raspberry-pi-pico 及其依赖扩展,可以点击刷新查看安装进度
-
右下角显示完成安装,关闭 vscode
配置扩展
-
打开目录 C:\Users\用户名,将整个 .pico-sdk 拷贝至该目录
-
拷贝完成
-
打开 vscode,对 Raspberry Pi Pico 扩展中各个路径进行配置
配置如下:Cmake Path: ${HOME}/.pico-sdk/cmake/v3.28.6/bin/cmake.exe Git Path: ${HOME}/.pico-sdk/git/cmd/git.exe Ninja Path: ${HOME}/.pico-sdk/ninja/v1.12.1/ninja.exe Python3 Path: ${HOME}/.pico-sdk/python/3.12.1/python.exe
新建工程
-
配置完成,测试新建工程,输入工程名、选择路径后点击 Creat 创建工程
测试官方示例,可以点击工程名旁的 Example 进行选择
-
创建工程成功
-
选择SDK版本
-
选择 Yes 进行高级配置
-
选择交叉编译链,13.2.Rel1 适用 ARM 核,RISCV.13.3 适用 RISCV 核,这里根据您的需求任意选择其中一个即可
-
CMake 版本选择 Default(前面配置的路径)
-
Ninja 版本选择 Default
-
选择开发板
-
点击 Complie 进行编译
-
成功编译出 uf2 格式文件即可
导入工程
- 导入工程的 Cmake 文件不能有中文(包括注释),否则可能导致导入失败
-
导入自己的工程需要在 Cmake 文件中加一行代码,才能正常切换 pico 和 pico2,否则即使选择 pico2,编译得到的固件仍是适用于 pico 的
set(PICO_BOARD pico CACHE STRING "Board type")
更新扩展
Arduino IDE 系列
安装Arduino IDE
-
首先到Arduino官网下载Arduino IDE的安装包。
-
这里选择仅下载就可以了。
-
下载完成后,点击安装。
注意:安装过程中会提示你安装驱动,我们点击安装即可
Arduino IDE中文界面
在Arduino IDE中安装Arduino-Pico Core
-
打开Arduino IDE,点击左上角的文件,选择首选项
-
在附加开发板管理器网址中添加如下链接,然后点击OK
https://github.com/earlephilhower/arduino-pico/releases/download/4.0.2/package_rp2040_index.json
注意:如果您已经有ESP32板URL,您可以使用逗号分隔 URL,如下所示:https://dl.espressif.com/dl/package_esp32_index.json,https://github.com/earlephilhower/arduino-pico/releases/download/4.0.2/package_rp2040_index.json
-
点击工具>开发板>开发板管理器>搜索pico,由于我的电脑已经安装过了,所以显示已安装
国内用户
- 因为网络原因,国内用户连接github并不稳定,我们另外提供了一份安装包,可以跳过在线的过程
- 若已经成功配置了pico环境,可以直接跳过本章
-
下载rp2040压缩包,将解压的rp2040文件夹复制到如下路径下
C:\Users\[username]\AppData\Local\Arduino15\packages
第一次上传程序
-
按住Pico板上的BOOTSET按键,将pico通过Micro USB线接到电脑的USB接口,待电脑识别出一个可移动硬盘(RPI-RP2)后,松开按键。
- 下载程序,打开arduino\PWM\D1-LED路径下的D1-LED.ino
-
点击工具>端口,记住已有的COM,不需要点击这个COM(不同电脑显示的COM不一样,记住自己电脑上已有的COM)
-
用USB线将驱动板和计算机连接起来,再点击工具>端口,第一次连接选择uf2 Board,上传完成后,再次连接就会多出一个COM口
-
点击工具>开发板>Raspberry Pi Pico>Raspberry Pi Pico或Raspberry Pi Pico 2
- 设置完成后,点击向右箭头上传将程序
- 如果期间遇到了问题,需要重新安装或者更换Arduino IDE版本时,卸载Arduino IDE需要卸载干净,卸载软件后需要手动删除C:\Users\[name]\AppData\Local\Arduino15这个文件夹内的所有内容(需要显示隐藏文件才能看到) 再重新安装
开源例程
MircoPython视频例程(github)
MicroPython固件/Blink例程(C)
树莓派官方C/C++示例程序 (github)
树莓派官方micropython示例程序 (github)
Arduino官方C/C++示例程序 (github)
示例程序
C/C++例程
01-LCD
- LCD刷一张图片并等待2.5秒
- LCD刷GUI示例
02-picoprobe
- 该例程基于开源程序picoprobe
- RP2350-GEEK运行picoprobe例程,将模拟出一个USB TO SWD 和 USB TO UART设备
- 通过UART接作为USB转串口工具,可用于与设备通讯
- 通过SWD接口作为debug工具,配合openocd可调试大部分arm芯片
- 具体使用方法可参考下文《picoprobe使用教程》
03-FATFS
- 该例程基于开源程序no-OS-FatFS-SD-SDIO-SPI-RPi-Pico
- 注意sd卡文件格式为FAT32
Micropython例程
01-LCD
使用方法
例程效果
- LCD刷出GUI画面,等待几秒,刷出bmp图片
02-SD
使用方法
例程效果
LVGL 示例程序
C
示例效果
本例显示的效果为通过 LVGL 显示一张图片。
示例简介
本例用于测试 LVGL 控件交互、样式美化等, LVGL 的具体开发请参考LVGL开发文档。
实现功能
- 本例使用 DMA 传输颜色数据到 SPI 总线,降低 CPU 的利用率,在进行简单交互时可以控制 CPU 的占用率在 50% 以下,内存占用在 35% 以下。
- 本例系统时钟为 200MHz ,设置 SPI 的外围时钟频率与系统时钟一致,同时使用 LVGL 库的双缓冲区机制,在进行一个缓冲区的数据传输时另一个缓冲区进行渲染,保证了动画的流畅度。
- 本例通过 LVGL 显示一张图片,展示了 LVGL 控件的简单运用。
编译运行
- Windows
- 参考Windows环境搭建教程完成环境搭建
- 打开 VS 2022->工具栏->命令行->开发者 Powershell
- 将你的 pico-sdk 所在绝对地址设置为 PICO_SDK_PATH,如我的 pico-sdk 地址为“D:\pico\pico-sdk”
setx PICO_SDK_PATH "D:\pico\pico-sdk"
- 下载例程,进入源码目录,如果 build 目录已经存在,则可以直接进入。如没有则创建该目录:
mkdir build cd build
- 执行 cmake ,自动生成 Makefile 文件:
cmake -G "NMake Makefiles" ..
- 执行 nmake 生成可执行文件,然后在终端中输入:
nmake
编译好后会生成一个 .uf2 格式的文件。 - 按住板上的 boot 按键,通过 Micro USB 线将板子接到电脑的 USB 接口,然后松开按键,电脑会将 pico 识别为一个可移动盘,最后将编译生成的 .uf2 格式的文件复制到 pico 即可
- Ubuntu
- 参考Pico入门使用手册的 Chapter 2. The SDK 完成环境搭建
- 打开一个 terminal,设置环境变量 PICO_SDK_PATH 的值为 pico-sdk 所在绝对地址,如我的 pico-sdk 地址为“/home/pico/pico-sdk”
nano ~/.bashrc #将以下内容添加到最后一行 export PICO_SDK_PATH="/home/pico/pico-sdk"
- 设置完后保存退出,使配置立即生效
source ~/.bashrc
- 下载例程,进入源码目录,如果 build 目录已经存在,则可以直接进入。如没有则创建该目录:
mkdir build cd build
- 执行 cmake ,自动生成 Makefile 文件:
cmake ..
- 执行 nmake 生成可执行文件,然后在终端中输入:
nmake
编译好后会生成一个 .uf2 格式的文件。 - 按住板上的 boot 按键,通过 Micro USB 线将板子接到电脑的 USB 接口,然后松开按键,电脑会将 pico 识别为一个可移动盘,最后将编译生成的 .uf2 格式的文件复制到 pico 即可
源码解析
源码结构
- LVGL 库的源码位于工程文件夹的 lib/lvgl ,使用的版本号为8.1,二次开发请参考对应版本的开发文档。
- LVGL 库的相关设置在工程文件夹的 examples/inc/lv_conf.h 中,可以设置显示刷新频率、系统占用数据等。
- LVGL 库的应用代码位于工程文件夹的 examples/src/LVGL_example.c 。
LVGL 初始化
在使用 LVGL 图像库之前,您需要先初始化 LVGL。
- LVGL 库的初始化函数
- 代码位置:examples/src/LVGL_example.c
- 实现功能:主要用于初始化 LVGL 所需的硬件和结构体变量。
LVGL_Init();
- LVGL 库核心初始化
- 代码位置:examples/src/LVGL_example.c
/*2.Init LVGL core*/ lv_init();
LVGL 运行
LVGL 库定时调用心跳接口函数 lv_tick_inc 来通知LVGL过去的时间,以便 LVGL 能够更新其内部的时间状态,处理与时间相关的任务,例如动画、定时器等。在主函数的循环中还需要调用 lv_task_handler 函数,以便 LVGL 及时处理事件和任务,保证用户界面的响应和刷新。
- LVGL 心跳接口
- 代码位置:examples/src/LVGL_example.c
- 实现方式:需要确保 lv_task_handler 的优先级低于 lv_tick_inc 的优先级,所以在本例中 lv_tick_inc 在定时器回调函数中调用。
//每5ms调用一次定时器回调函数 add_repeating_timer_ms(5, repeating_lvgl_timer_callback, NULL, &lvgl_timer); static bool repeating_lvgl_timer_callback(struct repeating_timer *t) { lv_tick_inc(5); return true; }
- LVGL 任务处理器
- 代码位置:examples/src/LCD_XinXX_LVGL_test.c
- 实现方式:要处理 LVGL 的任务,需要定期调用 lv_timer_handler(),本例中在主函数的循环中进行调用。
int main() { ... while(1) { lv_task_handler(); DEV_Delay_ms(5); ... } }
LVGL 显示
要实现 LVGL 显示,必须初始化一个显示驱动,并设置显示驱动的各个属性,例如,颜色格式、绘制缓冲区、渲染模式以及显示回调函数。在每个 LV_DISP_DEF_REFR_PERIOD(在 lv_conf.h 中设置),LVGL 会检测 UI 上是否发生了一些需要重绘的事情。例如,按下按钮、更改图表、发生动画等。需要重新绘制时,LVGL 调用显示回调函数完成图像在刷新区的绘制。
- LVGL 显示刷新率设置
- 代码位置:examples/inc/lv_conf.h
- 设置方式:在 lv_conf.h 中还能设置显示缓冲区刷新频率的时间,可以修改这个定义来改变屏幕的刷新时间。
#define LV_DISP_DEF_REFR_PERIOD 10 // 单位:ms,这里为10ms
- LVGL 显示颜色设置
- 代码位置:examples/inc/lv_conf.h
- 设置目的:由于 lv_color_t 结构体在默认状态下所构建的像素颜色储存方式与本例需要传输的数据不一致,直接进行传输会导致显示的图像出现色差。
#define LV_COLOR_16_SWAP 1
- LVGL 显示相关变量定义
- 代码位置:examples/src/LVGL_example.c
- 实现功能:定义显示驱动 disp_drv,绘制缓冲区 disp_buf。本例实现双缓冲机制,绘制缓冲区由缓冲区 buf0 和 buf1 组成,大小均设置为屏幕显示面积的一半,能够在降低大面积刷屏锯齿的同时有效提高屏幕刷新率;在使用单缓冲区时最好设置为屏幕显示面积的 10%,可以有效降低系统占用但在大面积图像刷新时会出现较明显的锯齿。
static lv_disp_drv_t disp_drv; static lv_disp_draw_buf_t disp_buf; static lv_color_t buf0[DISP_HOR_RES * DISP_VER_RES/2]; static lv_color_t buf1[DISP_HOR_RES * DISP_VER_RES/2];
- LVGL 显示设备注册
- 代码位置:examples/src/LVGL_example.c
- 实现功能:根据设计需求完善 LVGL 库核心结构体变量,初始化显示驱动 disp_drv,并设置绘制缓冲区,该缓冲区是 LVGL 用来渲染屏幕内容的简单数组。一旦渲染准备就绪,绘制缓冲区的内容将使用显示驱动程序中设置的 disp_drv_flush_cb 函数发送到显示器。
/*3.Init LVGL display*/ lv_disp_draw_buf_init(&disp_buf, buf0, buf1, DISP_HOR_RES * DISP_VER_RES / 2); lv_disp_drv_init(&disp_drv); disp_drv.flush_cb = disp_flush_cb; disp_drv.draw_buf = &disp_buf; disp_drv.hor_res = DISP_HOR_RES; disp_drv.ver_res = DISP_VER_RES; lv_disp_t *disp= lv_disp_drv_register(&disp_drv);
- LVGL 显示回调函数
- 代码位置:examples/src/LVGL_example.c
- 实现功能:主要完成图像在刷新区的绘制。
void disp_flush( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p ) 参数: lv_disp_drv_t *disp_drv: 显示驱动结构体指针,包含了与显示相关的信息和函数指针。该参数常用于通知刷新完成 const lv_area_t *area : 区域结构体指针,包含待刷新区域的位置信息。在本例中,用于创建 TFT 显示的窗口 lv_color_t *color_p : 颜色结构体指针,表示要在刷新区域内显示的颜色数据。在本例中,作为DMA输入读取地址将数据传输到SPI总线,完成图像的绘制
- LVGL 显示回调函数实现
- 代码位置:examples/src/LVGL_example.c
- 实现方式:在本例中为了最大化降低处理器的利用率,使用 DMA 来进行颜色数据的传输,设置 color_p 作为读地址,SPI 总线的输出数据寄存器为写地址。
static void disp_flush_cb(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p) { LCD_SetWindows(area->x1, area->y1, area->x2+1, area->y2+1); DEV_Digital_Write(LCD_DC_PIN, 1); DEV_Digital_Write(LCD_CS_PIN, 0); dma_channel_configure(dma_tx, &c, &spi_get_hw(LCD_SPI_PORT)->dr, color_p, // read address ((area->x2 + 1 - area-> x1)*(area->y2 + 1 - area -> y1))*2, true); }
- LVGL 刷新完成通知实现
- 代码位置:examples/src/LVGL_example.c
- 实现功能:每一次图像刷新完成后都需要通知 LVGL 核心,以便 LVGL 准备下个刷新图像的渲染。
- 实现方式:本例在 DMA 传输完成中断服务函数中通知 LVGL 图像刷新完成,如果使用阻塞通知的机制就无法利用双缓冲机制来提高刷新速度。
static void dma_handler(void) { if (dma_channel_get_irq0_status(dma_tx)) { dma_channel_acknowledge_irq0(dma_tx); DEV_Digital_Write(LCD_CS_PIN, 1); lv_disp_flush_ready(&disp_drv); } }
LVGL 控件布局
在 LVGL 中,我们能够建立各种不同的用户界面。界面的基本组成部分是对象,也称为控件(Widgets),比如按钮(Button)、标签(Label)、图像(Image)、列表(List)、图表或文本区域。在一个界面中,可以同时创建多个控件,并且我们可以设置它们的位置、尺寸、父对象、样式以及事件处理程序等基本属性。
- LVGL 控件初始化
- 代码位置:examples/src/LVGL_example.c
- 实现功能:主要用于风格化控件和布局控件。
void Widgets_Init(void);
- LVGL 创建图块
- 代码位置:examples/src/LVGL_example.c
- 实现功能:Tile 视图是一个容器对象,其元素(称为图块)可以按网格形式排列。用户可以通过滑动来在各个图块之间导航。调用 lv_tileview_add_tile(tileview, row_id, col_id, dir) 在第 row_id 行和第 col_id 列上创建一个新图块。dir可以是 LV_DIR_LEFT/RIGHT/TOP/BOTTOM/HOR/VER/ALL 或值,以便通过滑动移动到给定方向的相邻图块。
//在 (0,0) 创建一个图块,支持向下滑动到 (0,1) tile1 = lv_tileview_add_tile(tv, 0, 0, LV_DIR_BOTTOM);
- LVGL 创建控件
- 代码位置:examples/src/LVGL_example.c
- 实现功能:创建控件,不同控件需要使用不同的函数接口,可以选择父对象进行创建。
//创建一个控件,其中 tab1 为该按键的父对象,可以替换为list、title等可以有子对象的控件 sw = lv_switch_create(tab1);
- LVGL 控件的对齐定位
- 代码位置:examples/src/LVGL_example.c
- 实现功能:使控件能够基于参考点进行偏移定位。控件对齐偏移的参考点控件的中心。
- 对齐标准: LVGL 库具备内部对齐和外部对齐两种方式。默认以左上角作为原点,向左为水平方向的正方向,向下为垂直方向的正方向。
- LVGL 控件切换字体大小
- 代码位置:examples/inc/lv_conf.h、examples/src/LVGL_example.c
- 实现功能:在实际运用时一个界面可能需要运用多种字体大小,可以在 lv_conf.h 中使能多种字体大小,且可以设置默认字体大小。设置字体大小时需要对控件风格化,使控件能够按照设置的风格进行渲染。利用 lv_obj_add_style 函数可以实现对控件各个部位在不同状态下的渲染。
#define LV_FONT_MONTSERRAT_16 1 // 使能16号字体 #define LV_FONT_MONTSERRAT_18 1 // 使能18号字体 #define LV_FONT_DEFAULT &lv_font_montserrat_18 // 设置默认字体大小为18号 static lv_style_t style_label; lv_style_init(&style_label); // 初始化风格 lv_style_set_text_font(&style_label, &lv_font_montserrat_16); // 设置字体大小为16号 lv_obj_add_style(label,&style_label,0); // 设置label主题的风格
- LVGL 控件事件处理
- 代码位置:examples/src/LVGL_example.c
- 实现功能:在 LVGL 中,可以给控件添加事件处理回调函数,使控件发生被点击、滚动、重绘等事件时,触发事件从而进入事件处理回调函数。在程序中调用 lv_obj_add_event_cb(obj, event_cb, filter, user_data)函数,为控件 obj 添加事件 filter 的处理函数 event_cb,当控件 obj 触发 filter 事件时,系统会自动调用 event_cb 函数。最后一个参数是指向事件中可用的任何自定义数据的指针。
//为控件 sw 添加事件 LV_EVENT_VALUE_CHANGED 的处理函数 sw_event_cb lv_obj_add_event_cb(sw, sw_event_cb,LV_EVENT_VALUE_CHANGED,NULL);
Python
示例效果
本例显示的效果为通过LVGL显示一张图片。
示例简介
本例用于测试 LVGL 控件交互、样式美化等,使用的版本号为9.1,LVGL V9 的开发文档中没有提供 Python 示例,具体开发请参考LVGL开发文档。
实现功能
- 本例系统时钟为 230MHz ,设置 SPI 的外围时钟频率与系统时钟一致,同时使用 LVGL 库的双缓冲区机制,在进行一个缓冲区的数据传输时另一个缓冲区进行渲染,保证了动画的流畅度。
- 本例通过 LVGL 显示一张图片,展示了 LVGL 控件的简单运用。
编译运行
- 操作步骤
- 开始使用前,需要设置集成开发环境 Thonny Python IDE (Windows版本 V3.3.3)
- 下载例程,按住板上的 boot 按键,通过 Micro USB 线将板子接到电脑的 USB 接口,然后松开按键,电脑会将 pico 识别为一个可移动盘,将 Python 目录下的 .uf2 格式的文件复制到 pico 中
- 打开 Thonny,将例程中的 examples 、 lib 目录上传至开发板
- 打开 examples 目录下的文件 LCD_1in14_LVGL_test.py,参考下图步骤运行程序
- 构建固件
- 构建环境:仅测试 Ubuntu 22.04
- Github:lv_micropython
- 参考 Raspberry Pi Pico port 部分 进行编译
- 固件生成路径:lv_micropython/ports/rp2/build-PICO/firmware.uf2
源码解析
源码结构
- LVGL 库的源码请参考 lv_micropython
- LVGL 库的相关设置在 lv_micropython仓库/lib/lv_bindings/lv_conf.h 文件中,可以设置显示刷新频率、系统占用数据等。
- LVGL 库的应用代码位于工程文件夹的 examples/LVGL_example.py 、 lib/LVGL.py。
LVGL 初始化
在使用 LVGL 图像库之前,您需要导入 LVGL 库并初始化 LVGL 对象
- 导入 LVGL 库
- 代码位置:lib/LVGL.py
- 实现功能:导入 LVGL 库,并使用别名 "lv" 以方便调用其功能
import lvgl as lv
- 创建 LVGL 对象
- 代码位置:examples/LCD_1in14_LVGL_test.py
- 实现功能:创建 LVGL 对象,并传入 LCD 和 TSC 对象作为参数
# Init LVGL LVGL(LCD=LCD,TSC=TSC)
- LVGL 初始化
- 代码位置:lib/LVGL.py
- 代码说明:LVGL 核心初始化位于 LVGL 类的初始化函数,在创建 LVGL 对象时自动调用
if not lv.is_initialized(): lv.init()
LVGL 运行
LVGL 库定时调用心跳接口函数 lv.tick_inc 来通知 LVGL 过去的时间,以便 LVGL 能够更新其内部的时间状态,处理与时间相关的任务,例如动画、定时器等。此外还需要调用 lv.task_handler 函数,以便 LVGL 及时处理事件和任务,保证用户界面的响应和刷新。
- LVGL 运行接口
- 代码位置:lib/LVGL.py
- 实现方式:创建一个 event_loop 对象。在该类的初始化函数中,我们创建一个定时器。该定时器会在设定的时间间隔内自动调用心跳接口函数和事件处理函数。调用的时间间隔可以通过传递 freq 参数调节,例如 lv_utils.event_loop(freq=200),默认为 40 ms。
# Create event loop if not yet present if not lv_utils.event_loop.is_running(): self.event_loop=lv_utils.event_loop()
- LVGL 心跳接口
- 代码位置:lib/lv_utils.py
- 实现方式:需要确保 lv.task_handler 的优先级低于 lv.tick_inc 的优先级,所以在本例中,lv.tick_inc 在定时器回调函数中调用。
#每 5ms 调用一次定时器回调函数 self.timer.init(mode=Timer.PERIODIC, period=self.delay, callback=self.timer_cb) // 本例中 self.delay = 5 def timer_cb(self, t): lv.tick_inc(self.delay) if self.scheduled < self.max_scheduled: try: micropython.schedule(self.task_handler_ref, 0) self.scheduled += 1 # 正在处理的任务数增加 except: pass
- LVGL 任务处理器
- 代码位置:lib/lv_utils.py
- 实现方式:要处理 LVGL 的任务,需要定期调用 lv.task_handler,本例在定时器回调函数中调用 lv.tick_inc 之后再进行调用。
def task_handler(self, _): try: if lv._nesting.value == 0: lv.task_handler() if self.refresh_cb: self.refresh_cb() self.scheduled -= 1 # 正在处理的任务数减少 except Exception as e: if self.exception_sink: self.exception_sink(e)
LVGL 显示
要实现 LVGL 显示,必须初始化一个显示驱动,并设置显示驱动的各个属性,例如,颜色格式、绘制缓冲区、渲染模式以及显示回调函数。在每个 LV_DEF_REFR_PERIOD(在 lv_conf.h 中设置),LVGL 会检测 UI 上是否发生了一些需要重绘的事情。例如,按下按钮、更改图表、发生动画等。需要重新绘制时,LVGL 调用显示回调函数完成图像在刷新区的绘制。
- LVGL 显示刷新率设置
- 代码位置:lv_micropython仓库/lib/lv_bindings/lv_conf.h
- 设置方式:在 lv_conf.h 中可以修改 LV_DEF_REFR_PERIOD 来改变屏幕的刷新时间。
#define LV_DEF_REFR_PERIOD 10 // 单位:ms,这里为10ms
- LVGL 显示相关变量定义
- 代码位置:lib/LVGL.py
- 实现功能:buf0 和 buf1 大小设置为屏幕显示面积的 33% 是为了实现 LVGL 双缓冲机制,能够在降低大面积刷屏锯齿的同时有效提高屏幕刷新率;在使用单缓冲区时最好设置为屏幕显示面积的 10%,可以有效降低系统占用但在大面积图像刷新时会出现较明显的锯齿。
# Init LVGL display buf1 = lv.draw_buf_create(self.LCD.width, self.LCD.height // 3 , color_format, 0) buf2 = lv.draw_buf_create(self.LCD.width, self.LCD.height // 3, color_format, 0)
- LVGL 显示设备注册
- 代码位置:lib/LVGL.py
- 实现功能:根据设计需求完善 LVGL 库核心结构体变量,初始化显示驱动 disp_drv,并设置绘制缓冲区,该缓冲区是 LVGL 用来渲染屏幕内容的简单数组。一旦渲染准备就绪,绘制缓冲区的内容将使用显示驱动程序中设置的 disp_drv_flush_cb 函数发送到显示器。
self.disp_drv = lv.display_create(self.LCD.width, self.LCD.height) # 创建显示驱动器对象,并设置宽度和高度 self.disp_drv.set_color_format(color_format) # 设置颜色格式为 RGB565 self.disp_drv.set_draw_buffers(buf1, buf2) # 设置绘制缓冲区 self.disp_drv.set_render_mode(lv.DISPLAY_RENDER_MODE.PARTIAL) # 设置渲染模式为部分刷新模式 self.disp_drv.set_flush_cb(self.disp_drv_flush_cb) # 设置显示回调函数
- LVGL 显示回调函数
- 代码位置:lib/LVGL.py
- 实现功能:主要完成图像在刷新区的绘制。
def disp_drv_flush_cb(self,disp_drv,area,color_p) 参数: disp_drv : 显示驱动结构体指针,包含了与显示相关的信息和函数指针。该参数常用于通知刷新完成 area : 区域结构体指针,包含待刷新区域的位置信息。在本例中,用于创建 TFT 显示的窗口 color_p : 颜色结构体指针,表示要在刷新区域内显示的颜色数据。在本例中,作为DMA输入读取地址将数据传输到SPI总线,完成图像的绘制
- LVGL 显示回调函数实现
- 代码位置:lib/LVGL.py
- 实现方式:在本例中为了最大化降低处理器的利用率,使用 DMA 来进行颜色数据的传输,设置 color_p 作为读地址,SPI 总线的输出数据寄存器为写地址。代码较长仅展示部分,完整代码请下载示例查看。
def disp_drv_flush_cb(self,disp_drv,area,color_p): ...... self.rgb565_swap_func(data_view, size) # 转换颜色格式 self.LCD.setWindows(area.x1, area.y1, area.x2+1, area.y2+1) # 设置 LVGL 界面显示位置 ...... # DMA 配置立即执行 while self.dma.active(): # 等待 DMA 空闲 pass self.disp_drv.flush_ready() # 通知 LVGL 数据传输完成
LVGL 控件布局
在 LVGL 中,我们能够建立各种不同的用户界面。界面的基本组成部分是对象,也称为控件(Widgets),比如按钮(Button)、标签(Label)、图像(Image)、列表(List)、图表或文本区域。在一个界面中,可以同时创建多个控件,并且我们可以设置它们的位置、尺寸、父对象、样式以及事件处理程序等基本属性。
- 创建 LVGL 界面对象
- 代码位置:examples/LVGL_example.py
- 实现功能:创建 LVGL 界面对象,并传入 LCD 对象作为参数
# Init WIDGETS WIDGETS(LCD=LCD)
- LVGL 创建图块
- 代码位置:examples/LVGL_example.py
- 实现功能:Tile 视图是一个容器对象,其元素(称为图块)可以按网格形式排列。用户可以通过滑动来在各个图块之间导航。使用 Tile 视图对象调用 add_tile(tileview, row_id, col_id, dir) 在第 row_id 行和第 col_id 列上创建一个新图块。dir可以是 lv.DIR.LEFT/RIGHT/TOP/BOTTOM/HOR/VER/ALL 或值,以便通过滑动移动到给定方向的相邻图块。
//在 (0,0) 创建一个图块,支持向下滑动到 (0,1) self.tv = lv.tileview(self.scr) self.tile1 = self.tv.add_tile(0, 0, lv.DIR.BOTTOM)
- LVGL 创建控件
- 代码位置:examples/LVGL_example.py
- 实现功能:创建控件,不同控件需要使用不同的函数接口,可以选择父对象进行创建。
//创建一个 table 控件,其中 tile2 为该控件的父对象,可以替换为list、title等可以有子对象的控件 self.table_imu_data = lv.table(self.tile2)
- LVGL 控件的对齐定位
- 代码位置:examples/LVGL_example.py
- 实现功能:使控件能够基于参考点进行偏移定位。控件对齐偏移的参考点控件的中心。
- 对齐标准: LVGL 库具备内部对齐和外部对齐两种方式。默认以左上角作为原点,向左为水平方向的正方向,向下为垂直方向的正方向。
- LVGL 控件切换字体大小
- 代码位置:lv_micropython仓库/lib/lv_bindings/lv_conf.h、examples/LVGL_example.py
- 实现功能:在实际运用时一个界面可能需要运用多种字体大小,可以在 lv_conf.h 中使能多种字体大小,且可以设置默认字体大小。设置字体大小时需要对控件风格化,使控件能够按照设置的风格进行渲染。利用 add_style 函数可以实现对控件各个部位在不同状态下的渲染。
#define LV_FONT_MONTSERRAT_16 1 // 使能16号字体 #define LV_FONT_MONTSERRAT_18 1 // 使能18号字体 #define LV_FONT_DEFAULT &lv_font_montserrat_18 // 设置默认字体大小为18号 table_imu_data= lv.style_t() // 创建对象 table_imu_data.init() // 初始化 table_imu_data.set_text_font(lv.font_montserrat_16) // 设置字体大小为16 self.table_imu_data.add_style(style_imu_table, 0) // 设置风格
picoprobe使用教程
安装OpenOCD
Linux (and Raspberry Pi)
下载依赖库
sudo apt install automake autoconf build-essential texinfo libtool libftdi-dev libusb-1.0-0-dev
获取并编译
git clone https://github.com/raspberrypi/openocd.git cd openocd ./bootstrap ./configure make -j4 sudo make install
Windows
- 因为OpenOCD自编译在windows环境下比较复杂,推荐使用已经编译好的版本
- 解压并存放在比较短的目录中,如直接存放在C盘中
添加环境变量
- 点击“开始”菜单,搜索“环境变量”。
- 点击“编辑系统环境变量”
- 双击“path”变量,进入编辑界面。
- 添加新的路径
- ①创建新变量地址
- ②输入OpenOCD的存放地址
- ③点击 确定进行保存
- 点击“确定”保存更改。
- 重启电脑
安装GDB
Linux (and Raspberry Pi)
- 安装gdb-multiarch
sudo apt install gdb-multiarch
Windows
- 如果你已经正确安装了pico-sdk相关的环境,则跳过此步骤,因为GDB已经被Arm GNU Toolchain包含
- 如果你未安装pico-sdk相关的环境,建议使用官方提供pico安装程序进行安装
sudo openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000" -c "program blink.elf verify reset exit"
使用Pcio Debug Probe烧录及调试
烧录程序
- Pico Debug Probe 可让您通过 SWD 端口和 OpenOCD 加载二进制文件
- 每次将新二进制文件推送到 Pico 时,您无需拔下然后按住 BOOTSEL 按钮
- 以对RP2350使用为例,烧录程序指令为
sudo openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000" -c "program {你的elf文件名}.elf verify reset exit"
调试程序
打开OpenOCD服务器
- 你可以让openocd在服务器模式下使用,并连接 GDB,从而为您提供断点和“正确”调试。
使用GDB命令行
- 本例程基于pico-sdk环境搭建完成,并且pico-example编译完成
- 打开powershell并进入对应的build文件夹,这里以blink例程为例
- 打开gbd,输入以下指令
- 如果为windows输入指令为
arm-none-eabi-gdb blink.elf
- 如果为linux输入指令为
gdb blink.elf
- 如果为windows输入指令为
- 依次输入以下指令
target remote localhost:3333 load continue
使用VSCode调试
- 请确保前文打开OpenOCD服务器与使用GDB命令行运行正常
- 请确保Pico编译环境搭建正常
- 请确保你的VSCode安装以下插件
- Cortex-Debug
- Cmake-tools
- C/C++
- 首先打开OpenOCD服务器
- 使用VSC打开pico-examples文件夹并打开blink例程
- 使用快捷键F1并输入以下指令
open 'launch.json'
- 打开后将下文放入其中
- 若为Windows系统则输入
{ "version": "0.2.0", "configurations": [ { "name": "Pico Debug", "type":"cortex-debug", "cwd": "${workspaceRoot}", "executable": "${command:cmake.launchTargetPath}", "request": "launch", "servertype": "external", // This may need to be arm-none-eabi-gdb depending on your system "gdbPath" : "gdb", // Connect to an already running OpenOCD instance "gdbTarget": "localhost:3333", "svdFile": "${env:PICO_SDK_PATH}/src/rp2350/hardware_regs/rp2350.svd", "runToMain": true, // Work around for stopping at main on restart "postRestartCommands": [ "break main", "continue" ] } ] }
- 若linux系统则输入
{ "version": "0.2.0", "configurations": [ { "name": "Pico Debug", "type":"cortex-debug", "cwd": "${workspaceRoot}", "executable": "${command:cmake.launchTargetPath}", "request": "launch", "servertype": "external", // This may need to be arm-none-eabi-gdb depending on your system "gdbPath" : "arm-none-eabi-gdb", // Connect to an already running OpenOCD instance "gdbTarget": "localhost:3333", "svdFile": "${env:PICO_SDK_PATH}/src/rp2350/hardware_regs/rp2350.svd", "runToMain": true, // Work around for stopping at main on restart "postRestartCommands": [ "break main", "continue" ] } ] }
- 两者区别为调用的gdb不同
- 进入运行与调试界面 快捷键 Ctrl+Shift+D
- ①将pico debug选为 调试器
- ②将CMake选为 debug模式
- ③开始调试按键,快捷键F5
- ④选择调试对象选为blink
- 点击调试按键进入调试模式,快捷键F5
- 出现调试工具栏
- ①重启设备
- ②继续运行程序
- ③单步执行
- ④进入函数运行
- ⑤跳出函数运行
- ⑥停止调试
- 点击继续运行程序 快捷键F5,即可看到pico运行blink例程
使用Pico VSCode烧录及调试(推荐)
- 使用前请先安装Pico VSCode插件。
- 安装Pico VSCode插件后无需额外搭建环境,可按以下步骤进行烧录和调试程序。
导入工程
烧录程序
调试程序
资料
配套资料
文档
程序
官方资料
树莓派官方文档
树莓派开源例程