基于STM32设计的数码相册

发布者:平安幸福最新更新时间:2023-07-18 来源: elecfans关键字:STM32  数码相册  显示效果 手机看文章 扫描二维码
随时随地手机看文章

一、项目介绍

项目是基于STM32设计的数码相册,能够通过LCD显示屏解码显示主流的图片,支持bmp、jpg、gif等格式。用户可以通过按键或者触摸屏来切换图片,同时还可以旋转显示,并能够自适应居中显示,小尺寸图片居中显示,大尺寸图片自动缩小显示(超出屏幕范围)。图片从SD卡中获取。

image-20230618135436038

二、设计思路

2.1 硬件设计

本项目所需的主要硬件:

  • STM32F103ZET6

  • LCD屏幕

  • SD卡模块

  • 按键和触摸屏

2.2 软件设计

(1)解码图片

在STM32芯片中,解码图片需要将读取到的数据存入图形缓冲区中,以便进行图画显示。常用的解码算法有JPEG解码和BMP解码。

(2)图片显示

为了更好的实现图片旋转和缩放功能,在显示图片时需对其进行矩阵运算。通过左右翻转和上下翻转,可实现图片的旋转功能。通过计算图片与显示屏幕之间的比例关系并进行缩放,实现自适应居中和图片的缩放功能。

(3)SD卡

SD卡模块可通过SPI接口与STM32芯片进行通信,读取SD卡中的图片数据,实现对图片的加载和显示。

(4)按键和触摸屏

在使用过程中,用户可以通过按键和触摸屏对图片进行切换、旋转和缩放等操作。通过设置中断处理函数,响应用户的操作并及时更新显示屏幕上的图片。

2.3 图片播放流程图

image-20230618135212377

2.4 显示效果

image-20230618135401101

image-20230618135409530

image-20230618135417655

image-20230618135426430

image-20230618135436038

三、代码设计

3.1 主函数

#include "stm32f10x.h"

 #include "led.h"

 #include "delay.h"

 #include "key.h"

 #include "usart.h"

 #include < string.h >

 #include < stdio.h >

 #include "sd.h" //SD卡

 #include "ff.h" //文件系统

 #include "bmp.h" //文件系统

 #include "iic.h"

 #include "at24c02.h"

 #include "xpt2046.h"

 #include "lcd.h"

 

 

 FATFS fs;  // 用户定义的文件系统结构体

 int main()

 {

     DIR  dir_dp;

     FILINFO file_info;

     u32 sd_size;    //存放SD卡返回的容量

     BeepInit();       //蜂鸣器初始化

     LedInit();      //LED灯初始化 

     UsartInit(USART1,72,115200);

     KeyInit();     //按键初始化

     IICInit();

     LcdInit();

     TOUCH_Init(); 

     //TOUCH_ADJUST(); //触摸屏校准

     

     printf("串口工作正常!\r\n");

     if(SDCardDeviceInit()) 

     {

        printf("SD卡初始化失败!\r\n");

     }

     

     sd_size=GetSDCardSectorCount(); //检测SD卡大小,返回值右移11位得到以M为单位的容量

     printf("SD卡Sizeof:%d\r\n",sd_size >>11);

     

   f_mount(&fs,"0:",1);  // 注册文件系统工作区,驱动器号 0,初始化后其他函数可使用里面的参数

     LcdClear(0xFFFF);

     

     //f_mkdir("0:/目录创建测试!"); //测试OK

     //f_unlink("0:/123"); //删除目录,注意只能删除空目录

     //f_unlink("0:/1.bmp");//删除文件

     //printf("%d\r\n",Show_BMP("1.bmp"));

     

     if(f_opendir(&dir_dp,"0:/bmp")!=FR_OK)printf("目录打开失败!\r\n");

     

     //循环读取目录

     while(f_readdir(&dir_dp,&file_info)==FR_OK)

     {

             if(file_info.fname[0]==0)break;    //判断目录跳出条件,表示目录已经读取完毕

             if(strstr(file_info.fname,".bmp")) //过滤目录

             {

                     printf("文件名称: %s,文件大小: %ld 字节\r\n",file_info.fname,file_info.fsize);

             }else   printf("文件名称: %s,文件大小: %ld 字节\r\n",file_info.fname,file_info.fsize);

     }

     if(f_closedir(&dir_dp)!=FR_OK)printf("目录关闭失败!\r\n");

     while(1)

     {   

          LED1=!LED1;

          DelayMs(100);

     }

 }

 

