基于STM32设计的数码相册

发布时间:2023-07-18  

一、项目介绍

项目是基于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("串口工作正常! ");

     if(SDCardDeviceInit()) 

     {

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

     }

     

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

     printf("SD卡Sizeof:%d ",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 ",Show_BMP("1.bmp"));

     

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

     

     //循环读取目录

     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 字节 ",file_info.fname,file_info.fsize);

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

     }

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

     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;      //图片信息

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>