前几天完成的点灯的实验,今天可以尝试点一下屏幕了。
找到官方例程里jpg的例程。首先烧录下看看现象。
然后分析下代码。
主要是使用 STM32H7的硬件JPEG解码器,从FLASH中读取JPEG图片(image_320_240_jpg)。
通过 DMA将解码后的 RGB 数据传输到 LCD 显示。
主函数部分
int main(void) {
uint32_t xPos, yPos;
uint8_t lcd_status;
// 系统初始化(MPU、缓存、HAL、时钟)
MPU_Config(); // 配置内存保护单元(SDRAM 写通模式)
CPU_CACHE_Enable(); // 启用 CPU 缓存(I-Cache 和 D-Cache)
HAL_Init(); // HAL 库初始化(系统时基、NVIC 分组等)
SystemClock_Config(); // 配置系统时钟为 400MHz(CM7 核心频率)
// 初始化 LCD
lcd_status = BSP_LCD_Init(...);
if (lcd_status != OK) Error_Handler(); // 错误处理(LED2 亮起)
UTIL_LCD_SetLayer(0); // 设置显示层 0
UTIL_LCD_Clear(WHITE); // 清屏为白色
// JPEG 解码(非阻塞模式,通过 DMA)
JPEG_Decode_DMA(&JPEG_Handle, (uint32_t)image_320_240_jpg, ...);
while (!Jpeg_HWDecodingEnd); // 等待解码完成
// 获取 JPEG 图像信息(宽度、高度、色度抽样)
HAL_JPEG_GetInfo(&JPEG_Handle, &JPEG_Info);
// 计算图像居中位置
xPos = (LCD_X_Size - JPEG_Info.ImageWidth) / 2;
yPos = (LCD_Y_Size - JPEG_Info.ImageHeight) / 2;
// 通过 DMA2D 将解码数据复制到 LCD 帧缓冲区
DMA2D_CopyBuffer(...);
// 主循环(程序挂起在此)
while (1);
}
主函数主要有硬件加速解码与 DMA、内存与缓存管理和显示适配与对齐三部分组成。
1. 硬件加速解码与 DMA
JPEG 解码:通过 HAL_JPEG_Decode_DMA() 启动非阻塞解码。
DMA2D:负责将解码后的 YCbCr 数据转换为 ARGB8888 格式然后搬运到 LCD 帧缓冲区。
2. 内存与缓存管理
MPU 配置:将 SDRAM 区域设为 “可缓存 + 写通” 模式。
CPU 缓存:启用 I-Cache和 D-Cache。
3. 显示适配与对齐
居中显示:通过计算 (LCD 宽度 - 图像宽度)/2 和 (LCD 高度 - 图像高度)/2 确定显示位置。
数据对齐:根据色度抽样类型(如 4:2:0 需 16 字节行对齐),确保 DMA2D 传输时数据边界正确。
了解程序结构后就可以尝试替换一下图片了。找一张相同尺寸的图片,然后用xxd命令就可以将图片转换成数组。xxd -i 1231236.jpg > output.h
生成后打开output.h文件,复制数组内容到原工程数组内。编译下载就可以看到实验现象了。
|