


本章节包含以下部分,请按需阅读:
初次接触 Pico MicroPython 开发,想要快速上手?我们为您准备了一套通用的入门教程。此教程旨在帮助开发者快速熟悉 Thonny IDE 并上手开发。教程内容涵盖环境搭建、项目创建、组件使用及外设编程等,帮助您迈出 MicroPython 编程的第一步。
请参考 安装和配置 Thonny IDE 教程 下载安装 Thonny IDE。
MicroPython 示例程序位于 示例程序包 的 examples\MicroPython 目录中。
| 示例程序 | 基础例程说明 | 依赖库 |
|---|---|---|
| 01_SD | 挂载 SD 卡 | - |
| 02_RTC | 获取 RTC 数据 | - |
| 03_GUI | GUI 显示程序 | - |
| 04_KEY | 按键测试 | - |
| 05_SHTC3 | 温湿度传感器测试 | - |
| 06_TOUCH | 触摸屏测试 | - |
| 07_ES8311 | ES8311 音频录音与播放测试 | - |
【程序说明】
【硬件连接】
【代码分析】
sdcard.SDCard(spi, cs, baudrate):创建 SD 卡对象,并将初始化的 SPI 接口与 CS 引脚绑定到 SD 卡驱动中。uos.mount(sd, '/sd'):将 SD 卡文件系统挂载到 /sd 目录下。挂载成功后,用户即可通过 /sd 路径对 SD 卡进行文件读写操作,例如创建、读取或删除文件。【运行效果】
通过 thonny 将 01_SD 文件下的所有 py 文件上传到开发板中,并复位。开发板复位后会根据 boot.py 的程序,自动将 SD 挂载到 sd 目录下。

【程序说明】
【硬件连接】
【代码分析】
RTC = PCF85063():创建 RTC 对象。RTC.setDate(weekday, day, month, year):设置 RTC 日期。RTC.setTime(hour, minute, second):设置 RTC 时间。RTC.readTime():读取 RTC 时间。RTC.setAlarm(second, minute, hour, day, weekday):设置 RTC 闹钟。RTC.enableAlarm():使能 RTC 闹钟。【运行效果】
使用 thonny 运行 02_RTC 文件下的 py 文件。

【程序说明】
【硬件连接】
【代码分析】
epd = EPD_1in54 :创建 LCD 对象。epd.Clear(0xff):清除全屏。epd.fill(0xff):填充全屏颜色。epd.text("RP2350-Touch-ePaper-1.54", 0, 30, 0x00):在屏幕上写文字。epd.hline(10, 150, 80, 0x00):画水平线。epd.vline(10, 90, 60, 0x00):画垂直线。epd.display(epd.buffer):刷新屏幕(真正显示出来)。【运行效果】
使用 thonny 运行 03_GUI 文件下的 py 文件。

【程序说明】
down、up、click(单击)、double(双击)、long(长按),并在串口/Thonny Shell 中打印事件日志。key_events.py(可作为库导入复用,也可作为主程序脚本直接运行)。【硬件连接】
【代码分析】
BootKey:BOOTSEL 读取封装rp2.bootsel_button()(或部分版本用 machine.bootsel_button())提供读取接口。pressed():返回当前是否按下(True 表示按下)。GpioKey:普通 GPIO 按键读取封装Pin(pin, Pin.IN, pull):将指定 GPIO 配置为输入,并配置上拉/下拉。active_low=True:表示按下为 0,松开为 1(常见接法)。Key:按键事件状态机(轮询式)debounce_ms:消抖时间。只有当电平变化稳定持续超过该时间,才认为状态真的变化。double_ms:双击判定窗口。单击事件会在“松开后等待 double_ms”确认没有第二次点击后才发出。long_ms:长按阈值。按住超过 long_ms 时立即触发一次 long(不必等待松开)。poll(now):每隔一段时间调用一次,内部完成:down/uplongclick,2 次转换为 doublemain(banner=False, poll_ms=10):程序入口banner=True 时打印操作提示(适合“作为主程序脚本”运行时引导初学者)。poll_ms 为轮询间隔,越小越灵敏但占用 CPU 越多(常用 5~20ms)。【运行效果】
04_KEY 文件夹下的 py 文件。key_events.py,确认解释器选择的是开发板对应的 MicroPython 端口。__main__ 方式执行,因此会自动进入 main(banner=True),直接看到提示与按键事件输出。main.py 里显式调用 key_events.main(...)。key_events.py 上传到开发板根目录并重命名为 main.py。power down / power up / power clickpower doublepower longboot down / boot up / boot click ...key_events.py 不变,上传到开发板。main.py 中显式调用:import key_eventskey_events.main(banner=True)(或 banner=False)Thonny 点击 Stop(中断)按钮,或在 Shell/REPL 中按 Ctrl+C 结束轮询循环并返回交互提示符。

【程序说明】
【硬件连接】
0x70【代码分析】
常量配置
I2C 默认参数(见 shtc3.py 文件头部的常量):
SHTC3_I2C_NUM:I2C 控制器编号SHTC3_I2C_SCL / SHTC3_I2C_SDA:默认引脚SHTC3_I2C_ADDR:I2C 地址SHTC3_I2C_FREQ:I2C 频率SHTC3 指令集:
SHTC3_REG_WAKEUP / SHTC3_REG_SLEEP / SHTC3_REG_SOFTRESET / SHTC3_REG_READIDSHTC3_MEAS_ALL:根据 stretch/low_power/hum_first 组合选择“测量指令”SHTC3:传感器驱动类
__init__(..., i2c=None, crc_fail_return=(None, None))
i2c:允许外部传入已创建好的 I2C 对象,方便多设备共享总线crc_fail_return:CRC 校验失败时的返回值(默认 (None, None))wakeup():唤醒soft_reset():软复位crc8(buffer)
0x31,初值 0xFF)read_id()
Nonemeasurement(hum_first=False, low_power_meas=False, stretch=False, ...)
(temperature_c, humidity_rh)low_power_meas=True:低功耗测量(更省电,但重复性/精度表现略受影响,温度影响更明显)stretch=True:启用 clock stretching(是否需要取决于你的 I2C 总线/驱动实现)hum_first:传感器返回的两个数据块(温度/湿度)谁在前hum_frist:保留了旧示例中的拼写(typo)兼容read(low_power=False, stretch=False, ...)
measurement(hum_first=False, ...)main(...):示例入口(单文件一体化)
当 shtc3.py 作为脚本直接运行时,会执行:
main():循环读取并打印温湿度Ctrl+C 可中断循环参数说明:
interval_s:打印间隔(秒)crc_fail_return:可覆盖驱动默认 CRC 失败返回值【运行效果】
方式 A:通过 Thonny 直接运行 05_SHTC3 文件夹下的 py 文件。
在电脑上用 Thonny 打开 shtc3.py,确认解释器选择的是开发板对应的 MicroPython 端口。
点击 Run 执行,默认会进入 main(),看到类似输出:
SHTC3 ID: 0x....Temperature: 25.12 °C, Humidity: 45.67 %停止运行:Thonny 点击 Stop,或在 REPL 里按 Ctrl+C。
方式 B:作为库导入复用(推荐)
shtc3.py 上传到开发板文件系统(与 main.py 同目录通常最方便)。main.py 里使用:import time
from shtc3 import SHTC3
shtc3 = SHTC3()
while True:
t, rh = shtc3.read()
if t is not None and rh is not None:
print(t, rh)
time.sleep(1)

