Day3.
br/>4. 优化代码结构,提高模块化程度,将LCD显示、定时器封装为独立可复用的组件;<br/>3. 掌握了图像/汉字的取模方法与LCD显示函数的编写,能实现个性化界面开发;成功完成ESP32 LCD驱动移植、静态显示(颜色/图片/汉字/字符串)、动态显示(动图循环)功能实现,完成FreeRTOS延时与定时器的配置与应用,实现定时器控制的LCD动态显示,所有功能测试正常,无明显BUG。<br/>
机器人设计与应用综合实训——ESP32开发技术分享
本文为机器人设计与应用综合实训中,基于ESP32的开发技术分享帖,主要记录实训过程中ESP32的LCD动态显示与定时器开发要点、问题排查及实践总结,适配实训报告补充、技术复盘及同学间交流使用。
核心方向:ESP32芯片LCD外设驱动、动态显示实现、定时器配置与应用、代码调试与优化,贴合实训核心需求,兼顾技术细节与实操记录。
|
实训项目名称 |
ESP32 LCD动态显示与定时器开发 |
|
实训时间 |
___3.11_______ |
|
ESP32开发板型号 |
ESP32-S3-WROOM-1-N16R8 |
|
开发环境 |
VSCode + ESP-IDF v5.4.2 |
|
实训小组人数 |
____1______ |
二、ESP32开发核心知识点梳理
本部分记录实训中LCD动态显示与定时器开发涉及的ESP32核心技术点,结合实操场景补充原理与应用细节。
|
知识点类别 |
具体知识点 |
核心原理简述 |
实训应用场景<br/>(机器人相关) |
备注<br/>(易错点/重点) |
|
外设驱动 |
LCD显示屏驱动(ST7789) |
基于SPI通信协议实现LCD屏初始化、颜色设置、图像/字符显示,通过IO扩展芯片PCA9557控制LCD_CS等引脚,结合PSRAM解决内存分配不足问题 |
机器人状态显示界面、数据可视化展示 |
1. 需开启PSRAM并在内存分配时指定MALLOC_CAP_SPIRAM;2. SPI引脚与时钟频率需与硬件匹配 |
|
外设驱动 |
LCD动态显示 |
通过循环刷新取模后的图片帧、结合延时/定时器控制帧刷新速率,实现动图、动态数据的显示效果 |
机器人动态动画展示、实时参数刷新显示 |
取模时需包含图像头数据,便于程序自动识别宽高 |
|
引脚配置 |
I2C引脚配置 |
配置I2C主模式,实现ESP32与PCA9557、触摸屏等外设的通信,为LCD驱动提供IO扩展支持 |
LCD屏IO扩展芯片控制、外设通信 |
SDA/SCL引脚需开启上拉,波特率配置为100kHz |
|
代码开发 |
FreeRTOS定时器/延时 |
利用FreeRTOS系统延时vTaskDelay或自定义定时器,控制程序执行时序,实现LCD显示的动态调度 |
LCD动态显示帧间隔控制、机器人定时数据刷新 |
1. configTICK_RATE_HZ默认1000Hz,延时单位为ms;2. 定时器需配置任务栈与优先级 |
|
代码开发 |
图像/汉字取模 |
通过取模软件将图片、汉字转换为C语言数组,为LCD显示提供数据来源,支持不同点阵大小的字体/图片定制 |
LCD个性化界面、汉字/自定义图片显示 |
非8整数倍点阵需补0,取模格式需与显示程序匹配 |
三、ESP32机器人开发实操步骤
按实训流程,记录从LCD驱动移植到动态显示与定时器实现的完整步骤,明确每一步的核心操作与目的。
|
步骤序号 |
实操内容<br/>(ESP32相关) |
操作步骤细节 |
使用工具/代码片段 |
操作结果<br/>(成功/失败及原因) |
|
1 |
LCD驱动组件移植 |
1. 基于现有工程复制创建LCD专属工程;<br/>2. 新建LCD组件,添加LCD.h/LCD.c文件,移植I2C、PCA9557、LCD屏初始化代码;<br/>3. 配置组件CMakeLists.txt,添加driver/esp_lcd依赖 |
VSCode、ESP-IDF组件管理<br/>idf_component_register(SRCS "LCD.c" INCLUDE_DIRS "include" REQUIRES driver esp_lcd) |
成功,编译无报错,驱动组件可被主程序调用 |
|
2 |
PSRAM配置解决内存问题 |
1. 运行LCD初始化代码出现“内存分配不足”报错;<br/>2. 打开SDK配置编辑器,搜索PSRAM并勾选相关选项,开启外部SPIRAM支持;<br/>3. 内存分配时使用heap_caps_malloc并指定MALLOC_CAP_SPIRAM |
ESP-IDF SDK配置编辑器<br/>`uint16_t *buffer = (uint16_t *)heap_caps_malloc(size, MALLOC_CAP_8BIT |
MALLOC_CAP_SPIRAM);` |
|
3 |
LCD静态显示实现 |
1. 通过取模软件将图片/汉字转换为C数组,添加到工程;<br/>2. 移植图片、字符、汉字显示函数,调用esp_lcd_panel_draw_bitmap实现显示;<br/>3. 测试整屏颜色设置、单张图片、汉字/字符串显示功能 |
Image2Lcd、PCtoLCD2002取模软件<br/>lcd_set_color(YELLOW);/LCD_ShowString(0,16,"XXX",RED,WHITE); |
成功,LCD可正常显示颜色、图片、汉字与字符串 |
|
4 |
LCD动态显示实现 |
1. 使用GIF分解工具将动图拆分为单帧图片,批量取模为C头文件;<br/>2. 工程中添加图片帧目录,配置CMakeLists.txt包含头文件路径;<br/>3. 定义指针数组关联所有图片帧,通过for循环遍历刷新显示 |
GIF分解工具、批量取模脚本<br/>for(uint8_t i=0;i<=5;i++){lcd_draw_pictrue(0,0,images[i]);vTaskDelay(100);} |
成功,LCD实现动图循环显示,帧速率可通过延时调整 |
|
5 |
FreeRTOS延时/定时器配置 |
1. 检查SDK中configTICK_RATE_HZ配置为1000Hz,确保vTaskDelay延时单位为ms;<br/>2. 测试延时函数控制LCD动态显示帧间隔,调整延时参数优化显示效果;<br/>3. 新建Timer组件,编写定时器初始化与回调函数,实现定时触发LCD显示刷新 |
ESP-IDF FreeRTOS配置<br/>vTaskDelay(100/ portTICK_PERIOD_MS); |
成功,可通过延时/定时器精准控制LCD动态显示时序 |
|
6 |
功能联调与优化 |
1. 整合LCD动态显示与定时器代码,实现定时刷新的动态显示界面;<br/>2. 优化内存使用,显示完成后及时调用heap_caps_free释放内存;<br/>3. 调整帧刷新速率与定时器周期,解决显示卡顿/闪烁问题 |
内存释放代码<br/>heap_caps_free(pixels); |
成功,LCD动态显示流畅,无内存泄漏,定时器触发精准 |
四、ESP32开发常见问题及解决方案
记录实训过程中LCD动态显示与定时器开发遇到的ESP32相关问题,填写解决方案与总结,便于后续复盘和同学参考。
|
问题序号 |
问题描述(ESP32相关) |
排查过程 |
解决方案 |
问题总结(避免方法) |
|
1 |
LCD初始化时报错“Memory for bitmap is not enough” |
1. 排查代码发现内存分配未使用外部PSRAM;<br/>2. 检查开发板硬件支持8MB PSRAM,但SDK未开启相关配置 |
1. 打开ESP-IDF SDK配置编辑器,勾选“Support for external, SPI-connected RAM”;<br/>2. 内存分配使用heap_caps_malloc并指定MALLOC_CAP_SPIRAM |
开发前确认硬件外设支持,按需开启SDK配置,大内存分配优先使用外部PSRAM |
|
2 |
LCD显示图片时位置偏移、尺寸错误 |
1. 排查取模文件,发现未包含图像头数据,程序无法识别实际宽高;<br/>2. 检查显示函数调用时的坐标与宽高参数设置错误 |
1. 取模时勾选“包含图像头数据”,修改显示函数自动从数据头解析宽高;<br/>2. 确认显示坐标与图片实际尺寸匹配,避免超出LCD屏分辨率(320*240) |
取模时统一配置格式,包含头数据;调用显示函数前核对坐标与尺寸参数 |
|
3 |
LCD动态显示动图时卡顿、帧率不均 |
1. 排查代码发现无延时控制,帧刷新速率过快;<br/>2. 检查循环中未优化内存操作,重复分配释放内存耗时 |
1. 使用vTaskDelay添加帧间隔延时(如100ms),或用定时器固定触发周期;<br/>2. 优化内存操作,可提前分配缓存减少重复申请释放 |
动态显示需根据硬件性能控制帧率,避免无节制刷新;优化内存操作减少程序耗时 |
|
4 |
FreeRTOS延时函数vTaskDelay计时不准 |
1. 排查SDK配置,发现configTICK_RATE_HZ被修改为100Hz;<br/>2. 检查延时参数未按portTICK_PERIOD_MS换算 |
1. 打开SDK配置,将configTICK_RATE_HZ恢复为1000Hz;<br/>2. 延时参数统一按vTaskDelay(ms/ portTICK_PERIOD_MS)编写 |
不要随意修改FreeRTOS核心配置,延时函数使用标准参数换算方式 |
|
5 |
汉字显示时部分字符无法显示 |
1. 排查字模文件LCDFont.h,发现未添加对应汉字的取模数据;<br/>2. 检查汉字显示函数,发现点阵匹配错误 |
1. 使用PCtoLCD2002取模软件生成对应汉字的字模,添加到tHz16/tHz30数组;<br/>2. 确保字模点阵大小与显示函数的内存分配、绘制参数匹配 |
按需添加汉字字模,避免一次性添加过多;字模点阵与显示函数需一一对应 |
五、实训总结与ESP32开发心得
|
项目完成情况 |
成功完成ESP32 LCD驱动移植、静态显示(颜色/图片/汉字/字符串)、动态显示(动图循环)功能实现,完成FreeRTOS延时与定时器的配置与应用,实现定时器控制的LCD动态显示,所有功能测试正常,无明显BUG。 |
|
ESP32开发重点收获 |
1. 掌握了ESP32 LCD屏(ST7789)的SPI驱动移植方法,理解了IO扩展芯片PCA9557的I2C控制逻辑;<br/>2. 解决了ESP32内存分配不足的问题,学会了PSRAM的SDK配置与heap_caps_malloc的使用技巧;<br/>3. 掌握了图像/汉字的取模方法与LCD显示函数的编写,能实现个性化界面开发;<br/>4. 理解了LCD动态显示的核心原理,学会了通过FreeRTOS延时/定时器控制程序时序;<br/>5. 积累了ESP32开发的问题排查经验,能快速定位编译、硬件、内存相关的常见错误。 |
|
存在的不足 |
1. 对ESP32 LCD底层驱动原理理解不够深入,仅能完成代码移植与简单修改;<br/>2. 定时器开发仅使用了基础的FreeRTOS延时,未实现中断式定时器的高级应用;<br/>3. LCD动态显示的优化手段单一,未考虑DMA传输、帧率自适应等高级技巧;<br/>4. 代码的模块化与可复用性不足,不同功能的代码耦合度较高。 |
|
后续改进计划 |
1. 深入学习ESP32 SPI/I2C外设的底层驱动原理,理解esp_lcd组件的源码逻辑;<br/>2. 学习ESP32中断式定时器与硬件定时器的开发,实现更精准的定时控制;<br/>3. 研究LCD显示的优化方法,尝试使用DMA传输减少CPU占用,提升动态显示流畅度;<br/>4. 优化代码结构,提高模块化程度,将LCD显示、定时器封装为独立可复用的组件;<br/>5. 结合机器人实训需求,实现LCD动态显示机器人的传感器数据、运动状态等实时信息。 |
1. LCD动态显示核心代码
hello_world_main.c文件
*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "LCD/LCD.h"
//#include "mge22.h"
#include "mag.c"
#include "Timer.h"
#include "IMG00000.h"
#include "IMG00006.h"
#include "IMG00029.h"
//指向图片的指针数组
unsigned char *images[]={
gImage_IMG00000,
gImage_IMG00006,
gImage_IMG00029,
};
//extern const unsigned char gImage_mag[]; //引入图片
void app_main(void)
{
int sec = 0 ;
char str[20]={0};
bsp_i2c_init(); //IIC接口初始化
pca9557_init(); //扩展口初始化
bsp_lcd_init(); //LCD初始化
// lcd_set_color(BLACK); //设置LCD颜色
// lcd_draw_pictrue(0,0,gImage_mag); //绘制图片,(0,0)是图片的起始坐标,gImage是图片数组
// //lcd_draw_char(0,0,'A',WHITE,BLACK); //绘制字符,(0,0)是显示起始坐标,WHITE为字符颜色,BLACK为背景颜色
// ESP_Timer_Init(); 定时器初始化
while (1){
for(uint8_t i=0;i<=5;i++){
lcd_draw_pictrue(0,0,images[i]);
vTaskDelay(100);
}
// if (sec !=timer_sec){
// sec =timer_sec;
// sprintf(str,"%02d:%02d:%02d",sec/3600%24,sec/60%60,sec%60);
// LCD_ShowString32(0,0,str,WHITE,GRAY);
// }
vTaskDelay(1);
}
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐



所有评论(0)