一、項(xiàng)目介紹
項(xiàng)目是基于STM32設(shè)計(jì)的數(shù)碼相冊(cè),能夠通過(guò)LCD顯示屏解碼顯示主流的圖片,支持bmp、jpg、gif等格式。用戶(hù)可以通過(guò)按鍵或者觸摸屏來(lái)切換圖片,同時(shí)還可以旋轉(zhuǎn)顯示,并能夠自適應(yīng)居中顯示,小尺寸圖片居中顯示,大尺寸圖片自動(dòng)縮小顯示(超出屏幕范圍)。圖片從SD卡中獲取。
二、設(shè)計(jì)思路
2.1 硬件設(shè)計(jì)
本項(xiàng)目所需的主要硬件:
- STM32F103ZET6
- LCD屏幕
- SD卡模塊
- 按鍵和觸摸屏
2.2 軟件設(shè)計(jì)
(1)解碼圖片
在STM32芯片中,解碼圖片需要將讀取到的數(shù)據(jù)存入圖形緩沖區(qū)中,以便進(jìn)行圖畫(huà)顯示。常用的解碼算法有JPEG解碼和BMP解碼。
(2)圖片顯示
為了更好的實(shí)現(xiàn)圖片旋轉(zhuǎn)和縮放功能,在顯示圖片時(shí)需對(duì)其進(jìn)行矩陣運(yùn)算。通過(guò)左右翻轉(zhuǎn)和上下翻轉(zhuǎn),可實(shí)現(xiàn)圖片的旋轉(zhuǎn)功能。通過(guò)計(jì)算圖片與顯示屏幕之間的比例關(guān)系并進(jìn)行縮放,實(shí)現(xiàn)自適應(yīng)居中和圖片的縮放功能。
(3)SD卡
SD卡模塊可通過(guò)SPI接口與STM32芯片進(jìn)行通信,讀取SD卡中的圖片數(shù)據(jù),實(shí)現(xiàn)對(duì)圖片的加載和顯示。
(4)按鍵和觸摸屏
在使用過(guò)程中,用戶(hù)可以通過(guò)按鍵和觸摸屏對(duì)圖片進(jìn)行切換、旋轉(zhuǎn)和縮放等操作。通過(guò)設(shè)置中斷處理函數(shù),響應(yīng)用戶(hù)的操作并及時(shí)更新顯示屏幕上的圖片。
2.3 圖片播放流程圖
2.4 顯示效果
三、代碼設(shè)計(jì)
3.1 主函數(shù)
#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" //文件系統(tǒng)
#include "bmp.h" //文件系統(tǒng)
#include "iic.h"
#include "at24c02.h"
#include "xpt2046.h"
#include "lcd.h"
?
?
FATFS fs; // 用戶(hù)定義的文件系統(tǒng)結(jié)構(gòu)體
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(); //觸摸屏校準(zhǔn)
printf("串口工作正常!\\r\\n");
if(SDCardDeviceInit())
{
printf("SD卡初始化失敗!\\r\\n");
}
sd_size=GetSDCardSectorCount(); //檢測(cè)SD卡大小,返回值右移11位得到以M為單位的容量
printf("SD卡Sizeof:%d\\r\\n",sd_size >>11);
f_mount(&fs,"0:",1); // 注冊(cè)文件系統(tǒng)工作區(qū),驅(qū)動(dòng)器號(hào) 0,初始化后其他函數(shù)可使用里面的參數(shù)
LcdClear(0xFFFF);
//f_mkdir("0:/目錄創(chuàng)建測(cè)試!"); //測(cè)試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("目錄打開(kāi)失敗!\\r\\n");
//循環(huán)讀取目錄
while(f_readdir(&dir_dp,&file_info)==FR_OK)
{
if(file_info.fname[0]==0)break; //判斷目錄跳出條件,表示目錄已經(jīng)讀取完畢
if(strstr(file_info.fname,".bmp")) //過(guò)濾目錄
{
printf("文件名稱(chēng): %s,文件大小: %ld 字節(jié)\\r\\n",file_info.fname,file_info.fsize);
}else printf("文件名稱(chēng): %s,文件大小: %ld 字節(jié)\\r\\n",file_info.fname,file_info.fsize);
}
if(f_closedir(&dir_dp)!=FR_OK)printf("目錄關(guān)閉失敗!\\r\\n");
while(1)
{
LED1=!LED1;
DelayMs(100);
}
}
?