大容量SD卡在WiFi环境要素记录仪中的应用
2016-03-22孙晓林
孙晓林
摘要:研究并设计了一种新型环境要素(温度、湿度)数据采集系统的SD卡存储方案,能够识别MMC卡、SD卡,并且也可以细分SD1.0和SD2.0以及SD2.0是否是SDHC卡还是普通SD卡,几乎兼容了市面上已知的所有SD存储卡类型。该方案选用基于51内核的C8051F320高性能单片机作为主控器,采用SPI总线与SD卡通信,使用FAT32文件系统,解决了长时间对环境温度进行采集所必须面临的数据量庞大的问题,并且本方案将温度数据结合时标信息存储在Excel表格中,可以供计算机直接进行处理。
关键词:C8051F320;SD卡;FAT32;大容量存储
中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2016)02-0037-02
Abstract: A new scheme of SD memory card applied to the WiFi environment elements recording instrument is designed,and the method of distinguishing SD card type is given. High performance MCU C8051F320 based on 51 core is used as main controller and communicates with SD card through SPI bus.System uses FAT32 file system to solve the problems of large data storage, and the scheme stores time information in the excel sheet,which computer could process directly.
Key words: C8051F320; SD card; FAT32; large capacity storage
WIFI环境要素记录仪需要通过WIFI将多点采集的数据传输到总机,由于环境要素变化趋势缓慢,所以只有通过长时间大量采集到的数据才有科研价值,因此总机采用大容量存储设备作为存储介质是一个很好的选择。在市面上最常见的可插拔式存储设备有SD卡,U盘和CF卡。CF卡不能与计算机直接通信,而U盘的硬件电路较复杂,所以综合考虑SD卡是最为可靠的选择。SD卡耐用,安全,存储容量大,满足采集系统需要存储大量数据的需求。
为了方便卡上数据在操作系统上的处理,将Windows操作系统上的FAT32文件系统移植到了单片机系统中,单片机对SD卡的数据写入完全符合FAT32文件系统规范,计算机可直接处理SD卡中的数据。
1 SD卡接口硬件电路设计
C8051F320系列器件使用Silicon Labs的专利CIP-51微控制器内核。
CIP-51和MCS-51指令集完全兼容。CIP-51采用流水线结构,70%的指令的执行时间为1或2个系统时钟周期。CIP-51内核具有标准8052的所有外设部件,包括四个16位计数器/定时器、一个具有增强波特率配置的全双工UART、一个增强型SPI端口、2304字节内部RAM、128字节SFR地址空间及25/21个I/O引脚。C8051F320单片机工作电压3.3V,与SD卡工作电压兼容。
SD卡支持SD模式和SPI模式两种通信方式。采用SPI模式虽然不如SD模式效率高,但是他只占用4个GPIO口。为了提高可移植性,在这里采用GPIO模拟SPI总线时序的方法与SD卡进行通信。SPI通信方式只需要4条信号线即可完成数据的传输,分别是时钟SCLK,主入从出MISO,主出从入MOSI,片选CS。
SD卡的最高数据读写速度为10MB/s,接口电压为2.7—3.6V,具有9个引脚。SD卡使用卡座代替传输电缆,减少了环境干扰,降低了出错率,而且一对一传输没有共享信道的问题。
2 SD卡接口的软件设计
本设计采用GPIO口模拟SPI总线时序的方法与SD卡通信,这里简单介绍
SPI总线时序和SD卡通信方式。
2.1 SPI总线时序
分配四个GPIO口分别作为SCLK、MISO、MOSI和CS,全部设置为推挽输出。写数据时,先将SCLK置为低电平,在MOSI引脚上准备好传输的位,延时一段时间后将SCLK置为高电平,再延时一段时间等待SD卡读走数据。读数据过程与写数据相反,需要注意的是SD卡在时钟下降沿发送数据,SCLK复位后需要延时一段时间之后再检测MISO引脚上的数据。以上过程无论发送者是谁都是以字节为单位传输,先发高位。
2.2 SD卡的初始化与识别
要读写SD卡,首先要对其初始化。初始化成功后,即可发送命令甄别SD卡种类以及获取其他关键信息。普通SD卡和SDHC卡最大的不同在于它们扇区寻址方式,SDHC卡寻址方式为扇区地址寻址,普通SD卡寻址方式为字节地址寻址。因此在读写操作时应该根据不同的卡对地址进行不同的处理。
3 FAT32文件系统
文件管理系统就是要实现一种文件名与文件数据的映射,也就是给定一文件名后就可以找到它所对应的数据。这看似简单的要求,事实上要考虑很多问题,比如数据的不连续存储、存储空间的有效利用等。FAT32文件系统解决这个问题的具体方式是用文件索引的办法,FAT32专门开辟了一块存储空间用来存储文件数据区地址的索引,这个地址也就是文件数据区所占用的簇的地址,之所以用簇作为最小存储单位是FAT32在空间与效率的矛盾中做出的权衡。这块专门的空间就是FAT32的核心--文件分配表(FAT)。
FAT表的表项与数据区中的簇是一一对应的,每一个表项是32位无符号整数值,这些值就是表项的属性,如果一个文件不止占用一个簇,那么它对应的起始簇的表项值就是下一个簇的地址,其他表项以此类推就形成了一个链表结构,通过这种链表结构便可以方便地查询整个文件数据。
3.1 FAT32文件系统结构
FAT32文件系统可以分为以下几个部分:MBR:主引导记录。主要功能是记录各个分区的信息(分区信息由MBR中的DPT记录)。
DBR:DOS引导记录。DBR中的BPB(BIOS参数块)记录了很多非常关键的参数,如扇区和簇的大小、FAT表的大小、根目录的位置等。
FAT:FAT32的核心,上文中已有讲解,这里不再赘述。
首目录:即第一个目录,是进入磁盘的第一个入口。首目录扇区存储的是文件索引还有子目录索引。
文件/目录项:通常是一个32字节的数据段,用来记录文件和目录的相关信息,如名称、大小、时间、数据开始位置等。
数据区(DA):是FAT32文件系统的数据存储的主体部分。数据区中存储的是文件和目录的数据,本身是由最小存储单元(簇)构成的。
DBR包含了与文件系统相关的很多极为重要的参数信息,DBR扇区有一个非常明显的标志,那就是它的开头是一个跳转指令(EB 58 90)。我们真正关心的是中间的79个字节的数据,这79个字节就是BPB。
在保留扇区之后紧接着的就是FAT区,存有文件分配表,文件分配表一般有两个。接下来是首目录簇,首目录簇簇号是第2簇,第0和第1簇为保留簇。具体各个区域地址的计算可从BPB表中解析出的相关数据计算获得。
3.2 FAT32文件系统的实现
本文设计的文件系统采用模块化结构,所有功能封装在相应的功能函数中,总体框架如图1所示。
本系统属于自动化控制,所以没有提供用户使用的应用程序,设备上电后自动工作。基于此,文件系统的操作也是基于一套流程自动工作,文件系统具体工作流程如图2所示。
图2中文件系统的工作全部借助功能函数来完成。寻找文件夹功能通过unsigned long FindDir()函数完成,这个函数依次将首目录中的文件目录项读出来,文件夹在FAT32中也被看成一个文件,然后通过判断每个文件名称是否是CSV寻找文件夹。
如果文件夹已经存在则调用ClearFile(unsigned long)函数删除原先的.CSV文件,参数传入的是文件夹的起始簇地址,地址由FindDir()函数返回,删除操作是将文件目录项的前十一个字节也就是文件名和扩展名字段写为0xE5,0x20,…,0x20即为删除,之后还需要对FAT表进行复位操作,将文件夹所占用的簇的簇项还原成空簇。
如果文件夹不存在,则创建CSV文件夹,创建文件夹首先需要构造文件目录项,文件目录项最重要的三项就是文件名、扩展名和起始簇,文件夹不需要扩展名,文件名定义为CSV,起始簇通过调用unsigned long FindNextCLus(unsigned long)函数完成,传入的参数是上一次刚刚分配的簇地址,这样函数就从这个簇项开始向下搜索空簇,而不用每次都从0簇开始,需要注意的是,每次分配了一个空簇需要将这个簇对应的数据区内容全部复位为0,以免上次删除的文件内容还留在数据区中。
文件目录项构造完毕后,函数寻找首目录中空闲空间以安插构造好的文件目录项,这个过程需要注意极限情况,即首目录簇空间刚刚好用尽,这样需要先构造新簇后再安插。文件夹和文件不同之处在于,文件数据区就是文件内容,而文件夹的数据区中依然是类似首目录簇中的一个个文件目录项,文件夹数据区最开始的两个目录项是规定好的,第一个目录项把该文件夹在首目录中的目录项前十一个字节更换成0x2E,0x20,…,0x20,第二个改为0x2E,0x2E,…,0x20并且把起始簇地址写为0,其实这两个目录项就是在文件结构中经常见到的”.”和”..”。创建文件与创建文件夹过程大同小异,构造好文件目录项之后安插到文件夹目录簇中即可,也需要注意极限情况。
以上创建的文件是.CSV格式,之所以创建这样格式的文件是因为该文件格式支持把数据以ASCII码写入,并且以逗号分隔之后,在EXCEL表格里每一个以逗号分隔的数据就单独显示在一个单元格中,不需要再做任何处理。所以当总机获得了一个数据采集端传来的数据后就把它转化成ASCII码并且以逗号分隔写入到文件数据区中。数据写入操作由unsigned int WriteDataToSD(unsigned char*,unsigned char)完成,指针参数指向25个字节的数据包,函数内部主要是完成向缓冲区复制数据包的工作,512字节缓冲区装满后写入文件中,并且更新文件长度,对扇区计数,8个扇区装满后给文件分配新簇。另一个参数是准备复制进缓冲区的数据包长度,因为缓冲区大小不是数据包长度整数倍,所以最后肯定不能一次性将25个字节写入,具体能写入多少就需要程序进行判断,实现方法是让函数返回缓冲区已写入字节长度给一个变量WriteByte,然后进行计算: (512-WriteByte)>25? 25:512- WriteByte,结果值在下一次调用函数时作为参数传入。
最后在采集完数据需要系统停止工作时极有可能缓冲区并没有被装满,也就不会触发写SD卡的操作,如果不进行处理的话这些数据就会被丢弃,虽然丢弃的数据量对整体采集的数据来说非常小,但是为了提高系统的可靠性,在这里还是用一个函数WriteWhenOff()来处理,强制将缓冲区里数据写入到SD卡,这就需要WriteDataToSD()函数在内部往SD卡写数据同时更新一些全局变量以记录文件数据区待写入空间的地址,以便于调用WriteWhenOff()函数时可以接着往下写。
4 结语
本文介绍了SD卡在WiFi环境要素记录仪中的应用,使用C8051F320单片机处理与SD卡的通信,极大地提高了通信速率。本系统很好地解决了市面上各种SD卡的识别问题,提高了可靠性,并给出了适用于嵌入式系统的FAT32文件系统的实现,直接将数据存入EXCEL表格中供PC处理。
参考文献:
[1] 唐磊,洪传荣,朱广信.基于FPGA的SD卡控制器设计[J].电声技术,2011,3(3):29-31.
[2] 魏来,周穗华,刘旭东.基于SD卡的水声信号采集系统设计[J].海洋技术学报,2010,2(2):51-55.
[3] 李文华,徐国洪,胡华文.基于FAT32文件系统的SD卡数据存储结构研究[J].长江大学学报,2012,9(6):102-104.