跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

STM32F103RC TFT-LCD 电子相册开发:图片解码算法详解

介绍基于 STM32F103RC 和 TFT-LCD 的电子相册系统开发。涵盖硬件连接、FATFS 文件系统移植、BMP/JPEG 解码算法实现及显示优化。通过 SPI 读取 SD 卡图片,利用 FSMC 驱动屏幕,提供源码与问题解决方案,支持幻灯片播放模式。

极客零度发布于 2026/3/29更新于 2026/7/2036 浏览
STM32F103RC TFT-LCD 电子相册开发:图片解码算法详解

摘要

本教程详细介绍基于 STM32F103RC 微控制器和 TFT-LCD 显示屏的电子相册系统开发,涵盖硬件连接、文件系统移植、BMP/JPEG 解码算法实现及显示优化。通过 FATFS 文件系统读取 SD 卡图片,采用专用解码算法处理图像数据,最终在 320×480 分辨率屏幕上流畅显示。

一、项目概述

1.1 系统架构设计

  • 主控:STM32F103RC
  • 存储:SD 卡
  • 显示:TFT-LCD
  • 交互:用户按键
  • 软件:FATFS 文件系统、BMP 解码器、JPEG 解码器、显示驱动

1.2 硬件组件清单

组件型号数量
主控STM32F103RCT61
显示屏ILI9486 3.5 寸 TFT1
存储MicroSD 卡 (≥4GB)1
接口SPI 转 SD 模块1

1.3 技术指标

  • 支持格式:BMP24/JPEG
  • 最大分辨率:2048×1536
  • 刷新速率:≥2fps(320×480)
  • 功耗:<[email protected]

二、开发环境搭建

2.1 软件工具

  1. Keil MDK v5.25
  2. STM32CubeMX
  3. FATFS R0.14b
  4. LibJPEG v9d

2.2 硬件连接

/* 引脚定义 - stm32f10x_pin.h */
#define LCD_CS GPIO_Pin_12 // PB12
#define LCD_DC GPIO_Pin_11 // PB11
#define SD_CS GPIO_Pin_8   // PA8

2.3 工程创建步骤

  1. 使用 CubeMX 配置:
    • SPI1: 18MHz (SD 卡)
    • FSMC: Bank1 NOR/PSRAM (LCD)
    • GPIO: 用户按键

添加中间件:

Middleware/
├─ FATFS/
├─ LibJPEG/
└─ STemWin/

三、TFT-LCD 驱动开发

3.1 显示屏初始化

// lcd_init.c
 
{
    LCD_Reset();           
    delay_ms();
    LCD_WriteCmd();    
    delay_ms();
    LCD_WriteCmd();    
    LCD_WriteData();   
    LCD_WriteCmd();    
    LCD_WriteData();   
    LCD_WriteCmd();    
}
void
LCD_Init
(void)
// 硬件复位
50
0x11
// 退出睡眠模式
120
0x3A
// 设置颜色模式
0x55
// 16 位 RGB565
0x36
// 设置扫描方向
0x48
// 竖屏模式
0x29
// 开启显示

3.2 FSMC 配置

// fsmc.c
void FSMC_LCD_Config(void)
{
    FSMC_NORSRAMInitTypeDef init;
    FSMC_NORSRAMTimingInitTypeDef timing;
    
    timing.FSMC_AddressSetupTime = 2;
    timing.FSMC_AddressHoldTime = 1;
    timing.FSMC_DataSetupTime = 5;
    timing.FSMC_BusTurnAroundDuration = 1;
    
    init.FSMC_Bank = FSMC_Bank1_NORSRAM1;
    init.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
    init.FSMC_MemoryType = FSMC_MemoryType_SRAM;
    init.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
    init.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
    init.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
    
    FSMC_NORSRAMInit(&init);
    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}

四、文件系统移植

4.1 FATFS 配置

// fatfs_impl.c
DSTATUS SD_disk_initialize(void)
{
    SPI_InitTypeDef spi;
    spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    spi.SPI_Mode = SPI_Mode_Master;
    spi.SPI_DataSize = SPI_DataSize_8b;
    spi.SPI_CPOL = SPI_CPOL_High;
    spi.SPI_CPHA = SPI_CPHA_2Edge;
    spi.SPI_NSS = SPI_NSS_Soft;
    spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
    
    SPI_Init(SPI1, &spi);
    SPI_Cmd(SPI1, ENABLE);
    return RES_OK;
}

4.2 图片遍历函数

// file_scan.c
FRESULT scan_files(char* path)
{
    DIR dir;
    FILINFO fno;
    FRESULT res = f_opendir(&dir, path);
    
    while(1)
    {
        res = f_readdir(&dir, &fno);
        if(res != FR_OK || fno.fname[0] == 0) break;
        
        if(fno.fattrib & AM_DIR)
        {
            // 目录处理
        }
        else
        {
            if(strstr(fno.fname, ".bmp") || strstr(fno.fname, ".jpg"))
            {
                // 添加到图片列表
            }
        }
    }
    f_closedir(&dir);
    return res;
}

五、图片解码算法

5.1 BMP 解码实现

// bmp_decoder.c
uint8_t BMP_Show(const char* filename)
{
    FIL file;
    UINT bytesread;
    BMP_Header header;
    
    f_open(&file, filename, FA_READ);
    f_read(&file, &header, sizeof(BMP_Header), &bytesread);
    
    // 校验文件头
    if(header.signature != 0x4D42) return 1;
    
    // 设置显示窗口
    LCD_SetWindow(0, 0, header.width, header.height);
    
    // 读取像素数据
    uint32_t offset = header.data_offset;
    f_lseek(&file, offset);
    
    for(int y = header.height - 1; y >= 0; y--)
    {
        f_read(&file, line_buffer, header.width * 3, &bytesread);
        for(int x = 0; x < header.width; x++)
        {
            uint16_t color = RGB888toRGB565(line_buffer[x*3+2], line_buffer[x*3+1], line_buffer[x*3]);
            LCD_WriteData(color);
        }
    }
    
    f_close(&file);
    return 0;
}

5.2 JPEG 软解码优化

// jpeg_decoder.c
void JPEG_Decode(const char* filename)
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FIL file;
    
    f_open(&file, filename, FA_READ);
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);
    
    // 设置文件源
    jpeg_stdio_src(&cinfo, &file);
    jpeg_read_header(&cinfo, TRUE);
    cinfo.out_color_space = JCS_RGB;
    jpeg_start_decompress(&cinfo);
    
    // 逐行解码
    uint8_t* line = malloc(cinfo.output_width * 3);
    while(cinfo.output_scanline < cinfo.output_height)
    {
        jpeg_read_scanlines(&cinfo, &line, 1);
        RGB888_To_LCD(line, cinfo.output_width);
    }
    
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    f_close(&file);
    free(line);
}

5.3 图像缩放算法

  1. 原始图像
  2. 计算缩放比例
  3. 双线性插值
  4. 目标像素计算
  5. 写入显示缓冲区

六、系统整合

6.1 主程序逻辑

// main.c
int main(void)
{
    HAL_Init();
    SystemClock_Config();
    LCD_Init();
    SD_Init();
    
    while(1)
    {
        switch(current_mode)
        {
            case MODE_BROWSE:
                show_image_list();
                break;
            case MODE_DISPLAY:
                display_current_image();
                break;
            case MODE_SLIDESHOW:
                auto_play_images();
                break;
        }
        key_scan();
    }
}

6.2 内存优化策略

  1. 使用分块解码:将大图分割为多个区块处理
  2. JPEG 解码使用 MCU(Minimum Coded Unit) 缓存
  3. 建立双缓冲机制:
uint16_t buffer1[320*50]; // 50 行缓冲区
uint16_t buffer2[320*50];

七、常见问题解决

问题现象原因分析解决方案
花屏时序配置错误调整 FSMC 时序参数
图片显示错位字节对齐问题添加 __align(4) 修饰缓冲区
JPEG 解码慢未启用硬件加速使用 CRC 加速 DCT 计算
文件读取失败SD 卡格式不兼容格式化为 FAT32 分配单元 32KB

八、成果

8.1 功能演示

  • 图片切换时间:<500ms (320×480 JPEG)
  • 支持幻灯片播放模式
  • 内存占用:<45KB RAM

8.2 性能对比

解码方式320×240640×4801024×768
BMP 直读120ms480ms1900ms
JPEG 软解280ms620ms2400ms
JPEG 硬解85ms210ms780ms

8.3 扩展建议

  1. 添加触摸屏控制
  2. 实现图片旋转功能
  3. 增加 WiFi 传输模块
  4. 添加 EXIF 信息显示

技术图谱

  • 电子相册系统
    • 硬件层: STM32F103RC, TFT-LCD, SD 存储
    • 驱动层: FSMC 总线, SPI 协议, GPIO 控制
    • 中间件: FATFS, LibJPEG, FreeRTOS
    • 应用层: 文件管理,图片解码,用户界面,幻灯播放
    • 扩展能力: 触摸控制,网络传输,图片编辑

目录

  1. 摘要
  2. 一、项目概述
  3. 1.1 系统架构设计
  4. 1.2 硬件组件清单
  5. 1.3 技术指标
  6. 二、开发环境搭建
  7. 2.1 软件工具
  8. 2.2 硬件连接
  9. 2.3 工程创建步骤
  10. 三、TFT-LCD 驱动开发
  11. 3.1 显示屏初始化
  12. 3.2 FSMC 配置
  13. 四、文件系统移植
  14. 4.1 FATFS 配置
  15. 4.2 图片遍历函数
  16. 五、图片解码算法
  17. 5.1 BMP 解码实现
  18. 5.2 JPEG 软解码优化
  19. 5.3 图像缩放算法
  20. 六、系统整合
  21. 6.1 主程序逻辑
  22. 6.2 内存优化策略
  23. 七、常见问题解决
  24. 八、成果
  25. 8.1 功能演示
  26. 8.2 性能对比
  27. 8.3 扩展建议
  28. 技术图谱
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 利用腾讯云 HAI 与 DeepSeek 快速搭建响应式个人网页
  • 数组与哈希表(Map/Object)核心区别及实战
  • Word2Vec 原理与实现详解
  • 电商系统高并发库存设计与扣减策略
  • 前端国际化开发最佳实践
  • GLM-4.6V-Flash-WEB 食品包装识别准确性验证
  • 网络安全行业前景深度解析与入行路径建议
  • 10 款主流 AIGC 降重工具免费与付费版对比评测
  • 基于 Spark 与机器学习的电影票房预测及推荐系统
  • AIGC 技术在元宇宙中的应用与实现
  • Vue3 中点击方法提示不存在,检查是否缺少 setup 暴露
  • AI 产品经理核心人工智能技术概览
  • 字节跳动 DeerFlow 2.0 开源:超级智能体框架架构与实战
  • 基于比迪丽 AI 模型的龙珠主题短视频创作提效方案
  • 哈希算法详解:原理、实现与安全应用
  • 渐进式 Web 应用开发实例:核心技术与实战
  • AI 热榜深度解析:平台生态、多智能体与模型产品化趋势
  • AI 编程工具对比:GitHub Copilot、Trae、Cursor
  • DeepFace 与 OpenCV 实现情绪分析器
  • 数据结构初阶:树的概念、术语与表示方法

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online