|
MSP430F5438A单片机基于SPI的FatFs移植
[复制链接]
本帖最后由 fish001 于 2019-3-16 22:05 编辑
不管移植什么程序,最重要的就是,
不要自以为是
一定要先查资料,花一周查资料,查到查不到为止,否则你编了一半的程序再参考别人的,直接后果是你下不了决心推翻重来
1. FatFs移植要点:
相信能看到这个博客的都知道FatFs是什么了,目前应该是0.11版本,我就不多废话了,一个开源的文件系统,不全面的说,作用就是让你编程序操作写SD卡的内容能够被PC机读出来(有不对的话懂的大神请指正)
它的好处就是只要写底层的几个硬件驱动函数就OK了,上层的函数都已经写好了,清楚格式直接调用就可以了。
所谓“硬件驱动”函数,就是告诉单片机,完成一个动作(比如初始化)具体需要哪个IO口怎样变化,哪个IO口该高,哪个IO口该低,通信端口选哪个,发什么东西,这些基本动作组合在一起,就能够完成初始化。
FatFs所需要的驱动函数共有五个,diskio.h 文件里面看就是这样的:
DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
函数返回值:
DSTATUS
是一个枚举类型变量,包含5个元素,依次是成功、读写错误、写保护、未准备好、参数错误:
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
实际在写程序的时候返回值分得细有助于快速定位问题的所在,但是我移植的时候图省事只用了成功、读写错误、参数错误三个,原因是写保护我没有编写专门的函数去判断,而未准备好出现的概率很低。
各个函数的输入参数具体到每个函数再进行一一说明
那么下面首先以初始化程序
DSTATUS disk_initialize (BYTE pdrv);
具体说一下:通过TI的单片机MSP430F5438A进行函数的实现步骤
一个密歇根大学的人写的技术报告,MSP430F149写的程序,但是只实现了单次读写,并且使用了DMA(内存直读)这种高端的功能(我会上载到资料,待补全)
SD卡的官方协议说明书,这个基本上太重要了,名字是part1_410,看来只是整个的一部分,不过很详细,说得很明白,只要你耐心细心,很多东西都可以直接找到,如果你关心的是SPI模式的话第7章是重点!
2. disk_initialize函数实现
这个函数在diskio.c当中的函数体是这样的:
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
int result;
switch (pdrv) {
case ATA :
result = ATA_disk_initialize();
// translate the reslut code here
return stat;
case MMC :
result = MMC_disk_initialize();
// translate the reslut code here
return stat;
case USB :
result = USB_disk_initialize();
// translate the reslut code here
return stat;
}
return STA_NOINIT;
}
可以看到FatFs很“贴心”的提供了ATA、MMC、USB三款接口存储器的初始化程序,可是你要是真的认为它贴心你就错了……
首先来说输入参数pdrv,这个具体可以理解为你要操作的存储器编号,我们操作单片机的通常也就一个存储器(我项目里面是SD卡),所以在ffconf.h的定义中:
#define _VOLUMES 1
这样一来,所有的输入参数pdrv就都是0了,而ATA MMC USB的定义是这样的:
/* Definitions of physical drive number for each drive */
#define ATA 0 /* Example: Map ATA harddisk to physical drive 0 */
#define MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
#define USB 2 /* Example: Map USB MSD to physical drive 2 */
MMC_disk_initialize();
哪知道单个存储器条件下人家根本执行不到这儿啊!
所以,如果你们只有一个盘,一定要实现的是ATA那个,管他名字是什么,这里我最后实现的时候折衷了一下,把
MMC_disk_initialize();
拷贝到ATA下面了,也算是偷了个懒。那么
MMC_disk_initialize();
|
|