SD卡讀取bmp圖片移植調(diào)試完成
2,接著讓SD卡讀取24位bmp圖片,并顯示。--完成 步驟1,移植。 步驟2,調(diào)試。
調(diào)試步驟:
第一步:驗(yàn)證能從SD的FAT32文件系統(tǒng)中讀取所有bmp圖片數(shù)據(jù)---完成。
第二步:驗(yàn)證處理后的像素?cái)?shù)據(jù)正確。---完成。
第三步:把處理完的像素?cái)?shù)據(jù),通過顯示屏顯示。--完成。
主要困難點(diǎn):一開始不知道24bit bmp的圖片的行末尾數(shù)據(jù)會(huì)自動(dòng)補(bǔ)0,因?yàn)橐粋€(gè)掃描行必須為4的倍數(shù)。
參考了2種代碼。調(diào)試如下。
第一步:驗(yàn)證能從SD的FAT32文件系統(tǒng)中讀取所有bmp圖片數(shù)據(jù)---完成。
一開始以為讀文件的內(nèi)容的函數(shù)不能讀圖片數(shù)據(jù)。來后對比其他參考程序后,發(fā)現(xiàn)是可以讀的,別人也在調(diào)用這個(gè)函數(shù)讀圖片數(shù)據(jù)呢。
復(fù)習(xí)了FAT32的文件系統(tǒng),知道了apple.bmp的數(shù)據(jù)內(nèi)容在2101扇區(qū),于是讓read One block直接讀,但是讀不出。發(fā)現(xiàn)在znfat.c中調(diào)用read one block讀2101扇區(qū)是可以的,說明數(shù)據(jù)能讀,并且讀出來看了下,內(nèi)容和winhex一樣。但是循環(huán)讀幾個(gè)block后,就死機(jī)了。
于是,再往下分析 znFAT_Read_File函數(shù),原來for(i=pfi->FileCurPos;i
imin=pfi->FileCurPos;
imax=pArg->BytesPerSector;
for(i=imin;i
但是因?yàn)閎mp文件大于512byte。所以要循環(huán)讀的。讀完后都放在file_info中,但是發(fā)現(xiàn)讀第一個(gè)512是對的,讀第二個(gè)512就變成了0.后來發(fā)現(xiàn)原因。原來是file_info一定要定義一個(gè)范圍。這樣下次讀的時(shí)候就可以覆蓋之前的512個(gè)字節(jié).一開始定義為UINT8 *file_info;于是循環(huán)讀的時(shí)候就出問題了。改成UINT8 file_info[512];就ok了。已經(jīng)證明能順利從SD的FAT32文件系統(tǒng)中讀取所有bmp圖片數(shù)據(jù),并且和winhex中看出的數(shù)值是一致的。
第二步:驗(yàn)證處理后的像素?cái)?shù)據(jù)正確。---完成。
復(fù)習(xí)了bmp文件的格式,主要是24位bmp的格式,數(shù)據(jù)是從左下角,以行方式讀到右上角的。并且一個(gè)像素由B,R,G三個(gè)字節(jié)組成。前54個(gè)字節(jié)是文件頭。后面的是真正的數(shù)據(jù)值。ok,24為bmp真彩就這幾個(gè)要點(diǎn)。于是看了看把24位轉(zhuǎn)為為16位的方法。這里在調(diào)試的時(shí)候因?yàn)槁┛戳藬?shù)據(jù)的組織方式是左下角到右上角。導(dǎo)致我之前一度懷疑24位轉(zhuǎn)16的代碼有問題。不過,轉(zhuǎn)換代碼中,我沒有把B,G,R轉(zhuǎn)為16位后再進(jìn)行與操作。導(dǎo)致數(shù)據(jù)丟失。后來串口打印出來才看出的。
第三步:把處理完的像素?cái)?shù)據(jù),通過顯示屏顯示。--完成。
這步照理很簡單啊。但是顯示的圖像就是很奇怪,一開始顯示一條斜線。
于是我網(wǎng)上搜索了下,主要有2種方案,
1,一種是一個(gè)個(gè)點(diǎn)寫入。
2,另一種是設(shè)置顯示區(qū)域,然后填充數(shù)據(jù)。后來查出來。
方案1:調(diào)試后發(fā)現(xiàn)。
address_set(x,x,y,y);我移植過來就改了函數(shù)名稱為address_set,其實(shí),我的這個(gè)函數(shù)應(yīng)該是address_set(x,y,x,y);怪不得顯示一條斜線呢!
然后就是每3個(gè)字節(jié),處理成16bit的2個(gè)字節(jié),一點(diǎn)點(diǎn)顯示出來。但是顯示的圖片就是不對。難道讀出的數(shù)據(jù)有問題?我之前檢查過每問題了。難道處理后的數(shù)據(jù)有問題,我之前檢查過函數(shù)也正確。于是,把處理后的數(shù)據(jù)打印出來,與Image2LCD中處理的數(shù)據(jù)對比。發(fā)現(xiàn)了很奇怪,前182個(gè)像素處理的很ok,很特別的是182就是第一行數(shù)據(jù),到第183-185這3個(gè)字節(jié)處理的結(jié)果和Image2LCD是不同的,然后發(fā)現(xiàn)如果放棄183.去處理184-185轉(zhuǎn)為2個(gè)字節(jié),那么就和Image2LCD一致了。然后突然先到了之前網(wǎng)頁上看到的一句話,說一個(gè)掃描行必須為4的倍數(shù)。不是4的倍數(shù)就自動(dòng)補(bǔ)0,這些0就是無效的像素?cái)?shù)據(jù)了。如下圖,終于發(fā)現(xiàn)了關(guān)鍵的問題。但是代碼要怎么改呢?于是乎,想到了方案2的代碼中,本來以為很多余的一句,我把它注釋掉了。原來就是很關(guān)鍵的一句話。znFAT_Read_File(&FileInfo,FileInfo.FileCurOffset,270,file_info);從每行的頭開始讀取數(shù)據(jù)。那么就移植方案2的代碼吧!一移植就成功了。
評論