RP2040-Touch-LCD-1.69
说明
| ||||||||||||||||||||
| ||||||||||||||||||||
产品概述
RP2040-Touch-LCD-1.69 是一款微雪(Waveshare)设计的低成本,高性能的微控制器开发板。在较小的板型下,板载了1.69英寸电容触摸LCD屏、锂电池充电芯片、六轴传感器(三轴加速度计与三轴陀螺仪)、RTC、蜂鸣器等外设,方便开发并嵌入应用到产品中。
产品特性
- 采用了Raspberry Pi研发的 RP2040 微控制器芯片
- 搭载了双核 ARM Cortex M0 + 处理器,运行频率高达 133MHz 灵活时钟
- 内置了 264KB 的 SRAM 和 4MB 的片上 Flash
- 采用Type-C接口,紧跟时代潮流,无需纠结正反插
- 板载 1.69 英寸电容触摸 LCD 屏,240×280 分辨率,262K 彩色
- 板载锂电池充放电接口,有利于移动场景使用
- 板载 RTC 时钟芯片、RTC 电池接口,方便计时定时功能
- 板载蜂鸣器可做听觉外设使用
- USB1.1 主机和设备支持
- 支持低功耗睡眠和休眠模式
- 可通过 USB 识别为大容量存储器进行拖放式下载程序
- 精确的片上时钟和定时器
- 温度传感器
- 片上加速浮点库
产品参数
LCD参数 | |||
触摸芯片 | CST816T | 触摸接口 | I2C |
显示芯片 | ST7789V2 | 显示接口 | SPI |
分辨率 | 240(H)RGB x 280(V) | 显示尺寸 | 27.972mm × 32.634mm |
显示面板 | IPS | 像素间距 | 0.11655mm × 0.11655mm |
IMU参数 | |||
传感器名称 | QMI8658 | ||
加速度计特性 | 分辨率:16 位 量程 (可选):±2、±4、±8、±16g | ||
陀螺仪特性 | 分辨率:16 位 量程 (可选):±16、±32、±64、±128、±256、±512、 ±1024、±2048°/sec |
注意事项
- 圆形触摸屏的边缘,触摸灵敏和准确度会有所下降,这是圆形触摸屏的结构导致的。
引脚分布
尺寸图
Pico快速上手
固件下载
| ||
|
文字教程
基础介绍
MicroPython系列
【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++】 Windows教程1——环境搭建
【C/C++】 Windows教程2——创建工程
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/global/package_rp2040_index.json
注意:如果您已经有ESP32板URL,您可以使用逗号分隔 URL,如下所示:https://dl.espressif.com/dl/package_esp32_index.json,https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
-
点击工具>开发板>开发板管理器>搜索pico,由于我的电脑已经安装过了,所以显示已安装
国内用户
- 因为网络原因,国内用户连接github并不稳定,我们另外提供了一份安装包,可以跳过在线的过程
- 若已经成功配置了pico环境,可以直接跳过本章
-
下载rp2040压缩包,将解压的rp2040文件夹复制到如下路径下
C:\Users\[username]\AppData\Local\Arduino15\packages
第一次上传程序
- 下载程序,打开arduino\PWM\D1-LED路径下的D1-LED.ino
-
点击工具>端口,记住已有的COM,不需要点击这个COM(不同电脑显示的COM不一样,记住自己电脑上已有的COM)
-
用USB线将驱动板和计算机连接起来,再点击工具>端口,第一次连接选择uf2 Board,上传完成后,再次连接就会多出一个COM口
-
点击工具>开发板>Raspberry Pi Pico/RP2040>Raspberry Pi Pico
- 设置完成后,点击向右箭头上传将程序
- 如果期间遇到了问题,需要重新安装或者更换Arduino IDE版本时,卸载Arduino IDE需要卸载干净,卸载软件后需要手动删除C:\Users\[name]\AppData\Local\Arduino15这个文件夹内的所有内容(需要显示隐藏文件才能看到) 再重新安装
开源例程
MircoPython视频例程(github)
MicroPython固件/Blink例程(C)
树莓派官方C/C++示例程序 (github)
树莓派官方micropython示例程序 (github)
Arduino官方C/C++示例程序 (github)
应用示例
LVGL 示例程序
示例效果
本例显示的效果为四个可以通过触摸屏滑动切换的界面。
- 第一个界面
- 第二个界面
- 第三个界面
- 第四个界面
示例简介
本例用于测试 LVGL 控件交互、样式美化等, LVGL 的具体开发请参考LVGL开发文档。
实现功能
- 本例使用 DMA 传输颜色数据到 SPI 总线,降低 CPU 的利用率,在进行简单交互时可以控制 CPU 的占用率在 50% 以下,内存占用在 35% 以下。
- 本例系统时钟为 200MHz ,设置 SPI 的外围时钟频率与系统时钟一致,同时使用 LVGL 库的双缓冲区机制,在进行一个缓冲区的数据传输时另一个缓冲区进行渲染,保证了动画的流畅度。
- 本例使用触摸屏切换界面,实现实时展示六轴传感器、RTC数据,通过控件实时控制蜂鸣器开关、频率以及屏幕亮度,展示了 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 格式的文件复制到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 ..
- 执行 make 生成可执行文件,然后在终端中输入:
make
等待编译好后将生成的 .uf2 格式的文件复制到pico中即可。
源码解析
源码结构
- LVGL 库的源码位于工程文件夹的 lib/lvgl ,使用的版本号为8.1,二次开发请参考对应版本的开发文档。
- LVGL 库的相关设置在工程文件夹的 examples/inc/lv_conf.h 中,可以设置显示刷新频率、系统占用数据等。
- LVGL 库的应用代码位于工程文件夹的 examples/src/LVGL_example.c 。
LVGL 初始化
LVGL 库的初始化流程主要就是对几个 LVGL 核心结构体变量的初始化,LVGL 库的运行依靠核心结构体变量。
- LVGL 库的初始化函数
- 代码位置:examples/src/LVGL_example.c
- 实现功能:主要用于初始化 LVGL 所需的硬件和结构体变量。
void Widgets_Init(void);
- LVGL 库核心结构体变量定义
- 代码位置:examples/src/LVGL_example.c
- 定义方式:buf0 和 buf1 大小设置为屏幕显示面积的一半是为了实现 LVGL 双缓冲机制,能够在降低大面积刷屏锯齿的同时有效提高屏幕刷新率;在使用单缓冲区时最好设置为屏幕显示面积的10%,可以有效降低系统占用但在大面积图像刷新时会出现较明显的锯齿。
// LVGL static lv_disp_draw_buf_t disp_buf; //LVGL绘制缓冲区 static lv_color_t buf0[DISP_HOR_RES * DISP_VER_RES/2];//LVGL颜色数据缓冲区0 static lv_color_t buf1[DISP_HOR_RES * DISP_VER_RES/2];//LVGL颜色数据缓冲区1 static lv_disp_drv_t disp_drv; //LVGL显示驱动 static lv_indev_drv_t indev_ts; //LVGL触摸屏输入设备驱动
- LVGL 库的初始化函数实现
- 代码位置:examples/src/LCD_1in69_LVGL_test.c、examples/src/LVGL_example.c
- 实现功能:根据设计需求完善 LVGL 库核心结构体变量,初始化绘制缓冲区。绘制缓冲区 disp_buf 通过调用 lv_disp_draw_buf_init 实现初始化,该缓冲区是 LVGL 用来渲染屏幕内容的简单数组。 一旦渲染准备就绪,绘制缓冲区的内容将使用显示驱动程序中设置的 flush_cb 函数发送到显示器。
// 初始化LVGL核心 lv_init(); // 初始化LVGL显示缓冲区结构体变量disp_buf 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 运行
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 显示
在每个 LV_DISP_DEF_REFR_PERIOD(在 lv_conf.h 中设置),LVGL 会检测 UI 上是否发生了一些需要重绘的事情。例如,按下按钮、更改图表、发生动画等。需要重新绘制时,LVGL 调用显示回调函数完成图像在刷新区的绘制。
- 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/inc/lv_conf.h
- 设置目的:由于 lv_color_t 结构体在默认状态下所构建的像素颜色储存方式与本例需要传输的数据不一致,直接进行传输会导致显示的图像出现色差。
#define LV_COLOR_16_SWAP 1
- LVGL 显示刷新率设置
- 代码位置:examples/inc/lv_conf.h
- 设置方式:在 lv_conf.h 中还能设置显示缓冲区刷新频率的时间,可以修改这个定义来改变屏幕的刷新时间。
#define LV_DISP_DEF_REFR_PERIOD 10 // 单位:ms,这里为10ms
- 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 中,允许用户注册输入设备,如触摸板、鼠标、键盘或编码器等设备。用户可以通过这些输入设备控制用户界面,实现更好的交互。
- LVGL 的输入设备回调函数
- 代码位置:examples/src/LVGL_example.c
- 实现功能:主要用于更新输入事件。
static void ts_read_cb(lv_indev_drv_t * drv, lv_indev_data_t*data); 参数: lv_indev_drv_t *indev_drv: LVGL 中的输入设备驱动结构体指针。在本例中,该结构体为触摸屏输入设备驱动 lv_indev_data_t *data : LVGL 中的输入设备数据结构体指针。在本例中,该结构体用于存储输入设备的状态和数据,包括当前的触摸状态(按下或释放)以及触摸点的坐标
- LVGL 调用输入设备回调函数的频率设置
- 代码位置:examples/inc/lv_conf.h
- 设置方式: LVGL 默认每 30ms 调用一次输入设备回调函数来更新输入设备所触发的事件,可以在 lv_conf.h 中进行设置。
#define LV_INDEV_DEF_READ_PERIOD 30 // 单位:ms,这里为30ms
- 触摸屏输入设备的回调函数实现
- 代码位置:examples/src/LVGL_example.c
- 实现方式:主要是通过触摸中断更新触摸屏的触摸状态和触摸点坐标。
static void touch_callback(uint gpio, uint32_t events) { if (gpio == Touch_INT_PIN) { CST816S_Get_Point(); gesture = CST816S_Get_Gesture(); ts_x = Touch_CTS816.x_point; ts_y = Touch_CTS816.y_point; ts_act = LV_INDEV_STATE_PRESSED; } } static void ts_read_cb(lv_indev_drv_t * drv, lv_indev_data_t*data) { data->point.x = ts_x; data->point.y = ts_y; data->state = ts_act; ts_act = LV_INDEV_STATE_RELEASED; }
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
- 实现功能:创建控件,不同控件需要使用不同的函数接口,可以选择父对象进行创建。
//创建一个控件,其中 tile4 为该按键的父对象,可以替换为list、title等可以有子对象的控件 lv_obj_t *btn = lv_btn_create(tile4);
- LVGL 控件的对齐定位
- 代码位置:examples/src/LVGL_example.c
- 实现功能:使控件能够基于参考点进行偏移定位。控件对齐偏移的参考点控件的中心。
- 对齐标准: LVGL 库具备内部对齐和外部对齐两种方式。默认以左上角作为原点,向左为水平方向的正方向,向下为垂直方向的正方向。
//将btn控件定位在中心点向左偏移50个像素,向下偏移50个像素的位置 lv_obj_align(btn, LV_ALIGN_CENTER, -50 , 50);
![RP2040-Touch-LCD-1.28-LVGL-align.png](/w/upload/3/36/RP2040-Touch-LCD-1.28-LVGL-align.png)
- LVGL 控件切换字体大小
- 代码位置:examples/inc/lv_conf.h、examples/src/LVGL_example.c
- 实现功能:在实际运用时一个界面可能需要运用多种字体大小,可以在 lv_conf.h 中使能多种字体大小,且可以设置默认字体大小。设置字体大小时需要对控件风格化,使控件能够按照设置的风格进行渲染。利用 lv_obj_add_style 函数可以实现对控件各个部位在不同状态下的渲染。
#define LV_FONT_MONTSERRAT_14 1 // 使能14号字体 #define LV_FONT_MONTSERRAT_16 1 // 使能16号字体 #define LV_FONT_DEFAULT &lv_font_montserrat_14 // 设置默认字体大小为14号 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);
资料
配套资料
示例程序
原理图
数据手册
官方资料
树莓派官方文档
- Raspberry Pi Pico入门学习MicroPython编程书籍(英文版)
- 树莓派相关书籍下载
- Raspberry Pi Pico原理图
- Pico引脚分布图
- Pico入门使用手册
- Pico C SDK使用手册
- Pico Python SDK使用手册
- Pico数据手册
- RP2040数据手册
- RP2040硬件设计参考手册
树莓派开源例程
开发软件
FAQ