(2)MC9S12UF32与SD卡之间的数据传输
在完成对时钟频率和传输数据线宽度的配置之后,通过发送相应的读写命令就可以实现单片机与SD卡之间的数据传输了。在单片机向SD卡写入数据的过程中,编程者将需要写入的数据写入SDHC模块的SDATA寄存器(16位)之后,该数据将被转移至发送数据FIFO中。与此同时,只要发送数据FIFO非空,其中的数据就会不断地通过数据线被写入SD卡的相应位置。在单片机从SD卡中读取数据的过程中,SD卡中的数据将不断发送至接收数据FIFO中。只要接收FIFO非空,单片机就可以不断地通过读SDATA寄存器得到接收数据FIFO中的数据。
2.2 DSl2887实时钟模块
DSl2887模块使用数据/地址复用的并行异步总线,可以为单片机提供100年以内的实时钟信息(年/月/日/时/分/秒)。它内部具有石英晶振和锂电源,首次使用时,需要对该模块内部的寄存器进行相应配置,激活晶振使其进入工作状态。由于DSl2887内部带有锂电源,所以一旦晶振被激活,即使外部掉电,该模块依然可以保存并提供正确的实时钟信息。
设定DSl2887的时间和从DSl2887中读取时间信息的底层程序比较简单,只需参照芯片手册对寄存器进行合理配置。但是,需要特别注意的是,在写时钟和读取时钟之前需要锁存时钟信息相关的buffer,防止在读写过程中由于出现时钟信息自动更新情况而导致的错误。系统中,在每次读写实时钟之前,查询DSl2887内部控制寄存器A最高位UIP是否为O,以避免上述错误的产生。因为芯片手册中给出,一旦UIP=O,那么在244μs内实时钟模块都不会自动更新当前的时钟信息,而这段时间足以让单片机完成读写实时钟的过程。
3 FatFS文件系统的移植与配置
3.1 FatFS软件包简介
采用文件系统,是为了在单片机能够对SD卡进行数据读写的同时,保证其读写的数据能够被大多数通用设备识别。换言之,数据在存储器内的组织型式,需要遵循一些已有的工业标准和规范。例如使用FAT文件系统,数据存储单元的SD卡取下来后,可以使用任何标准的读卡器在windows、Linux等PC机上读出。
当前著名的嵌入式文件系统有若干种选择,比如EFSL(Embedded Filesystem Library)、uC/FS、/TinyFatFS等。这之中EFSL和FatFs都是开放源码的,具有十分详尽的文档和函数手册,除错更新也十分及时,在本文的设计中我们采用的是FatFS。
FatFS采用使用ANSI C编写,具有很好的硬件平台独立性,使用者只需要对源程序进行简单的修改和配置,就可以将其移植到各种系列的单片机上。此外,它的内存开销很小,ROM的占有量在十几KB的量级,使用者可以根据不同的应用方便的对代码进行裁减。FatFS支持FATl2、FATl6和FAT32,可以建立独立的缓冲区对多个文件进行读写。FatFs是一个不断更新完善的软件,大量的相关信息可以从原作者的主页上得到(http://elm-chan.org/fsw/ff/00index_e.html),同时原作者也做了很多性能测试的工作。
3.2 FatFS的移植
可从FatFS的主页上下载得到FatFS R0.07版本。FatFS的主程序包含5个文件,即diskio.c、diskio.h、ff.c、ff.h和integer.h。其中,diskio.c和diskio.h是与底层硬件I/O相关的函数;ff.c和ff.h是应用函数,主要涉及FatFS的配置和裁减;而integer.h中定义了FatFS软件所使用的各种数据类型。
移植FatFS的过程中基本不需要对diskio.h和ff.c进行修改。除了核实integer.h中的数据类型定义是否与MC9S12U32数据类型相符之外,移植的重点工作在于diskio.c中6个主要函数的实现和ff.h中对于文件系统的裁减配置。dikio.c包含的6个接口函数:disk_initial-ize,disk status,disk ioctl,disk read,disk write和disk_fattime。它们分别实现存储介质的初始化、读取/写入若干个扇区的数据和获取实时钟信息的功能。