该数码相框的硬件平台以32 bit STM32系列的处理器STM32F103ZET6为核心,外围电路主要包括一个2.8英寸的TFT液晶模块、1个SD卡插座、5个LED灯和2个按键。硬件系统如图1所示。
![](http://www.21ic.com/d/file/201105/0aec9a66c5add80b31125bbe2be3a6c4.gif)
![](http://www.21ic.com/d/file/201105/2268d4d4fa0143ae489b3c463cc1918e.gif)
2 软件设计
2.1 移植FATFS文件系统
FATFS文件系统是一种完全免费开源的FAT文件系统模块,专为小型嵌入式系统而设计,用标准C语言编写,很方便移植[2]。本设计移植的FATFS版本为R0.07e,它支持FAT12、FAT16和FAT32,由于不涉及多个存储介质,因此,本设计仅移植了其简化版本Tiny-FATFS,其占用内存更少,只需要大约1 KB RAM。FATFS具有三层结构,如图3所示。
![](http://www.21ic.com/d/file/201105/61dab6230bc7bac273c640f16eafe111.gif)
Tiny-FATFS包含5个文件,分别是tff.c、tff.h、diskio.c、diskio.h和integer.h,移植之前首先要编写初始化和读写SD卡的SPI接口代码。代码主要包括SD_Init()、SD_ReadSingleBlock()、SD_ReadMultiBlock ()、SD_WriteSingle
Block()、SD_WriteMultiBlock()函数,而这些代码将在diskio.c中被调用。移植FATFS文件过程:
(1)准备好SPI读写SD卡的代码后就可以修改diskio.c了,实际上只需要编写6个接口函数:
①存储媒介初始化函数:DSTATUS disk_initialize(BYTE drv)。由于存储媒介是SD卡,所以实际上是对SD卡的初始化。drv是存储媒介号码,由于Tiny-FATFS只支持一个存储媒介,所以drv应恒为0。执行无误返回0,错误返回非0。
②状态检测函数:DSTATUS disk_status(BYTE drV)。检测是否支持当前的存储媒介,对Tiny-FATFS来说,只要drv为0,就认为支持,然后返回0。
③读扇区函数:DRESULT disk_read(BYTE drv,BYTE*buff,DWORD sector,BYTE.count)。在SD卡读接口函数的基础上编写,*buff存储已经读取的数据,sector是开始读的起始扇区,count是需要读的扇区数。1个扇区为512 B。执行无误返回0,错误返回非0。
④写扇区函数:DRESULT disk_write(BYTE drv,const BYTE*buff,DWORD sector,BYTE count)。在SD卡写接口函数的基础上编写,*buff存储要写入的数据,sector是开始写的起始扇区,count是需要写的扇区数。1个扇区为512 B。执行无误返回0,错误返回非0。
⑤存储媒介控制函数:DRESULT disk_ioctl(BYTE drv,BYTE ctrl,VoiI*buff)。ctrl是控制代码,*buff存储或接收控制数据。可以在此函数里编写自己需要的功能代码,如获得存储媒介的大小、检测存储媒介的上电与否,存储媒介的扇区数等。如果是简单的应用,也可以不用编写,返回0即可。
⑥DWORD get_fattime(Void)。本设计未涉及到文件的创建和修改,因此实时时钟部分未编写,直接返回一个32 bit无符号整数即可。
(2)对Tiny-FATFS进行配置,主要是修改tff.h和diskio.h。在diskio.h中,只需要配置一项:使能或者使能只读属性。由于本设计只涉及到SD卡的读操作,因此定义使能只读属性:#define_READONLY1。这样可以裁减掉关于写SD卡的那部分代码,从而使文件系统更精简。
在tff.h中,需要对整个文件系统做全面的配置,包括:
①#define_MCU_ENDIAN 1。STM32是小端模式,选择1。
②#define_FS_READONLY 1。使能只读操作,去掉写操作,节省空间。
③#define_FS_MINIMIZE 3。设为3表示使用最基本的FATFS函数,最大限度节省空间。
④#define_USE_STRFUNC 0。禁用字符串函数功能。
⑤#define_USE_FORWARD 0。禁用forward功能。
⑥#define_FAT321。支持FAT32文件系统。
⑦#define_USE_FSINFO 1。支持FAT32磁盘信息获取。
⑧#define_USE_SJIS 0。禁用shift-JIS码。
⑨#define_USE_NTFLAG 1。对文件名大小写敏感。
到此为止,FATFS的移植就全部完成了。
编写一段程序测试FATFS是否移植成功。以1 s的间隔循环读取SD卡中的bmp格式图片并显示,main函数的流程如图4所示。
![](http://www.21ic.com/d/file/201105/e343600cb84d30ef5b52d9739b4d873b.gif)
通常bmp图片都是24位颜色深度的(即RGB=8:8:8),而本设计使用的TFT液晶是16位颜色深度的(即RGB=5:6:5),因此在程序中需要作转换处理才能正常显示。转换程序代码如下:
u16 RGB888toRGB565(u8 r,u8 g,u8 b)
{
return(u16) (r & 0xF8) <<8|(g & 0xFC)<<3|(b & 0xF8)>>3;
}
由于bmp图片是最简单的图片格式,不涉及解码处理,因此大大简化了程序设计。
2.2 在μCOS-II平台上加载FATFS文件系统
FATFS的加载比其他一些嵌入式文件系统要简单[4],只需要在工程中加入tff.c和diskio.c这两个文件即可。需要注意的是,在tff.h中有以下4个函数:
int fputc(int, FIL*);
int fputs(const char*, FIL*);
int fprintf(FIL*, const char*, ...);
char* fgets(char*, int, FIL*);
这4个函数与stdio.h中定义的函数有冲突,需要将其删除。
此外,tff.h中还定义了一个EOF,也与stdio.h中的定义有冲突,只需把它重命名即可(如EOFF)。
2.3 在μCOS-II平台上编写任务函数
定义三个任务以实现数码相框功能:
static void TaskStart(void *pdata);
static void Task1(void *pdata);
static void Task2(void *pdata);
其中,TaskStart的优先级最高,在main函数中,初始化?滋COS-II后即被创建:
/* Initialize "μC/OS-II, The Real-Time Kernel"*/
OSInit();
/* Create the start task */
OSTaskCreate(TaskStart,(void*)0,
&TaskStartStk[TASK_START_STK_SIZE-1],0);
负责初始化目标板、SD卡和LCD,并创建任务Task1,同时处理按键USER_BUTTON_1。当按下USER_BUTTON_1时,删除任务Task2,其流程如图5所示。
![](http://www.21ic.com/d/file/201105/ed918a33730a0d26ecbcbbbe2a7a4729.gif)
static void Task1(void *pdata)
{
/* 设置变量; */
While(1)
{
if(!USER_BUTTON_2)
OSTaskCreate(Task2,(void *)0,
&TaskStk2[TASK2_STK_SIZE-1],4);
Read_pic_display();
OSTimeDly(OS_TICKS_PER_SEC/2);
}
}
Task2任务则只负责执行流水灯程序,即循环依次点亮5个LED,其优先级最低。
3 测试结果
本设计的实验平台是STM32红牛开发板,实物效果图如图6所示。
![](http://www.21ic.com/d/file/201105/6ade407b28c4b6971fc17d42e971b4d0.gif)
本设计基本实现了数码相框的功能,其设计的硬件极其简单,相比于一些基于高端32 bit MCU(如ARM)的方案[5],成本要低得多。相比于一些简单的读图显示程序,本设计基于嵌入式实时操作系统μCOS-II,在稳定性和可扩展性上都具有优势。另外,STM32性能优越,可以很流畅地运行μCOS-II和FATFS系统,也能够驱动QVGA甚至更高分辨率的TFT液晶屏,这是同价位8 bit或16 bit单片机所不能比拟的[6]。本设计还有需要改进的地方,如增加JPEG解码、增强文件名支持、改进幻灯切换方式以及添加其他功能等。
参考文献
[1] 王永虹,徐炜,郝立平.STM32系列ARM Cortex-M3微控制器原理与实践[M].北京:北京航空航天大学出版社,2008.
[2] 洪岳炜,王百鸣,谢超英.一种易于移植和使用的文件系统FATFS Module[J].单片机与嵌入式系统应用,2008(1):29-31.
[3] 任哲.嵌入式实时操作系统μC/OS-II原理与应用[M].北京:北京航空航天大学出版社,2005.
[4] 王命延,余爱军.一种加载在μCOS-II内核上的嵌入式文件系统[J].南昌大学学报,2005,29(2):197-199.
[5] 王伟能,吴烁宇,陈弟虎,等.基于S3C2410和Qt/Embedded的数码相框设计[J].微计算机信息,2009,25(6-2):81-83.
[6] 郑友胜.μCOS-II在C51中的应用设计[J].中小企业科技,2007(1):126-127.