引言
舰船自动舵参数采集传输系统设计中,大量的自动舵参数数据都存储在外部介质SD卡中。为使存储的采集数据可直接在PC机上读取、处理,需要使用文件系统组织数据格式。文件系统是操作系统用于明确磁盘或分区上文件的方法和数据结构,是对文件的管理规则,也是操作系统的重要组成部分,而操作系统对处理器要求比较高,且占用一定的存储空间,舰舵参数采集系统微处理器C8051F500没有操作系统,这就需要在SD卡上建立文件系统。而建立文件系统就需要实时时钟来管理数据文件的创建、修改、访问等详细时间信息。
通常用的单片机没有实时时钟部件,如果需要此功能就得使用定时器来实现,而一旦系统掉电时钟就不能运行,嵌入式文件系统就没有了时钟,这与设计要求不相符。高精度实时时钟芯片DS3231不仅能够在一定温度范围内提供优于2 min/年的计时精度[1],而且包含电池输入端,断开主电源仍然可以保持精确计时。因此,本文提出通过DS3231时钟芯片连续不断地给嵌入式文件系统提供实时时钟的方案。
1 存储系统结构
SD卡存储系统结构如图1所示,C8051F500单片机是主控芯片,通过SPI接口与SD卡实现数据通信,采集的数据在FAT32文件系统管理下,以文件形式存储于SD卡中,如.txt、.doc、.dat等。
图1 存储系统框图
2 FAT32文件系统的实现
目前常用的文件系统有两类[2]:基于微软Windows操作系统的FAT16、FAT32、NTFS、exFAT文件系统;Linux系统下的EXT2、EXT3、EXT4。Windows 操作系统使用广泛,且SD卡容量比较大,因此这里选用FAT32文件系统。
FAT32文件系统的实现方法可以分为[3]:直接法,分析FAT32文件系统的组织结构,遵循文件生成机制,编写程序代码实现功能;移植法,移植FAT文件系统模块,调用其提供的应用接口函数,同样可以实现功能。
目前比较流行使用的FAT文件系统模块主要有[4]:周立功公司的zlg/FS、Micrium公司的μC/FS、SourceForge.net网站上发布的开源项目efsl,以及日本电子爱好者设计并维护的FATFS文件系统模块。以上4个文件系统模块各有特点:zlg/FS因读写速率较慢,主要用于实验教学;Micrium公司的μC/FS一般在商业上使用;efsl及FATFS都是免费开源软件,FATFS相对成熟一些。
本文采用了移植FATFS Module方法,FATFS Module专门为小型嵌入式系统而设计,图2FATFS架构图采用标准的C语言编程,具备良好的硬件平台独立性,移植到8051、AVR等单片机上,只需简单修改。它还支持FAT12、FAT16和FAT32,以及多个存储介质,可以对多个文件进行读/写。FATFS整体框架如图2所示。
图2 FATFS框架图
顶层是应用层,调用FATFS Module提供的一系列API函数(如:f_open、f_read、f_write、f_close等),用户即使不理解FAT协议,也可以利用应用接口函数轻松地读/写文件;中间层完整地实现FAT文件读/写协议,用户无需对此进行任何修改;底层是用户在移植过程中需要处理的接口,需要用户编写代码,它包括存储介质的读/写接口Disk I/O和文件创建修改时间所需的实时时钟。
嵌入式文件系统的移植可以分为3步:编写SD卡的通信函数,编写RTC时钟函数和FATFS的移植。
编写RTC时钟函数实际上就是给文件系统时钟函数DWORD get_fattime(Void)赋值,连续提供给文件系统一个实时时钟。DWORD get_fattime(Void)需要RTC函数支持,返回一个32位无符号整数,时钟信息包含在这32位中,如图3所示。
图3 时钟位
3 DS3231实时时钟芯片
3.1 DS3231器件
DS3231是Maxim公司生产的一款低成本、超高精度的I2C总线实时时钟芯片[5],该器件不仅能够在一定温度范围内提供优于2 min/年的计时精度,而且省去了制造过程中晶振安装和布线校准的工作。
DS3231实时时钟(RTC),具有集成的温补晶体振荡器(TCX0)和1个32.768 kHz 的晶振,该晶振包含电池输入端,断开主电源仍然可以保持精确计时。集成晶体振荡器可提供器件的长期精确度,并减少生产的元件数。DS3231提供商级和工业级温度范围,采用16引脚、300 mil的SO封装[7]。RTC保持秒、分、时、星期、日期、月和年信息。当遇到少于31天的月份,将自动调整月末日期,包括闰年补偿。时钟可以工作于24小时模式或带AM/PM指示的12小时。提供2个可编程日历闹钟和1路可编程方波输出。地址与数据通过I2C双向串行传输。通过精密的、经过温度补偿的电压基准和比较器来监视VCC状态,检测电源故障,提供复位输出,并在必要时自动切换到备用电源。另外,RST监视引脚可作为手动按钮输入,以产生外部复位信号。
3.2 DS3231与单片机C8051F500的硬件连接
图4为高精度实时时钟芯片DS3231与主控制器C8051F500单片机的接口连接电路。
图4 C8051F500单片机与DS3231时钟芯片接口连接电路
DS3231的主要引脚功能说明:VCC用于主电源的DC引脚;INT/SQW为低电平有效中断或方波输出;RST是低电平有效复位引脚;GND为地;VBAT为备用电源输入;SDA为串行数据输入、输出;SCL为串行时钟输入。
C8051F500通过I2C总线与DS3231连接,DS3231的VCC接系统电源VCC,VBAT为备用电源输入,该引脚应该连接一个低泄漏电容去耦。INT/SQW为低电平有效中断或方波输出,该漏极开路输出要求外接上拉电阻,如果不使用,可保持开路。微控制器主要通过I2C总线向时钟芯片DS3231写时间信息,DS3231以写入的时间信息为基准精确走时。上电后,微控制器从时钟芯片读取时间信息并存入内存供系统使用,器件每隔64 s测量一次温度,通过调节晶振的负载电容,使其在指定温度达到2 ppm的精度[8],最终达到提高时钟精度的目的。即使系统断电一段时间后重新上电,时钟芯片内的实时数据仍能被正确读出。
3.3 与嵌入式文件系统有关的特性
3.3.1 DS3231电源供电方式
DS3231有两个电源引脚VCC和VBAT[9],分别连接电源VCC和备用电池,它们之间的切换由温度补偿电压基准(VPF)和监视VCC电平的比较器电路控制。当VCC高于VPF时,DS3231由VCC供电,当VCC低于VPF但高于VBAT时,DS3231由VCC供电;当VCC低于VPF和VBAT时,DS3231由VBAT供电;如果用一节容量为38 mAh的电子表用纽扣锂电池作备用电池,在系统掉电时电流损耗最大为3.5 μA,则至少供电时间为:
t=38×10-3/3.5×10-6=10 857 h
按照这个理论,可以粗略估计备用电池供电时间,能够满足实际需要。
3.3.2 DS3231采用I2C总线通信方式
单片机C8051F500通过读取时钟芯片DS3231的值来给文件系统提供日期时间,也可以写入DS3231一个任意的时间初始值,让其依据设定值开始计时,这就要求研究这两者之间的通信模式。DS3231工作于读和写两种模式。
(1) DS3231写模式
通过SDA线和SCL线来接收串行数据和时钟[10],收到每个字节后,发送应答位,START和STOP条件作为串行数据传输的开始和结束。
软件设计流程如图5所示。首先调用START_IIC()函数使单片机产生开始条件,再通过SendByte()函数,发送DS3231写地址,然后发出应答信号,接下来单片机向DS3231发送一个字地址(秒、分、时、日、月、年地址),产生应答信号后,再发送一个字节数据(秒、分、时、日、月、年数据)至DS3231设定初始化时间。产生应答信号后,调用STOP_IIC函数来使单片机产生终止数据写入条件。
图5 DS3231写模式
(2) DS3231读模式
接收和处理字节的方式与写模式相同,但是在这种模式下,方向位指示的传输方向是相反的。DS3231向SDA发送串行数据,并由SCL输入串行时钟。
软件设计流程如图6所示。单片机产生START条件后,通过SendByte()函数发送DS3231写地址,产生应答信号后,发送一个字地址(秒、分、时、日、月、年地址);产生应答信号后再通过SendByte()函数发送DS3231读地址;产生应答信号后,通过函数RcvByte()从DS3231读取一个字节数据(秒、分、时、日、月、年数据)来获取时间;产生应答信号后,最后调用STOP_IIC函数来使单片机产生终止数据读取条件。
图6 DS3231读模式
4 系统测试及结果
在系统测试中,C8051F500选用了22.118 400 MHz的外部晶振,存储介质选用了金士顿8 GB SDHC卡,分别在主电源供电5 V和LITHIUM CELL GR1220纽扣电池供电3 V的情况下,对1980年之后的年、月、日、时、分、秒等时间信息进行设定任意初始值,并在PC机上查看了存储在SD卡中的数据文件的创建、修改、访问等具体时间信息。
测试结果表明,不论在主电源供电还是备用纽扣电池供电情况下,存储在SDHC卡上的文件能够精确显示年、月、日、时、分、秒等时间信息。
结语
本文提出的通过DS3231高精度时钟芯片给嵌入式文件系统提供实时时间的方案具有可行性,解决了存储在SD卡上的采集数据文件没有实时时间的问题,并且在系统掉电情况下,通过一个纽扣锂电池仍然能够长时间连续不断地提供精确的年、月、日、时、分、秒等时间信息,满足了舰舵参数采集设计中对存储在SD卡上的数据文件的创建、修改、访问等时间信息的实际要求。