摘 要:为应对数码相框成本较高的问题,介绍了一种简易数码相框的设计,实现从SD卡读取bmp图片文件并在TFT液晶屏上显示的功能。本设计成本低,具有很高的实用价值。
关键词:数码相框;SD卡;STM32;μCOS-II;FATFS
本文介绍一种简单、低成本的数码相框的设计,它可以幻灯片式地浏览SD卡中的bmp格式的照片。
1 硬件电路
该数码相框的硬件平台以32 bit STM32系列的处理器STM32F103ZET6为核心,外围电路主要包括一个2.8英寸的TFT液晶模块、1个SD卡插座、5个LED灯和2个按键。硬件系统如图1所示。
系统关键器件的电路原理图如图2所示。STM32系列MCU基于专为要求高性能、低成本、低功耗的嵌入式应用而设计的ARM Cortex-M3内核,包括了STM32F103增强型系列和STM32F101基本型系列。本设计使用的是增强型系列的高端型号STM32F103ZET6,其最高主频可以达到72 MHz,内置512 KB的闪存以及64 KB的SRAM。同时其外设资源丰富,包括并行LCD接口(FSMC)、12通道DMA控制器、定时器、ADC、DAC、SDIO、I2C、SPI、USB、UART等[1]。可以说,它完全超越了同价位的8 bit或者16 bit单片机的性能,而又不像一般32 bit处理器那样价格昂贵。
本设计使用了一个带有通用并行接口(FSMC)的2.8英寸TFT液晶模块,这种液晶模块很常见,而且价格便宜,另外还有3.2英寸甚至更大的尺寸可供选择。STM32F103ZET6通过一个SPI接口与SD卡座连接,以便于控制和简化程序,而且对于静态图片,SPI的传输速度已足够。另外,还有用于调试的2个按键和5个LED。
2 软件设计
2.1 移植FATFS文件系统
FATFS文件系统是一种完全免费开源的FAT文件系统模块,专为小型嵌入式系统而设计,用标准C语言编写,很方便移植[2]。本设计移植的FATFS版本为R0.07e,它支持FAT12、FAT16和FAT32,由于不涉及多个存储介质,因此,本设计仅移植了其简化版本Tiny-FATFS,其占用内存更少,只需要大约1 KB RAM。FATFS具有三层结构,如图3所示。
应用层为用户提供了一系列接口函数,只需要简单的调用即可,而无需理会复杂的FAT协议。移植过程中,需要使用者修改的是底层接口(包括存储介质读写接口和供给文件创建修改时间的实时时钟)。
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所示。
需要说明的是,为了便于循环读图,SD卡中存储的bmp格式图片被刻意用数字编号来命名(如:1.bmp~n.bmp),这样,在程序中只需要简单处理文件名就可以按顺序读取图片了。
通常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所示。
Task1的任务是循环读取SD卡的bmp格式图片并送LCD显示,同时还要处理按键USER_BUTTON_2。当按下USER_BUTTON_2时,创建任务Task2,其示意性代码如下:
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所示。
实验结果表明,μCOS-II+FATFS方案实现的数码相框工作稳定,开机后μCOS-II加载成功即开始循环读取SD卡中的bmp图片并在TFT屏上显示。图片间的切换是简单的拉幕式切换,间隔为5 s(可调),经长时间观察,无读取失败、掉帧、花屏等问题,每张图片都是完美展示。根据测试程序的设计,按下USER_BUTTON_2按键则流水灯任务被创建,5个LED灯开始以走马灯的形式循环点亮;与此同时,图片读取和显示未受到任何影响,证明μCOS-II的任务调度机制稳定可靠。再按下USER_BUTTON_1,则流水灯任务被删除,LED停止动作。
本设计基本实现了数码相框的功能,其设计的硬件极其简单,相比于一些基于高端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.