【程序说明】
RP2350-Touch-ePaper-1.54 使用。【硬件连接】
【代码分析】
EPD_1in54:墨水屏驱动 + FrameBuffer 绘图封装(main.py)
framebuf.FrameBuffer:把 buffer 当作 200×200 单色画布使用,然后把 buffer 推到屏幕。send_command() / send_data():通过 SPI 写命令/数据到屏幕控制器。ReadBusy():轮询 BUSY 引脚等待屏幕空闲(墨水屏刷新期间必须等待)。displayPartBaseImage():把“底图”写入两次缓冲区(0x24/0x26),用于后续局刷更稳定(减少残影的常见做法)。init(update):两种刷新模式初始化FULL_UPDATE:全刷,慢但干净PART_UPDATE:局刷,快但可能有残影,需要底图配合touch_ft6336u:FT6336U 触摸驱动(FT6336U.py)
__init__)machine.I2C(id=1, scl=Pin(7), sda=Pin(6), freq=400_000):使用 I2C1,400kHz。int = Pin(8, IN, PULL_UP):触摸中断脚,下降沿触发回调。rst = Pin(16, OUT):复位脚,上电时按时序拉高/拉低复位芯片。init_chip():初始化与读 ID0xA3 获取 chip id,示例里期望 0x64,并打印 “init ok” 或 “ID error”。int_cb / read_touch_data)int_cb() 触发后调用 read_touch_data(),先读 TD_STATUS(0x02) 得到触摸点数,再读 TOUCH1_X(0x03) 起的 4 字节拼出 x/y。get_touch_xy)[{"x":..., "y":...}],并把 point_count 清零,保证一次触摸只取一次(更像“事件”而不是连续坐标流)。主程序流程(main.py)
epd = EPD_1in54()、epd.Clear(0xff)(0xff 表示白色)。touch = touch_ft6336u(),会在串口看到 FT6336U ID 相关输出。epd.displayPartBaseImage(epd.buffer),然后 epd.init(epd.part_update) 切到局刷模式。touch_debounce = 500:500ms 内只响应一次触摸,避免中断/抖动导致连发。touch.get_touch_xy():拿到一次触摸点后:displayPartial() 局刷【运行效果】
方式 A:通过 Thonny 直接运行运行 06_TOUCH 文件夹下的 py 文件。
FT6336U.py 上传到设备内置 RP2350 的 MicroPython 文件系统根目录。Initializing e-Paper...Initializing touch screen...FT6336U ID = 0x64、FT6336U init ok!Touch detected: (x, y)Touch: 区域名与 Pos: 坐标方式 B:作为上电自启程序
将 main.py 与 FT6336U.py 上传到设备内置 RP2350 的 MicroPython 文件系统根目录。
复位后自动运行。

【程序说明】
rp2.DMA 时可启用 DMA 加速。main.py 中修改):SAMPLE_FREQ = 24000,支持的采样率组合由 es8311.py 的 COEFF_DIV 表决定)res_in=16)、DAC 16bit(res_out=16)channel_count = 2)main.py:可直接运行的录音回放环回测试es8311.py:ES8311 I2C 寄存器驱动(时钟/格式/音量/静音/麦克风增益)audio_pio_mpy.py:PIO I2S + MCLK 输出(可选 DMA 接口)【硬件连接】
【代码分析】
es8311.py:ES8311 寄存器驱动(I2C)
write_reg() / read_reg():单寄存器写/读封装。COEFF_DIV + sample_frequency_config(mclk, rate):按 MCLK 与采样率查表配置分频(示例 MCLK = SAMPLE_FREQ * 256)。fmt_config(res_in, res_out):设置 I2S 数据位宽与工作模式(示例使用 I2S 格式,并打开相关模式位)。init(...):芯片复位 -> 时钟配置 -> 格式配置 -> ADC/DAC 相关寄存器初始化 -> 设置音量与麦克风增益。volume_set()/volume_get()、mute()、microphone_gain_set():常用控制接口。audio_pio_mpy.py:PIO I2S 收发 + MCLK 输出(可选 DMA)
mclk_pio():极简方波输出,用 StateMachine 产生 MCLK。audio_pio_out():等待 ES8311 输出的 LRCLK/BCLK,同步输出数据;每次 pull() 取一个 32-bit 帧(左 16bit + 右 16bit)。audio_pio_in():等待 LRCLK/BCLK,同步采样输入数据;autopush=True, push_thresh=16,只采集一个 16-bit 通道并推入 RX FIFO。AudioPIO:mclk_pio_init()/dout_pio_init()/din_pio_init():初始化各 StateMachine 及引脚方向。audio_in_into():轮询从 RX FIFO 取样(带超时提示,便于定位 BCLK/LRCLK/DIN 连接问题)。dma_record_into() / dma_play_from_i16():固件支持 rp2.DMA 时使用 DMA 从/到 PIO FIFO 直接搬运,提高实时性并降低 CPU 占用。main.py:录音回放环回示例
SAMPLE_FREQ、MCLK_FREQ、RECORD_DURATION_MS、DAC_VOLUME、MIC_GAIN、USE_DMA 等。init_hardware():打开功放使能脚(PA_CTRL_PIN)并初始化 I2C。init_es8311():读取 Chip ID,调用 codec.init(...),解除静音。init_audio_pio():配置 PIO 引脚与 StateMachine ID(默认 SM_DOUT_ID=0, SM_DIN_ID=5, SM_MCLK_ID=2)。condition_mic_samples() 去直流与衰减 -> 回放(DMA/非 DMA)。【运行效果】
07_ES8311 文件夹下的所有 py 文件上传到设备根目录。main.py,点击 Run 运行。07_ES8311 文件夹下的所有 py 文件上传到设备根目录。main.py(请确保 3 个文件都已上传:main.py、es8311.py、audio_pio_mpy.py)。Thonny 点击 Stop(中断)按钮,或在 Shell/REPL 中按 Ctrl+C 结束循环并返回交互提示符。