3.2 BMP图片解码

#include "bmp.h"

 unsigned short RGB888ToRGB565(unsigned int n888Color)  

 {  

     unsigned short n565Color = 0;  

   

     // 获取RGB单色,并截取高位  

     unsigned char cRed   = (n888Color & RGB888_RED)   > > 19;  

     unsigned char cGreen = (n888Color & RGB888_GREEN) > > 10;  

     unsigned char cBlue  = (n888Color & RGB888_BLUE)  > > 3;  

   

     // 连接  

     n565Color = (cRed < < 11) + (cGreen < < 5) + (cBlue < < 0);  

     return n565Color;  

 }  

 

 unsigned int RGB565ToRGB888(unsigned short n565Color)  

 {  

     unsigned int n888Color = 0;  

   

     // 获取RGB单色,并填充低位  

     unsigned char cRed   = (n565Color & RGB565_RED)    > > 8;  

     unsigned char cGreen = (n565Color & RGB565_GREEN)  > > 3;  

     unsigned char cBlue  = (n565Color & RGB565_BLUE)   < < 3;  

   

     // 连接  

     n888Color = (cRed < < 16) + (cGreen < < 8) + (cBlue < < 0);  

     return n888Color;  

 }  

 

 

 

 /*

 函数功能:实现截图功能

 参    数:

                 char filename:文件名称

 返 回 值:0表示成功,1表示失败

 */

 u8 C_BMP(const char *filename,u32 Width,u32 Height)

 {

     FIL  file; // 用户定义的文件系统结构体

     u8   res;  // 保存文件操作的返回值

     BITMAPFILEHEADER BmpHead; //保存图片文件头的信息

   BITMAPINFOHEADER BmpInfo; //图片参数信息

     char *p;

     u32 cnt,c_32;

     int x,y;

     u16 c_16; //存放16位的颜色

     

     /*1. 创建一张BMP图片*/

     res = f_open(&file,filename, FA_OPEN_ALWAYS | FA_WRITE);

     if(res!=0)return 1;

     

     /*2. 创建BMP的图片头参数*/

     memset(&BmpHead,0,sizeof(BITMAPFILEHEADER)); //将指定空间赋值为指定的值

     p=(char*)&BmpHead.bfType; //填充BMP图片的类型

     *p='B';

     *(p+1)='M';

 

     //BmpHead.bfType=0x4d42;//'B''M'   //0x4d42

     BmpHead.bfSize=Width*Height*3+54;  //图片的总大小

     BmpHead.bfOffBits=54;              //图片数据的偏移量

   res =f_write(&file,&BmpHead,sizeof(BITMAPFILEHEADER),&cnt);

     if(res!=0)return 1;

     

     /*3. 创建BMP图片的参数*/

     memset(&BmpInfo,0,sizeof(BITMAPINFOHEADER));

     BmpInfo.biSize=sizeof(BITMAPINFOHEADER); //当前结构体大小

     BmpInfo.biWidth=Width;

     BmpInfo.biHeight=Height;

     BmpInfo.biPlanes=1;

     BmpInfo.biBitCount=24;

     res =f_write(&file,&BmpInfo,sizeof(BITMAPINFOHEADER),&cnt);

     if(res!=0)return 1;

         

     /*4. 读取LCD屏的颜色数据,用于创建BMP图片*/

     for(y=Height-1;y >=0;y--)

     {

           for(x=0;x< Width;x++)

           {

                 c_16=LcdReadPoint(x,y); //读取LCD屏上一个点的颜色

                   c_32=RGB565ToRGB888(c_16); //颜色的转换

                   res =f_write(&file,&c_32,3,&cnt);

                   if(res!=0)return 1;

             }

     }

     

     /*5. 关闭文件*/

     f_close(&file);

 }

 

 

 /*

 函数功能:BMP图片显示功能

 参    数:

                 char filename:文件名称

 返 回 值:0表示成功,1表示失败

 */

 u8 Show_BMP(const char *filename)

 {

     FIL  file; // 用户定义的文件系统结构体

     u8   res;  // 保存文件操作的返回值

     BITMAPFILEHEADER BmpHead; //保存图片文件头的信息

   BITMAPINFOHEADER BmpInfo; //图片参数信息

     char *p;

     u32 cnt,c_24;

     int x,y;

     u16 c_16; //存放16位的颜色

     

     /*1. 打开一张BMP图片*/

     res = f_open(&file,filename,FA_READ);

     if(res!=0)return 1;

     

     /*2. 读取BMP的图片头参数*/

   res =f_read(&file,&BmpHead,sizeof(BITMAPFILEHEADER),&cnt);

     if(res!=0)return 1;

     

     /*3. 读取BMP图片的参数*/

     res =f_read(&file,&BmpInfo,sizeof(BITMAPINFOHEADER),&cnt);

     if(res!=0)return 1;

     

     /*4.显示BMP图片*/

     f_lseek(&file,BmpHead.bfOffBits); //移动到RGB数据的存放位置

     

     //后期的优化:读取一行的数据,再显示一行。

    for(y=0;y< BmpInfo.biHeight;y++)

      {

             for(x=0;x< BmpInfo.biWidth;x++)

          {

                 res =f_read(&file,&c_24,3,&cnt);

                     if(res!=0)return 1;

                 c_16=RGB888ToRGB565(c_24); //转换颜色

                 LcdDrawPoint(x,y,c_16);

          }

      }

     /*5. 关闭文件*/

     f_close(&file);

 }

 

 

