donatello
获得 765 次赞
帮助过2489人
在之前的报告中我已经成功从sd卡读取已知文件大小的bmp文件并显示,由于文件大小已知,因此要给这个图片开辟多大的数组也是事先计算好确定好的,
读取txt文本文件这种简单入门的fatfs操作已经学会,那么就可以尝试读取别的文件如bmp文件、jpg文件、mp3文件和mp4文件等,在学习fatfs的道路上走得更远。 官方例程包中自带了从sd卡读取bmp文件并在电容屏上显示的程序,但是这个程序问题多多:1.开发板上电前预先放入sd卡中的bmp文件格式必须是16位彩色,即rgb565格式(rgb565格式已在前面的帖子中详细说明,此处不作解释),而在windows7官方的画图软件中,生成的bmp文件只能选择单色、16色、256色和24位彩色,并没有官方例程所要求的16位彩色格式,并且实际应用中的bmp图片格式也大多是24位彩色。那么16位彩色与24位彩色又有什么区别呢?区别就在24位彩色图片格式的像素色彩使用的是rgb888格式,即一个像素点的红绿蓝灰度各占8位,因此存储一个像素点就需要2^24=16777216=16kb的空间,一个像素点有16777216种变化,基本上可以衡量出世间万物的所有颜色了
调通了sd卡之后,就可以进行基于sd卡的fatfs的学习了。俗话说内行看门道,外行看热闹,平时用stm32插sd卡看图片、播音乐觉得挺好玩,真正自己去调一次fatfs那真不是一般的困难。抛开fatfs中间层驱动ff.c/ff.h/diskio.h那些函数的实现原理不管,就是调用表层api如f_open、f_write这些函数都一波三折,最后还得参考官方例程。 fatfs官方提供了一系列的驱动包,这些驱动包有ff.c/ff.h、ff_gen_drv.c/ff_gen_drv.h、diskio.c/diskio.h、ffconf.h、integer.h,在这些驱动文件中官方已经把fatfs具体如何实现的函数都打包好了,我们无须理会也不要乱改,我们要改的只有带前缀的diskio.c/diskio.h扇区驱动源文件和头文件如sd_diskio.c/sd_diskio.h或者usb_diskio.c/usb_diskio.h,这些函数里面都有一个类型为diskio_drvtypedef的名为xx_driver硬件驱动结构体指针,里面包含有xx_initialize,xx_status,xx_read, xx_write,xx_ioctl五个函数指针,xx为自定义名称如sd、sram、flash、usbhost等等,diskio_drvtypedef的定义是在ff_gen_drv.h里面的,其作用是让fatfs文件系统与相应的sd、sram、flash、usbhost等硬件设备挂载对接,因此在xx_diskio.c/xx_diskio.h中需要“枚举”一个xx_driver出来(本质并不是enum那种枚举,而是像int a那样定义一个int类型的名为a的变量,说是枚举只是更容易理解,就类似于重定义fputc()函数以便让printf()函数选择相应串口外设或者lcd外设一样,说是“充当”或者“挂载器件”更为贴切),并在xx_initialize、xx_read、xx_write的函数中分别定义好外设的初始化函数、外设读取数据函数、外设写入数据函数,只要这些函数都没问题,fatfs就能在指定的存储设备中正常工作。
f412disco板子自带了一个sd卡接口,通信总线为高速的sdio,可以选择1位数据总线模式(sdio_bus_wide_1b)或者4位数据总线模式(sdio_bus_wide_4b),1位总线模式的原理类似于spi的半双工总线,而4位总线模式则算是一种并行总线了。 从电路图中可以看到,sd卡接口接在了f4系列的标准4位数据总线sdio接口,即pc8、pc9、pc10、pc11、pc12、pd2、pd3对应data0、data1、data2、data3、clk、cmd、det引脚。其中det引脚是用于判断是否有sd卡插上了sd卡接口,若有则为低电平,没有则为高电平,此引脚即可用于判断sd卡是否存在,避免在sd卡不存在时mcu也发送sdio指令和数据的情况,减少资源浪费,也可以用作sd卡的外部中断,使得mcu可以用中断方式启动sdio通信,免得mcu一直查询sd卡的存在,这点细节做到位了,用户在mp3播放器进行插拔sd卡的时候会觉得非常友好。
上次我用电容屏显示汉字,这次来点更好玩的,显示图片表情。lcd点阵显示汉字和图片其实区别不大,唯一的区别就是,汉字点阵的色彩单调,只需要1种或几种的颜色即可完成显示,但是图片的颜色是千变万化的,每一个像素点的颜色都不一定完全相同,按照16位真彩色标准,每一个像素点都可以指定为rgb565标准中的任意一种颜色,这种rgb颜色的数据长度为16位,对应红绿蓝三种色彩的位数为5、6、5,即每个点的红绿蓝灰度都分别为2^5、2^6、2^5,总色彩数为2^16=65536,即一个点可以显示65536种颜色,所以这种颜色排布方式又称为rgb565排布。