新闻中心

EEPW首页>嵌入式系统>设计应用> SD卡读取bmp图片移植调试完成

SD卡读取bmp图片移植调试完成

作者: 时间:2016-11-10 来源:网络 收藏
1,完成了SD卡读取文本文件的内容。--完成

2,接着让SD卡读取24位bmp图片,并显示。--完成 步骤1,移植。 步骤2,调试。
调试步骤:
第一步:验证能从SD的FAT32文件系统中读取所有bmp图片数据---完成。
第二步:验证处理后的像素数据正确。---完成。
第三步:把处理完的像素数据,通过显示屏显示。--完成。
主要困难点:一开始不知道24bit bmp的图片的行末尾数据会自动补0,因为一个扫描行必须为4的倍数。

本文引用地址://m.amcfsurvey.com/article/201611/317312.htm

参考了2种代码。调试如下。

第一步:验证能从SD的FAT32文件系统中读取所有bmp图片数据---完成。
一开始以为读文件的内容的函数不能读图片数据。来后对比其他参考程序后,发现是可以读的,别人也在调用这个函数读图片数据呢。

复习了FAT32的文件系统,知道了apple.bmp的数据内容在2101扇区,于是让read One block直接读,但是读不出。发现在znfat.c中调用read one block读2101扇区是可以的,说明数据能读,并且读出来看了下,内容和winhex一样。但是循环读几个block后,就死机了。
于是,再往下分析 znFAT_Read_File函数,原来for(i=pfi->FileCurPos;i BytesPerSector;i++)中的指针中的数值一直在变化。把它改成
imin=pfi->FileCurPos;
imax=pArg->BytesPerSector;
for(i=imin;i 那么这段函数算是可以用了。不会循环几次就死机了。

但是因为bmp文件大于512byte。所以要循环读的。读完后都放在file_info中,但是发现读第一个512是对的,读第二个512就变成了0.后来发现原因。原来是file_info一定要定义一个范围。这样下次读的时候就可以覆盖之前的512个字节.一开始定义为UINT8 *file_info;于是循环读的时候就出问题了。改成UINT8 file_info[512];就ok了。已经证明能顺利从SD的FAT32文件系统中读取所有bmp图片数据,并且和winhex中看出的数值是一致的。

第二步:验证处理后的像素数据正确。---完成。
复习了bmp文件的格式,主要是24位bmp的格式,数据是从左下角,以行方式读到右上角的。并且一个像素由B,R,G三个字节组成。前54个字节是文件头。后面的是真正的数据值。ok,24为bmp真彩就这几个要点。于是看了看把24位转为为16位的方法。这里在调试的时候因为漏看了数据的组织方式是左下角到右上角。导致我之前一度怀疑24位转16的代码有问题。不过,转换代码中,我没有把B,G,R转为16位后再进行与操作。导致数据丢失。后来串口打印出来才看出的。

第三步:把处理完的像素数据,通过显示屏显示。--完成。
这步照理很简单啊。但是显示的图像就是很奇怪,一开始显示一条斜线。
于是我网上搜索了下,主要有2种方案,
1,一种是一个个点写入。
2,另一种是设置显示区域,然后填充数据。后来查出来。
方案1:调试后发现。
address_set(x,x,y,y);我移植过来就改了函数名称为address_set,其实,我的这个函数应该是address_set(x,y,x,y);怪不得显示一条斜线呢!
然后就是每3个字节,处理成16bit的2个字节,一点点显示出来。但是显示的图片就是不对。难道读出的数据有问题?我之前检查过每问题了。难道处理后的数据有问题,我之前检查过函数也正确。于是,把处理后的数据打印出来,与Image2LCD中处理的数据对比。发现了很奇怪,前182个像素处理的很ok,很特别的是182就是第一行数据,到第183-185这3个字节处理的结果和Image2LCD是不同的,然后发现如果放弃183.去处理184-185转为2个字节,那么就和Image2LCD一致了。然后突然先到了之前网页上看到的一句话,说一个扫描行必须为4的倍数。不是4的倍数就自动补0,这些0就是无效的像素数据了。如下图,终于发现了关键的问题。但是代码要怎么改呢?于是乎,想到了方案2的代码中,本来以为很多余的一句,我把它注释掉了。原来就是很关键的一句话。znFAT_Read_File(&FileInfo,FileInfo.FileCurOffset,270,file_info);从每行的头开始读取数据。那么就移植方案2的代码吧!一移植就成功了。



评论


技术专区

关闭