3.3 jpeg图片解码

#include "piclib.h"

 #include "nt35310_lcd.h"

 _pic_info picinfo;      //图片信息

[1] [2] [3]
关键字:STM32  数码相册  显示效果 引用地址:基于STM32设计的数码相册

上一篇:STM32系列之LCD驱动接口与驱动程序介绍
下一篇:基于STM32跑步路径记录

推荐阅读最新更新时间:2024-11-02 21:37

STM32 ADC应用中信号源特性对转换结果的影响
STM32家族中的所有芯片都内置了逐次逼近寄存器型ADC模块.内部大致框架如下: 每次ADC转换先进行采样保持,然后分多步执行比较输出,步数等于ADC的位数,每个ADC时钟产生一个数据位。说到这里,用过STM32 ADC的人是不是想到了参考手册中关于12位ADC转换时间的公式: ST官方就如何保障或改善ADC精度写了一篇应用笔记AN2834。该应用笔记旨在帮助用户了解ADC误差的产生以及如何提高ADC的精度。主要介绍了与ADC设计的相关内容,比如外部硬件设计参数,不同类型的ADC误差来源分析等,并提出了一些如何减小误差的设计上建议。 这里我摘取部分内容,结合个人的理解加以整理与大家分享。更多细节可以去www.s
[单片机]
<font color='red'>STM32</font> ADC应用中信号源特性对转换结果的影响
STM32 触摸屏触摸功能
要用到触摸屏首先就要对触摸屏的原理有一定的了解,我想这个是前提,也不用太多说的。就是当触笔触到屏上时,对应的位置就会产生相应大小的电压,输入到芯片,AD转换后得到一个数据。而触摸校准就是将接受到的原始模数转换值转换成屏幕像素坐标。 再就是了解触摸芯片,知道他的工作方式,以及跟STM32的连线。触摸实验中,我的实验板是用SPI口来实现数据的传输的,即SPI与xpt2046相连。 触摸屏控制芯片ADS7843中文资料 ADS7843是一个内置12位模数转换、低导通电阻模拟开关的串行接口芯片。供电电压2.7~5 V,参考电压VREF为1 V~+VCC,转换电压的输入范围为0~ VREF,最高转换速率为125 kHz。 ADS
[单片机]
<font color='red'>STM32</font> 触摸屏触摸功能
Keil STM32工程环境搭建
ST官方提供了一套操作STM32各种外围设备的库,使用该库可以快速的搭建STM32工程,简化工作。 一、【安装STM32库】 将下载后的stm32f10x_stdperiph_lib.zip解压后得到三个文件夹分别是: Libraries 、 Project 、 Utilities 将这3个目录复制到 Keil uVision4 的安装目录,和目录中的文件覆盖合并。 二、【新建工程】 1、打开 Keil uVision4 ,在Project菜单中选择新建工程,选择工程要保存的位置,在弹出的“Select Device for target”的对话框中选择使用的STM32单片机的型号如“STM32F103C8”,点确定,然后
[单片机]
STM32】双堆栈的使用
首先了解一下双堆栈的知识,下面的图片来自《Cortex-M3权威指南》,有点枯燥,但还是要看的。 总结: 1.系统复位后默认使用的是MSP,复位后的状态是特权级线程状态,在这个状态下是允许修改寄存器 CONTROL (见上面的图片)的。进入到用户特权以后就不能修改这些寄存器了。 2.用户特权的情况(也就是用户建立的非中断服务程序)下可以使用MSP或PSP,特权模式(中断服务程序)只能使用MSP。 3.还有很重要的一条就是.假如在用户模式下使用的是PSP,那么寄存器的数值被保存到任务堆栈的空间,进入中断程序后就开始使用MSP,如果还有一个高
[单片机]
【<font color='red'>STM32</font>】双堆栈的使用
STM32开发笔记68: keil中使用ST-Link不能成功下载的真实原因
单片机型号:STM32F091RCT6 在STM32开发笔记67: 在keil中使用ST-Link不能成功下载的解决方法提到解决keil中使用ST-Link不能成功下载的一种方法,经仔细分析其实原因还在于程序上。 不能成功下载的程序中,包含如下程序,: CInit::CInit(uint8_t mode) { //底层初始化 HAL_Init(); //GPIO时钟使能 __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENAB
[单片机]
STM32 读写保护功能及设置
功能:: 读保护设置后将不能读出flash 的内容;当解除读保护的时候stm32 会自动擦出 整篇flash; 设置: 读保护设置:在程序的开头加入“读保护”代码,即实现了读保护功能;(每次程序 运行先 开保护) 解除读保护:解除读保护可以设置在按键里面,方便实现解锁,也不可不设; (1)设置读保护: if(FLASH_GetReadOutProtectionStatus() != SET) { //FLASH_Unlock();不解锁FALSH 也可设置读保护??? FLASH_ReadOutProtection(ENABLE); } (2)解除读保护 if(FLASH_GetReadOutProtectionStatus()
[单片机]
使用ST-Link Utility去除STM32芯片读写保护
问题:使用ISP/J-Link/ST-Link等无法下载代码,提示芯片写保护;读芯片信息时提示读保护。 原因:一般是修改了选项字节。 解决方法:这里使用ST-Link Utility来修改选项字节。 使用ST-Link连接到STM32芯片,点击Connect。 存在读保护。 修改选项字节。 将读保护等级修改为Level 0。 打钩的扇区会添加写保护,点击Unselect all不选择写保护。 写入选项字节后Flash会被擦除。 能正常写入程序。
[单片机]
使用ST-Link Utility去除<font color='red'>STM32</font>芯片读写保护
stm32+GPS定位
这周是个巨大任务,GPS模块调试。听着是挺高大上的样子,不过拿到模块的时候,还是什么都不懂,于是开始我的研究之旅。首先。直接用串口接GPS模块,连上电脑。打开串口调试助手,会看到模块给PC机发很多串口信息,如下: $GPRMC,055818.00,V,,,,,,,110515,,,N*7D $GPVTG,,,,,,,,,N*30 $GPGGA,055818.00,,,,,0,05,86.72,,,,,,0000*69 $GPGSA,A,1,27,42,31,26,50,,,,,,,,99.99,86.72,99.99*3B $GPGSV,3,1,12,08,24,044,35,09,31,315,,10,00,317,,16,67
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved