SD卡Fatfs文件系統(tǒng)BMP文件讀取顯示
首先說下硬件平臺是奮斗的stm32開發(fā)板,320*240的2.4寸TFT(有點小,)。
本文引用地址:http://m.butianyuan.cn/article/201612/325146.htm說下遇到的問題:
- startup_stm32f10x_hd.s 文件里再次修改堆棧大小,上次調試SD卡的時候就已經(jīng)調整了,這次再次調整,見下圖。但是還是有個問題,板子上啊的stm32f103vet6 是512K的ram。按理說堆棧可以調整到“Stack_Size EQU 0x00080000 ”但是卻只能調整到0x0000F0F0這個位置,大家有誰知道的可以告訴我。
- 在操作SD卡的時候,讀取到BMP文件的內容要先釋放到一個數(shù)組空間里,這個空間大小要設定好,否則會出莫名奇妙的問題。
- BMP圖片的文件名不能太長,否則無法讀取,這個應該是Fatfs的問題,沒有具體測試是幾個,但是不能超過10個英文字母(包括10個)。
- 顯示的格式要實現(xiàn)調整好,像我這塊屏是320*240的,事先用畫圖進行修改好,他們的尺寸值要是8的倍數(shù),否則讀取時會出錯。下面是修改的方法,(估計大家都會,就是怕自己忘記了),見下圖。
下面就是把代碼貼出來,這個代碼只是移植成功了,但是BMP文件的格式?jīng)]有去細致了解,中間一部分代碼沒有去深入的探究其原因。
C語言:Codee#20097
#include "TFCard_BMP.h"
/*==================================================================
用到的變量及宏定義
==================================================================*/
BMP_HEADbmp;//圖片文件頭
BMP_POINTpoint;
/*==================================================================
* Function : RGB888ToRGB565
* Description : 把24位圖變成16位圖
* Input Para : unsigned char r , unsigned char g , unsigned char b
* Output Para : void
* Return Value: 顏色值
==================================================================*/
u32RGB888ToRGB565(unsignedcharr,unsignedcharg,unsignedcharb)
{
return(u32) (r&0xF8)<<8| (g&0xFC)<<3| (b&0xF8)>>3;
}
/*==================================================================
* Function : DrawPixel
* Description : 畫點函數(shù),在TFT的某一點上畫一個顏色點
* Input Para : unsigned int x , unsigned int y , int Color ===》 x坐標,y坐標,顏色值
* Output Para : void
* Return Value: void
==================================================================*/
voidDrawPixel(unsignedintx,unsignedinty,intColor)
{
LCD_SetGramPoint(x,y);
LCD_WR_Data(Color);
}
/*==================================================================
* Function : Show_BMP
* Description : 顯示BMP格式的文件,分為圖片和圖標,圖片尺寸是240*320是完全顯示,圖標只顯示內容,其他白色的部分維持原來的顏色
* Input Para : unsigned char type , unsigned int point_x , unsigned int point_y , char *path
===》 顯示的類型:PCITURE圖片,ICON圖標 ,x軸起始點 ,y軸起始點 ,圖片在SD卡里的路徑
* Output Para : void
* Return Value: void
==================================================================*/
voidShow_BMP(unsignedchartype,unsignedintpoint_x,unsignedintpoint_y,char*path)
{
FATFSfs;// 磁盤掛載點
FILfil;// 文件打開點
FRESULTres;// 返回值類型結構體
//unsigned char buffer[4096*4]; // file copy buffer
unsignedcharbuffer[50000];// 這個數(shù)組和堆??臻g大小直接相關
unsignedintbr;// File R/W count
unsignedlongtx,ty,r_data,g_data,b_data;
disk_initialize(0);// 初始化磁盤
res=f_mount(0,&fs);// 掛載設備
while(1)
{
res=f_open(&fil,path,FA_OPEN_EXISTING|FA_READ);// 讀取圖標路徑
res=f_read(&fil,&bmp,sizeof(bmp),&br);// 讀取文件
if((bmp.pic_head[0]==B)&&(bmp.pic_head[1]==M))// 判斷是不是BMP文件
{
res=f_lseek(&fil,((bmp.pic_data_address_h<<16)|bmp.pic_data_address_l));// 采用了Windows的BMP格式,BMP原點在左下角
for(ty=0;ty {
res=f_read(&fil,buffer,(bmp.pic_w_l)*3,&br) ;
for(tx=0;tx {
r_data=*(tx*3+2+buffer);
g_data=*(tx*3+1+buffer);
b_data=*(tx*3+0+buffer);
if(tx<240)
{
point.x=tx;
point.y=bmp.pic_h_l-1-ty;
point.r=r_data;
point.g=g_data;
point.b=b_data;
if(type==PICTURE)// 如果顯示的是圖片的話,白色部分照常顯示
{
DrawPixel(point.x+point_x,point.y+point_y,RGB888ToRGB565(point.r,point.g,point.b));
}
elseif(type==ICON)// 如果顯示的是圖標的話,白色部分不顯示
{// 以下代碼根據(jù) DrawPixel() 函數(shù)更改增加
LCD_SetGramPoint(point.x+point_x,point.y+point_y);// 設定x軸,y軸的坐標
if(RGB888ToRGB565(point.r,point.g,point.b)==0xFFFF)// 判斷是不是白色部分
{
LCD_WR_Data(ili9320_BGR2RGB(LCD_RD_data()) );// 如果是白色就讀取當前顏色值并顯示
}
else
{
LCD_WR_Data(RGB888ToRGB565(point.r,point.g,point.b) );// 如果不是白色就顯示ICON的顏色
}
}
}
}
}
f_close(&fil);// 關閉文件
f_mount(0,NULL);// 卸載設備
break;// 跳出while(1)
}// End of if((bmp.pic_head....
}// End of while(1)....
}// End of void Show_BMP(....
/*==================================================================
用到的變量及宏定義
==================================================================*/
BMP_HEADbmp;//圖片文件頭
BMP_POINTpoint;
/*==================================================================
* Function : RGB888ToRGB565
* Description : 把24位圖變成16位圖
* Input Para : unsigned char r , unsigned char g , unsigned char b
* Output Para : void
* Return Value: 顏色值
==================================================================*/
u32RGB888ToRGB565(unsignedcharr,unsignedcharg,unsignedcharb)
{
return(u32) (r&0xF8)<<8| (g&0xFC)<<3| (b&0xF8)>>3;
}
/*==================================================================
* Function : DrawPixel
* Description : 畫點函數(shù),在TFT的某一點上畫一個顏色點
* Input Para : unsigned int x , unsigned int y , int Color ===》 x坐標,y坐標,顏色值
* Output Para : void
* Return Value: void
==================================================================*/
voidDrawPixel(unsignedintx,unsignedinty,intColor)
{
LCD_SetGramPoint(x,y);
LCD_WR_Data(Color);
}
/*==================================================================
* Function : Show_BMP
* Description : 顯示BMP格式的文件,分為圖片和圖標,圖片尺寸是240*320是完全顯示,圖標只顯示內容,其他白色的部分維持原來的顏色
* Input Para : unsigned char type , unsigned int point_x , unsigned int point_y , char *path
===》 顯示的類型:PCITURE圖片,ICON圖標 ,x軸起始點 ,y軸起始點 ,圖片在SD卡里的路徑
* Output Para : void
* Return Value: void
==================================================================*/
voidShow_BMP(unsignedchartype,unsignedintpoint_x,unsignedintpoint_y,char*path)
{
FATFSfs;// 磁盤掛載點
FILfil;// 文件打開點
FRESULTres;// 返回值類型結構體
//unsigned char buffer[4096*4]; // file copy buffer
unsignedcharbuffer[50000];// 這個數(shù)組和堆??臻g大小直接相關
unsignedintbr;// File R/W count
unsignedlongtx,ty,r_data,g_data,b_data;
disk_initialize(0);// 初始化磁盤
res=f_mount(0,&fs);// 掛載設備
while(1)
{
res=f_open(&fil,path,FA_OPEN_EXISTING|FA_READ);// 讀取圖標路徑
res=f_read(&fil,&bmp,sizeof(bmp),&br);// 讀取文件
if((bmp.pic_head[0]==B)&&(bmp.pic_head[1]==M))// 判斷是不是BMP文件
{
res=f_lseek(&fil,((bmp.pic_data_address_h<<16)|bmp.pic_data_address_l));// 采用了Windows的BMP格式,BMP原點在左下角
for(ty=0;ty
res=f_read(&fil,buffer,(bmp.pic_w_l)*3,&br) ;
for(tx=0;tx
r_data=*(tx*3+2+buffer);
g_data=*(tx*3+1+buffer);
b_data=*(tx*3+0+buffer);
if(tx<240)
{
point.x=tx;
point.y=bmp.pic_h_l-1-ty;
point.r=r_data;
point.g=g_data;
point.b=b_data;
if(type==PICTURE)// 如果顯示的是圖片的話,白色部分照常顯示
{
DrawPixel(point.x+point_x,point.y+point_y,RGB888ToRGB565(point.r,point.g,point.b));
}
elseif(type==ICON)// 如果顯示的是圖標的話,白色部分不顯示
{// 以下代碼根據(jù) DrawPixel() 函數(shù)更改增加
LCD_SetGramPoint(point.x+point_x,point.y+point_y);// 設定x軸,y軸的坐標
if(RGB888ToRGB565(point.r,point.g,point.b)==0xFFFF)// 判斷是不是白色部分
{
LCD_WR_Data(ili9320_BGR2RGB(LCD_RD_data()) );// 如果是白色就讀取當前顏色值并顯示
}
else
{
LCD_WR_Data(RGB888ToRGB565(point.r,point.g,point.b) );// 如果不是白色就顯示ICON的顏色
}
}
}
}
}
f_close(&fil);// 關閉文件
f_mount(0,NULL);// 卸載設備
break;// 跳出while(1)
}// End of if((bmp.pic_head....
}// End of while(1)....
}// End of void Show_BMP(....
有什么錯誤或者不對的地方歡迎大家批評指正。
評論