本章节包含以下部分,请按需阅读:
请参考 安装和配置 Pico C/C++ 开发环境教程 下载安装 Pico VS Code。
C/C++ 示例程序位于 示例程序包 的 examples\C 目录中。
| 示例程序 | 基础例程说明 | 依赖库 |
|---|---|---|
| 01_FatFs | FAT 文件系统,SD 卡 支持 SPI/SDIO 通讯 | - |
| 02_ES8311 | 开发板音频测试程序 | - |
| 03_GUI | GUI 显示程序 | - |
| 04_LVGL | LVGL 显示程序 | LVGL V8.4 |
【程序说明】
【硬件连接】
【代码分析】
sd_init_driver():初始化 SD 卡驱动。getchar_timeout_us():获取串口输入。process_stdio():处理串口输入。【运行效果】
使用 putty 或者 mobaxterm 等终端工具,打开开发板对应的 USB 串行端口
按 Enter 键启动命令行界面 (CLI)。您应该会看到类似这样的提示:
>
输入 help 指令可以得到可用指令,如下
> help
setrtc <DD> <MM> <YY> <hh> <mm> <ss>:
Set Real Time Clock
Parameters: new date (DD MM YY) new time in 24-hour format (hh mm ss)
e.g.:setrtc 16 3 21 0 4 0
date:
Print current date and time
lliot <drive#>:
!DESTRUCTIVE! Low Level I/O Driver Test
e.g.: lliot 1
format [<drive#:>]:
Creates an FAT/exFAT volume on the logical drive.
e.g.: format 0:
mount [<drive#:>]:
Register the work area of the volume
e.g.: mount 0:
unmount <drive#:>:
Unregister the work area of the volume
chdrive <drive#:>:
Changes the current directory of the logical drive.
<path> Specifies the directory to be set as current directory.
e.g.: chdrive 1:
getfree [<drive#:>]:
Print the free space on drive
cd <path>:
Changes the current directory of the logical drive.
<path> Specifies the directory to be set as current directory.
e.g.: cd 1:/dir1
mkdir <path>:
Make a new directory.
<path> Specifies the name of the directory to be created.
e.g.: mkdir /dir1
ls:
List directory
cat <filename>:
Type file contents
simple:
Run simple FS tests
big_file_test <pathname> <size in bytes> <seed>:
Writes random data to file <pathname>.
<size in bytes> must be multiple of 512.
e.g.: big_file_test bf 1048576 1
or: big_file_test big3G-3 0xC0000000 3
cdef:
Create Disk and Example Files
Expects card to be already formatted and mounted
start_logger:
Start Data Log Demo
stop_logger:
Stop Data Log Demo
【程序说明】
【硬件连接】
【代码分析】
Es8311_Init():初始化 ES8311。Es8311_Sample_Frequency_Config():配置采样率。Es8311_Microphone_Config():配置麦克风。Es8311_Microphone_Gain_Set():设置麦克风增益。Es8311_Voice_Volume_Set():设置音量。Sine_440hz_Out():输出 440 Hz 正弦波。Happy_Birthday_Out():生日快乐电子乐。Loopback_Test():录音播放测试。Music_Out():播放音乐。【运行效果】
build 目录下 uf2 尾缀文件,或直接烧录 02_ES8311\uf2 目录下 uf2 尾缀文件进行快速验证。【程序说明】
【硬件连接】
【代码分析】
我们对硬件操作进行了底层的封装,由于硬件平台不一样,内部的实现是不一样的,如果需要了解内部实现可以去对应的目录中查看,在 DEV_Config.c(.h) 可以看到很多定义,在目录:lib\Config
模块初始化与退出的处理
void DEV_Module_Init(void);
void DEV_Module_Exit(void);
这里是处理使用显示屏前与使用完之后一些 GPIO 的处理。
GPIO 读写
void DEV_Digital_Write(uint_16 Pin, uint_8 Value);
uint_8 DEV_Digital_Read(uint_16 Pin);
SPI 写数据
void DEV_SPI_WriteByte(uint_8 Value);
对于屏幕而言,如果需要进行画图、显示中英文字符、显示图片等怎么办,这些都是上层应用做的。这有很多小伙伴有问到一些图形的处理,我们这里提供了一些基本的功能 在如下的目录中可以找到 GUI,在目录:lib\GUI\GUI_Paint.c(.h)

在如下目录下是 GUI 依赖的字符字体,在目录:lib\Fonts

新建图像属性:新建一个图像属性,这个属性包括图像缓存的名称、宽度、高度、翻转角度、颜色
void Paint_NewImage(uint16_t *image, uint16_t Width, uint16_t Height, uint16_t Rotate, uint16_t Color)
参数:
image: 图像缓存的名称,实际上是一个指向图像缓存首地址的指针;
Width: 图像缓存的宽度;
Height: 图像缓存的高度;
Rotate: 图像的翻转的角度
Color: 图像的初始颜色;
选择图像缓存:选择图像缓存,选择的目的是你可以创建多个图像属性,图像缓存可以存在多个,你可以选择你所创建的每一张图像
void Paint_SelectImage(uint8_t *image)
参数:
image: 图像缓存的名称,实际上是一个指向图像缓存首地址的指针;
图像旋转:设置选择好的图像的旋转角度,最好使用在 Paint_SelectImage() 后,可以选择旋转 0、90、180、270 度
void Paint_SetRotate(uint16_t Rotate)
参数:
Rotate: 图像选择角度,可以选择 ROTATE_0、ROTATE_90、ROTATE_180、ROTATE_270 分别对应 0、90、180、270 度
不同选择角度下,坐标对应起始像素点不同,这里以 1.14 为例,四张图,按顺序为 0°, 90°, 180°, 270°。仅做为参考。

图像镜像翻转:设置选择好的图像的镜像翻转,可以选择不镜像、关于水平镜像、关于垂直镜像、关于图像中心镜像。
void Paint_SetMirroring(uint8_t mirror)
参数:
mirror: 图像的镜像方式,可以选择 MIRROR_NONE、MIRROR_HORIZONTAL、MIRROR_VERTICAL、MIRROR_ORIGIN 分别对应不镜像、关于水平镜像、关于垂直镜像、关于图像中心镜像
设置点在缓存中显示位置和颜色:这里是 GUI 最核心的一个函数、处理点在缓存中显示位置和颜色。
void Paint_SetPixel(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color)
参数:
Xpoint: 点在图像缓存中 X 位置
Ypoint: 点在图像缓存中 Y 位置
Color: 点显示的颜色
图像缓存填充颜色:把图像缓存填充为某颜色,一般作为屏幕刷白的作用。
void Paint_Clear(uint16_t Color)
参数:
Color: 填充的颜色
图像缓存部分窗口填充颜色:把图像缓存的某部分窗口填充为某颜色,一般作为窗口刷白的作用,常用于时间的显示,刷白上一秒。
void Paint_ClearWindows(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color)
参数:
Xstart: 窗口的 X 起点坐标
Ystart: 窗口的 Y 起点坐标
Xend: 窗口的 X 终点坐标
Yend: 窗口的 Y 终点坐标
Color: 填充的颜色
画点:在图像缓存中,在(Xpoint, Ypoint)上画点,可以选择颜色,点的大小,点的风格
void Paint_DrawPoint(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style)
参数:
Xpoint: 点的 X 坐标
Ypoint: 点的 Y 坐标
Color: 填充的颜色
Dot_Pixel: 点的大小,提供默认的 8 种大小点
typedef enum {
DOT_PIXEL_1X1 = 1, // 1 x 1
DOT_PIXEL_2X2 , // 2 X 2
DOT_PIXEL_3X3 , // 3 X 3
DOT_PIXEL_4X4 , // 4 X 4
DOT_PIXEL_5X5 , // 5 X 5
DOT_PIXEL_6X6 , // 6 X 6
DOT_PIXEL_7X7 , // 7 X 7
DOT_PIXEL_8X8 , // 8 X 8
} DOT_PIXEL;
Dot_Style: 点的风格,大小扩充方式是以点为中心扩大还是以点为左下角往右上扩大
typedef enum {
DOT_FILL_AROUND = 1,
DOT_FILL_RIGHTUP,
} DOT_STYLE;
画线:在图像缓存中,从 (Xstart, Ystart) 到 (Xend, Yend) 画线,可以选择颜色,线的宽度,线的风格
void Paint_DrawLine(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color, LINE_STYLE Line_Style , LINE_STYLE Line_Style)
参数:
Xstart: 线的 X 起点坐标
Ystart: 线的 Y 起点坐标
Xend: 线的 X 终点坐标
Yend: 线的 Y 终点坐标
Color: 填充的颜色
Line_width: 线的宽度,提供默认的 8 种宽度
typedef enum {
DOT_PIXEL_1X1 = 1, // 1 x 1
DOT_PIXEL_2X2 , // 2 X 2
DOT_PIXEL_3X3 , // 3 X 3
DOT_PIXEL_4X4 , // 4 X 4
DOT_PIXEL_5X5 , // 5 X 5
DOT_PIXEL_6X6 , // 6 X 6
DOT_PIXEL_7X7 , // 7 X 7
DOT_PIXEL_8X8 , // 8 X 8
} DOT_PIXEL;
Line_Style: 线的风格,选择线是以直线连接还是以虚线的方式连接
typedef enum {
LINE_STYLE_SOLID = 0,
LINE_STYLE_DOTTED,
} LINE_STYLE;
画矩形:在图像缓存中,从 (Xstart, Ystart) 到 (Xend, Yend) 画一个矩形,可以选择颜色,线的宽度,是否填充矩形内部
void Paint_DrawRectangle(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
参数:
Xstart: 矩形的 X 起点坐标
Ystart: 矩形的 Y 起点坐标
Xend: 矩形的 X 终点坐标
Yend: 矩形的 Y 终点坐标
Color: 填充的颜色
Line_width: 矩形四边的宽度,提供默认的 8 种宽度
typedef enum {
DOT_PIXEL_1X1 = 1, // 1 x 1
DOT_PIXEL_2X2 , // 2 X 2
DOT_PIXEL_3X3 , // 3 X 3
DOT_PIXEL_4X4 , // 4 X 4
DOT_PIXEL_5X5 , // 5 X 5
DOT_PIXEL_6X6 , // 6 X 6
DOT_PIXEL_7X7 , // 7 X 7
DOT_PIXEL_8X8 , // 8 X 8
} DOT_PIXEL;
Draw_Fill: 填充,是否填充矩形的内部
typedef enum {
DRAW_FILL_EMPTY = 0,
DRAW_FILL_FULL,
} DRAW_FILL;
画圆:在图像缓存中,以 (X_Center Y_Center) 为圆心,画一个半径为 Radius 的圆,可以选择颜色,线的宽度,是否填充圆内部
void Paint_DrawCircle(uint16_t X_Center, uint16_t Y_Center, uint16_t Radius, uint16_t Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
参数:
X_Center: 圆心的 X 坐标
Y_Center: 圆心的 Y 坐标
Radius: 圆的半径
Color: 填充的颜色
Line_width: 圆弧的宽度,提供默认的 8 种宽度
typedef enum {
DOT_PIXEL_1X1 = 1, // 1 x 1
DOT_PIXEL_2X2 , // 2 X 2
DOT_PIXEL_3X3 , // 3 X 3
DOT_PIXEL_4X4 , // 4 X 4
DOT_PIXEL_5X5 , // 5 X 5
DOT_PIXEL_6X6 , // 6 X 6
DOT_PIXEL_7X7 , // 7 X 7
DOT_PIXEL_8X8 , // 8 X 8
} DOT_PIXEL;
Draw_Fill: 填充,是否填充圆的内部
typedef enum {
DRAW_FILL_EMPTY = 0,
DRAW_FILL_FULL,
} DRAW_FILL;
写 Ascii 字符:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一个 Ascii 字符,可以选择 Ascii 码可视字符字库、字体前景色、字体背景色
void Paint_DrawChar(uint16_t Xstart, uint16_t Ystart, const uint8_t Ascii_Char, sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background)
参数:
Xstart: 字符的左顶点 X 坐标
Ystart: 字体的左顶点 Y 坐标
Ascii_Char:Ascii 字符
Font: Ascii 码可视字符字库,在 Fonts 文件夹中提供了以下字体:
font8:5*8 的字体
font12:7*12 的字体
font16:11*16 的字体
font20:14*20 的字体
font24:17*24 的字体
Color_Foreground: 字体颜色
Color_Background: 背景颜色
写英文字符串:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串英文字符,可以选择 Ascii 码可视字符字库、字体前景色、字体背景色
void Paint_DrawString_EN(uint16_t Xstart, uint16_t Ystart, const uint8_t * pString, sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background)
参数:
Xstart: 字符的左顶点 X 坐标
Ystart: 字体的左顶点 Y 坐标
pString: 字符串,字符串是一个指针
Font: Ascii 码可视字符字库,在 Fonts 文件夹中提供了以下字体:
font8:5*8 的字体
font12:7*12 的字体
font16:11*16 的字体
font20:14*20 的字体
font24:17*24 的字体
Color_Foreground: 字体颜色
Color_Background: 背景颜色
写中文字符串:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串中文字符,可以选择 GB2312 编码字符字库、字体前景色、字体背景色
void Paint_DrawString_CN(uint16_t Xstart, uint16_t Ystart, const uint8_t * pString, cFONT* font, uint16_t Color_Foreground, uint16_t Color_Background)
参数:
Xstart: 字符的左顶点 X 坐标
Ystart: 字体的左顶点 Y 坐标
pString: 字符串,字符串是一个指针
Font: GB2312 编码字符字库,在 Fonts 文件夹中提供了以下字体:
font12CN:ascii 字符字体 11*21,中文字体 16*21
font24CN:ascii 字符字体 24*41,中文字体 32*41
Color_Foreground: 字体颜色
Color_Background: 背景颜色
写数字:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串数字,可以选择 Ascii 码可视字符字库、字体前景色、字体背景色
void Paint_DrawNum(uint16_t Xpoint, uint16_t Ypoint, uint32_t Nummber, sFONT* Font, uint16_t Digit,uint16_t Color_Foreground, uint16_t Color_Background);
参数:
Xstart: 字符的左顶点 X 坐标
Ystart: 字体的左顶点 Y 坐标
Nummber: 显示的数字,这里使用的是 32 位长的 int 型保存,可以最大显示到 2147483647
Font: Ascii 码可视字符字库,在 Fonts 文件夹中提供了以下字体:
font8:5*8 的字体
font12:7*12 的字体
font16:11*16 的字体
font20:14*20 的字体
font24:17*24 的字体
Digit: 显示小数点位数
Color_Foreground: 字体颜色
Color_Background: 背景颜色
显示时间:在图像缓存中,在 (Xstart Ystart) 为左顶点,显示一段时间,可以选择 Ascii 码可视字符字库、字体前景色、字体背景色;
void Paint_DrawTime(uint16_t Xstart, uint16_t Ystart, PAINT_TIME *pTime, sFONT* Font, uint16_t Color_Background, uint16_t Color_Foreground)
参数:
Xstart: 字符的左顶点 X 坐标
Ystart: 字体的左顶点 Y 坐标
pTime: 显示的时间,这里定义好了一个时间的结构体,只要把时分秒各位数传给参数;
Font: Ascii 码可视字符字库,在 Fonts 文件夹中提供了以下字体:
font8:5*8 的字体
font12:7*12 的字体
font16:11*16 的字体
font20:14*20 的字体
font24:17*24 的字体
Color_Foreground: 字体颜色
Color_Background: 背景颜色
【运行效果】
build 目录下 uf2 尾缀文件,或直接烧录 firmware\C 目录下 03_GUI.uf2 进行快速验证。
【程序说明】
【硬件连接】
【代码分析】
LVGL 库的源码位于工程文件夹的 lib\lvgl ,使用的版本号为 8.4,二次开发请参考对应版本的开发文档。
LVGL 库的相关设置在工程文件夹的 examples\inc\lv_conf.h 中,可以设置显示刷新频率、系统占用数据等。
LVGL 库的应用代码位于工程文件夹的 main.c lv_port\lv_port_disp.c lv_port\lv_port_indev.c。
在使用 LVGL 图像库之前,您需要先初始化 LVGL。
LVGL 库的初始化函数
代码位置:main.c
实现功能:主要用于初始化 LVGL 所需的硬件和结构体变量。
LVGL_Init();
LVGL 库核心初始化
代码位置:main.c
/*2.Init LVGL core*/
lv_init();
LVGL 库定时调用心跳接口函数 lv_tick_inc 来通知 LVGL 过去的时间,以便 LVGL 能够更新其内部的时间状态,处理与时间相关的任务,例如动画、定时器等。在主函数的循环中还需要调用 lv_task_handler 函数,以便 LVGL 及时处理事件和任务,保证用户界面的响应和刷新。
LVGL 心跳接口
代码位置:main.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\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 显示相关变量定义
代码位置:lv_port\lv_port_disp.c
实现功能:定义显示驱动 disp_drv,绘制缓冲区 disp_buf。本例绘制缓冲区 buf0 设置为整个屏幕显示面积,能够在降低大面积刷屏锯齿的同时有效提高屏幕刷新率。
static lv_disp_drv_t disp_drv;
static lv_disp_draw_buf_t disp_buf;
static lv_color_t *buf0;
LVGL 显示设备注册
代码位置:lv_port\lv_port_disp.c
实现功能:根据设计需求完善 LVGL 库核心结构体变量,初始化显示驱动 disp_drv,并设置绘制缓冲区,该缓冲区是 LVGL 用来渲染屏幕内容的简单数组。一旦渲染准备就绪,绘制缓冲区的内容将使用显示驱动程序中设置的 disp_drv_flush_cb 函数发送到显示器。
static UBYTE img[(((EPD_1IN54_V2_WIDTH % 8 == 0)? (EPD_1IN54_V2_WIDTH / 8 ): (EPD_1IN54_V2_WIDTH / 8 + 1)) * EPD_1IN54_V2_HEIGHT)] = {0};
UBYTE *BlackImage = img;
Paint_NewImage(BlackImage, EPD_1IN54_V2_WIDTH, EPD_1IN54_V2_HEIGHT, ROTATE_0, WHITE);
static lv_disp_draw_buf_t draw_buf_dsc_1 = {0};
static lv_color_t buf_1[MY_DISP_HOR_RES * MY_DISP_VER_RES] = {0};
static lv_color_t buf_2[MY_DISP_HOR_RES * MY_DISP_VER_RES] = {0};
lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, buf_2, MY_DISP_HOR_RES * MY_DISP_VER_RES); /*Initialize the display buffer*/
/*-----------------------------------
* Register the display in LVGL
*----------------------------------*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set up the functions to access to your display*/
/*Set the resolution of the display*/
disp_drv.hor_res = MY_DISP_HOR_RES;
disp_drv.ver_res = MY_DISP_VER_RES;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = disp_flush;
disp_drv.user_data = BlackImage;
/*Set a display buffer*/
disp_drv.draw_buf = &draw_buf_dsc_1;
/*Required for Example 3)*/
#if 1
disp_drv.full_refresh = 1;
#endif
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
LVGL 显示回调函数
代码位置:lv_port\lv_port_disp.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 显示回调函数实现
代码位置:lv_port\lv_port_disp.c
static void disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p)
{
UBYTE *BlackImage = (UBYTE *)drv->user_data;
uint16_t *buffer = (uint16_t *)color_p;
for(int y = area->y1; y <= area->y2; y++)
{
for(int x = area->x1; x <= area->x2; x++)
{
uint8_t color = (*buffer < 0x7fff) ? BLACK : WHITE;
Paint_SetPixel(x,y, color);
buffer++;
}
}
EPD_1IN54_V2_DisplayPart(BlackImage);
lv_disp_flush_ready(drv);
}
LVGL 刷新完成通知实现
代码位置:lv_port\lv_port_disp.c
实现功能:每一次图像刷新完成后都需要通知 LVGL 核心,以便 LVGL 准备下个刷新图像的渲染。
lv_disp_flush_ready(drv);
在 LVGL 中,允许用户注册输入设备,如触摸板、鼠标、键盘或编码器等设备。用户可以通过这些输入设备控制用户界面,实现更好的交互。
LVGL 调用输入设备回调函数的频率设置
代码位置:examples\inc\lv_conf.h
设置方式: LVGL 默认每 30ms 调用一次输入设备回调函数来更新输入设备所触发的事件,可以在 lv_conf.h 中进行设置。
#define LV_INDEV_DEF_READ_PERIOD 30 // 单位:ms,这里为 30ms
LVGL 输入设备注册
代码位置:lv_port\lv_port_indev.c
设置方式:按键及触摸设备 indev_drv 并初始化。
void lv_port_indev_init(void)
{
static lv_indev_drv_t indev_drv;
#if INPUTDEV_TS
FT6336U_Init(FT6336U_Point_Mode);
// /*4.Init touch screen as input device*/
lv_indev_drv_init(&indev_ts);
indev_ts.type = LV_INDEV_TYPE_POINTER;
indev_ts.read_cb = ts_read_cb;
lv_indev_t * ts_indev = lv_indev_drv_register(&indev_ts);
DEV_KEY_Config(Touch_INT_PIN);
//Enable touch IRQ
DEV_IRQ_SET(Touch_INT_PIN, GPIO_IRQ_EDGE_RISE, &touch_callback);
#endif
keypad_init();
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);
}
LVGL 的输入设备回调函数
代码位置:lv_port\lv_port_indev.c
实现功能:主要用于更新输入事件。
static void keypad_read(lv_indev_drv_t * drv, lv_indev_data_t*data);
参数:
lv_indev_drv_t *indev_drv: LVGL 中的输入设备驱动结构体指针。在本例中,该结构体为按键输入设备驱动
lv_indev_data_t *data : LVGL 中的输入设备数据结构体指针。在本例中,该结构体用于存储输入设备的状态和数据,包括当前的按键状态(按下或释放)
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 中,我们能够建立各种不同的用户界面。界面的基本组成部分是对象,也称为控件(Widgets),比如按钮(Button)、标签(Label)、图像(Image)、列表(List)、图表或文本区域。在一个界面中,可以同时创建多个控件,并且我们可以设置它们的位置、尺寸、父对象、样式以及事件处理程序等基本属性。
LVGL 控件的对齐定位
代码位置:lv_app_hwtest.c
实现功能:使控件能够基于参考点进行偏移定位。控件对齐偏移的参考点控件的中心。
对齐标准: LVGL 库具备内部对齐和外部对齐两种方式。默认以左上角作为原点,向左为水平方向的正方向,向下为垂直方向的正方向。
//将 btn 控件定位在中心点向左偏移 45 个像素
lv_obj_align(sw, LV_ALIGN_CENTER, -45, 0);

LVGL 控件切换字体大小
代码位置:examples\inc\lv_conf.h、lv_app_hwtest.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 控件事件处理
代码位置:lv_app_hwtest.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);
【运行效果】
使用 VS Code 导入并编译 04_LVGL 工程,编译完成后,烧录 build 目录下 uf2 尾缀文件,或直接烧录 firmware\C 目录下 04_LVGL.uf2 文件进行快速验证。

本章节包含以下部分,请按需阅读:
请参考 安装和配置 Arduino IDE 教程 下载安装 Arduino IDE。
Arduino 示例程序位于 示例程序包 的 examples\Arduino 目录中。
| 示例程序 | 基础例程说明 | 依赖库 |
|---|---|---|
| 01_GUI | GUI 显示程序 | - |
【程序说明】
【硬件连接】
【代码分析】
我们对硬件操作进行了底层的封装,由于硬件平台不一样,内部的实现是不一样的,如果需要了解内部实现可以去对应的目录中查看,在 DEV_Config.c(.h) 可以看到很多定义,在目录:c\lib\Config
模块初始化与退出的处理
void DEV_Module_Init(void);
void DEV_Module_Exit(void);
这里是处理使用显示屏前与使用完之后一些 GPIO 的处理。
GPIO 读写
void DEV_Digital_Write(uint_16 Pin, uint_8 Value);
uint_8 DEV_Digital_Read(uint_16 Pin);
SPI 写数据
void DEV_SPI_WriteByte(uint_8 Value);
对于屏幕而言,如果需要进行画图、显示中英文字符、显示图片等怎么办,这些都是上层应用做的。这有很多小伙伴有问到一些图形的处理,我们这里提供了一些基本的功能 在如下的目录中可以找到 GUI,在目录:c\lib\GUI\GUI_Paint.c(.h)

在如下目录下是 GUI 依赖的字符字体,在目录:c\lib\Fonts

新建图像属性:新建一个图像属性,这个属性包括图像缓存的名称、宽度、高度、翻转角度、颜色
void Paint_NewImage(uint16_t *image, uint16_t Width, uint16_t Height, uint16_t Rotate, uint16_t Color)
参数:
image: 图像缓存的名称,实际上是一个指向图像缓存首地址的指针;
Width: 图像缓存的宽度;
Height: 图像缓存的高度;
Rotate: 图像的翻转的角度
Color: 图像的初始颜色;
选择图像缓存:选择图像缓存,选择的目的是你可以创建多个图像属性,图像缓存可以存在多个,你可以选择你所创建的每一张图像
void Paint_SelectImage(uint8_t *image)
参数:
image: 图像缓存的名称,实际上是一个指向图像缓存首地址的指针;
图像旋转:设置选择好的图像的旋转角度,最好使用在 Paint_SelectImage() 后,可以选择旋转 0、90、180、270 度
void Paint_SetRotate(uint16_t Rotate)
参数:
Rotate: 图像选择角度,可以选择 ROTATE_0、ROTATE_90、ROTATE_180、ROTATE_270 分别对应 0、90、180、270 度
不同选择角度下,坐标对应起始像素点不同,这里以 1.14 为例,四张图,按顺序为 0°, 90°, 180°, 270°。仅做为参考。

图像镜像翻转:设置选择好的图像的镜像翻转,可以选择不镜像、关于水平镜像、关于垂直镜像、关于图像中心镜像。
void Paint_SetMirroring(uint8_t mirror)
参数:
mirror: 图像的镜像方式,可以选择 MIRROR_NONE、MIRROR_HORIZONTAL、MIRROR_VERTICAL、MIRROR_ORIGIN 分别对应不镜像、关于水平镜像、关于垂直镜像、关于图像中心镜像
设置点在缓存中显示位置和颜色:这里是 GUI 最核心的一个函数、处理点在缓存中显示位置和颜色。
void Paint_SetPixel(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color)
参数:
Xpoint: 点在图像缓存中 X 位置
Ypoint: 点在图像缓存中 Y 位置
Color: 点显示的颜色
图像缓存填充颜色:把图像缓存填充为某颜色,一般作为屏幕刷白的作用。
void Paint_Clear(uint16_t Color)
参数:
Color: 填充的颜色
图像缓存部分窗口填充颜色:把图像缓存的某部分窗口填充为某颜色,一般作为窗口刷白的作用,常用于时间的显示,刷白上一秒。
void Paint_ClearWindows(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color)
参数:
Xstart: 窗口的 X 起点坐标
Ystart: 窗口的 Y 起点坐标
Xend: 窗口的 X 终点坐标
Yend: 窗口的 Y 终点坐标
Color: 填充的颜色
画点:在图像缓存中,在(Xpoint, Ypoint)上画点,可以选择颜色,点的大小,点的风格
void Paint_DrawPoint(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style)
参数:
Xpoint: 点的 X 坐标
Ypoint: 点的 Y 坐标
Color: 填充的颜色
Dot_Pixel: 点的大小,提供默认的 8 种大小点
typedef enum {
DOT_PIXEL_1X1 = 1, // 1 x 1
DOT_PIXEL_2X2 , // 2 X 2
DOT_PIXEL_3X3 , // 3 X 3
DOT_PIXEL_4X4 , // 4 X 4
DOT_PIXEL_5X5 , // 5 X 5
DOT_PIXEL_6X6 , // 6 X 6
DOT_PIXEL_7X7 , // 7 X 7
DOT_PIXEL_8X8 , // 8 X 8
} DOT_PIXEL;
Dot_Style: 点的风格,大小扩充方式是以点为中心扩大还是以点为左下角往右上扩大
typedef enum {
DOT_FILL_AROUND = 1,
DOT_FILL_RIGHTUP,
} DOT_STYLE;
画线:在图像缓存中,从 (Xstart, Ystart) 到 (Xend, Yend) 画线,可以选择颜色,线的宽度,线的风格
void Paint_DrawLine(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color, LINE_STYLE Line_Style , LINE_STYLE Line_Style)
参数:
Xstart: 线的 X 起点坐标
Ystart: 线的 Y 起点坐标
Xend: 线的 X 终点坐标
Yend: 线的 Y 终点坐标
Color: 填充的颜色
Line_width: 线的宽度,提供默认的 8 种宽度
typedef enum {
DOT_PIXEL_1X1 = 1, // 1 x 1
DOT_PIXEL_2X2 , // 2 X 2
DOT_PIXEL_3X3 , // 3 X 3
DOT_PIXEL_4X4 , // 4 X 4
DOT_PIXEL_5X5 , // 5 X 5
DOT_PIXEL_6X6 , // 6 X 6
DOT_PIXEL_7X7 , // 7 X 7
DOT_PIXEL_8X8 , // 8 X 8
} DOT_PIXEL;
Line_Style: 线的风格,选择线是以直线连接还是以虚线的方式连接
typedef enum {
LINE_STYLE_SOLID = 0,
LINE_STYLE_DOTTED,
} LINE_STYLE;
画矩形:在图像缓存中,从 (Xstart, Ystart) 到 (Xend, Yend) 画一个矩形,可以选择颜色,线的宽度,是否填充矩形内部
void Paint_DrawRectangle(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
参数:
Xstart: 矩形的 X 起点坐标
Ystart: 矩形的 Y 起点坐标
Xend: 矩形的 X 终点坐标
Yend: 矩形的 Y 终点坐标
Color: 填充的颜色
Line_width: 矩形四边的宽度,提供默认的 8 种宽度
typedef enum {
DOT_PIXEL_1X1 = 1, // 1 x 1
DOT_PIXEL_2X2 , // 2 X 2
DOT_PIXEL_3X3 , // 3 X 3
DOT_PIXEL_4X4 , // 4 X 4
DOT_PIXEL_5X5 , // 5 X 5
DOT_PIXEL_6X6 , // 6 X 6
DOT_PIXEL_7X7 , // 7 X 7
DOT_PIXEL_8X8 , // 8 X 8
} DOT_PIXEL;
Draw_Fill: 填充,是否填充矩形的内部
typedef enum {
DRAW_FILL_EMPTY = 0,
DRAW_FILL_FULL,
} DRAW_FILL;
画圆:在图像缓存中,以 (X_Center Y_Center) 为圆心,画一个半径为 Radius 的圆,可以选择颜色,线的宽度,是否填充圆内部
void Paint_DrawCircle(uint16_t X_Center, uint16_t Y_Center, uint16_t Radius, uint16_t Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
参数:
X_Center: 圆心的 X 坐标
Y_Center: 圆心的 Y 坐标
Radius: 圆的半径
Color: 填充的颜色
Line_width: 圆弧的宽度,提供默认的 8 种宽度
typedef enum {
DOT_PIXEL_1X1 = 1, // 1 x 1
DOT_PIXEL_2X2 , // 2 X 2
DOT_PIXEL_3X3 , // 3 X 3
DOT_PIXEL_4X4 , // 4 X 4
DOT_PIXEL_5X5 , // 5 X 5
DOT_PIXEL_6X6 , // 6 X 6
DOT_PIXEL_7X7 , // 7 X 7
DOT_PIXEL_8X8 , // 8 X 8
} DOT_PIXEL;
Draw_Fill: 填充,是否填充圆的内部
typedef enum {
DRAW_FILL_EMPTY = 0,
DRAW_FILL_FULL,
} DRAW_FILL;
写 Ascii 字符:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一个 Ascii 字符,可以选择 Ascii 码可视字符字库、字体前景色、字体背景色
void Paint_DrawChar(uint16_t Xstart, uint16_t Ystart, const uint8_t Ascii_Char, sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background)
参数:
Xstart: 字符的左顶点 X 坐标
Ystart: 字体的左顶点 Y 坐标
Ascii_Char:Ascii 字符
Font: Ascii 码可视字符字库,在 Fonts 文件夹中提供了以下字体:
font8:5*8 的字体
font12:7*12 的字体
font16:11*16 的字体
font20:14*20 的字体
font24:17*24 的字体
Color_Foreground: 字体颜色
Color_Background: 背景颜色
写英文字符串:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串英文字符,可以选择 Ascii 码可视字符字库、字体前景色、字体背景色
void Paint_DrawString_EN(uint16_t Xstart, uint16_t Ystart, const uint8_t * pString, sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background)
参数:
Xstart: 字符的左顶点 X 坐标
Ystart: 字体的左顶点 Y 坐标
pString: 字符串,字符串是一个指针
Font: Ascii 码可视字符字库,在 Fonts 文件夹中提供了以下字体:
font8:5*8 的字体
font12:7*12 的字体
font16:11*16 的字体
font20:14*20 的字体
font24:17*24 的字体
Color_Foreground: 字体颜色
Color_Background: 背景颜色
写中文字符串:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串中文字符,可以选择 GB2312 编码字符字库、字体前景色、字体背景色
void Paint_DrawString_CN(uint16_t Xstart, uint16_t Ystart, const uint8_t * pString, cFONT* font, uint16_t Color_Foreground, uint16_t Color_Background)
参数:
Xstart: 字符的左顶点 X 坐标
Ystart: 字体的左顶点 Y 坐标
pString: 字符串,字符串是一个指针
Font: GB2312 编码字符字库,在 Fonts 文件夹中提供了以下字体:
font12CN:ascii 字符字体 11*21,中文字体 16*21
font24CN:ascii 字符字体 24*41,中文字体 32*41
Color_Foreground: 字体颜色
Color_Background: 背景颜色
写数字:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串数字,可以选择 Ascii 码可视字符字库、字体前景色、字体背景色
void Paint_DrawNum(uint16_t Xpoint, uint16_t Ypoint, uint32_t Nummber, sFONT* Font, uint16_t Digit,uint16_t Color_Foreground, uint16_t Color_Background);
参数:
Xstart: 字符的左顶点 X 坐标
Ystart: 字体的左顶点 Y 坐标
Nummber: 显示的数字,这里使用的是 32 位长的 int 型保存,可以最大显示到 2147483647
Font: Ascii 码可视字符字库,在 Fonts 文件夹中提供了以下字体:
font8:5*8 的字体
font12:7*12 的字体
font16:11*16 的字体
font20:14*20 的字体
font24:17*24 的字体
Digit: 显示小数点位数
Color_Foreground: 字体颜色
Color_Background: 背景颜色
显示时间:在图像缓存中,在 (Xstart Ystart) 为左顶点,显示一段时间,可以选择 Ascii 码可视字符字库、字体前景色、字体背景色;
void Paint_DrawTime(uint16_t Xstart, uint16_t Ystart, PAINT_TIME *pTime, sFONT* Font, uint16_t Color_Background, uint16_t Color_Foreground)
参数:
Xstart: 字符的左顶点 X 坐标
Ystart: 字体的左顶点 Y 坐标
pTime: 显示的时间,这里定义好了一个时间的结构体,只要把时分秒各位数传给参数;
Font: Ascii 码可视字符字库,在 Fonts 文件夹中提供了以下字体:
font8:5*8 的字体
font12:7*12 的字体
font16:11*16 的字体
font20:14*20 的字体
font24:17*24 的字体
Color_Foreground: 字体颜色
Color_Background: 背景颜色
【运行效果】

开发板设计文件
数据手册