本帖最后由 ren0zhe 于 2013-11-4 10:33 编辑
第十五节 SD卡上FatFs文件系统的学习
本节主要讲述了FatFs文件系统的移植,详细介绍了,文件系统里面函数的使用方法。内容写了58页之多,耗时1周时间。有错误之处尽请指正,谢谢。
PDF版学习笔记
15科星F107开发板学习笔记—SD卡上文件系统FatFs的学习.pdf
(2.25 MB)
源码实例工程
15科星F107开发板学习笔记源码—SD卡上文件系统FatFs的学习.rar
(863.7 KB)
本节笔记,目录
笔记部分内容如下:
程序的编写下面我们开始代码的编写: 1、 主函数的编写 int main(void) { RCC_Configuration(); GPIO_Configuration(); USART_Configuration(); SPI_Configuration();
FATFS_TEST(); //FATFS常用功能测试函数
while (1) { } } 这里新接触的配置函数就是SPI的配置了,也是使用库提供的结构体对SPI进行定义,更多的SPI的介绍,我们这里就不多说了,MCU的芯片手册写的也很清楚了,这里复制过来也没啥意思。下面我们看一下SPI的配置函数,代码如下: void SPI_Configuration(void) { SPI_InitTypeDef SPI_InitStructure;
/* SPI3 Config*/ //一开始SD初始化阶段,SPI时钟频率必须<400Ks SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI设置为双线双向全双工模式 SPI_InitStructure.SPI_Mode =SPI_Mode_Master;//设置SPI工作模式:设置为主机模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL =SPI_CPOL_High;//选择了串行时钟的稳态:时钟悬空高 SPI_InitStructure.SPI_CPHA =SPI_CPHA_2Edge;//数据捕获于第二个时钟沿 SPI_InitStructure.SPI_NSS =SPI_NSS_Soft;//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理 //定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;//SPI_BaudRatePrescaler_4;// ; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC值计算的多项式 SPI_Init(SPI3,&SPI_InitStructure);//使用该结构体的参数对SPI3进行初始化
/* SPI3 enable */ SPI_Cmd(SPI3, ENABLE);//使能SPI3外设 }
2、 SD卡驱动函数的编写 这里使用文件SD_driver.c和SD_driver.h来写出SD读写的一些驱动函数。 函数列表如下: /* Private define------------------------------------------------------------*/ /* SD卡类型定义 */ #define SD_TYPE_MMC 0 #define SD_TYPE_V1 1 #define SD_TYPE_V2 2 #define SD_TYPE_V2HC 4
/* SPI总线速度设置*/ #define SPI_SPEED_LOW 0 #define SPI_SPEED_MID 1 #define SPI_SPEED_HIGH 2 /* SD传输数据结束后是否释放总线宏定义 */ #define NO_RELEASE 0 #define RELEASE 1
/* SD卡指令表 */ #define CMD0 0 //卡复位
/* Private macro-------------------------------------------------------------*/ //SD卡CS片选使能端操作: #define SD_CS_ENABLE() GPIO_ResetBits(GPIOD,GPIO_Pin_2) //选中SD卡 #define SD_CS_DISABLE() GPIO_SetBits(GPIOD,GPIO_Pin_2) //不选中SD卡 #define SD_PWR_ON() GPIO_ResetBits(GPIOD,GPIO_Pin_10) //SD卡上电 #define SD_PWR_OFF() GPIO_SetBits(GPIOD,GPIO_Pin_10) //SD卡断电 #define SD_DET() 1 //!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) //检测有卡 //1-有 0-无
/* Private function prototypes-----------------------------------------------*/ //void SPI_Configuration(void); void SPI_SetSpeed(u8 SpeedSet);
u8 SPI_ReadWriteByte(u8TxData); //SPI总线读写一个字节 u8 SD_WaitReady(void); //等待SD卡就绪 u8 SD_SendCommand(u8 cmd, u32 arg,u8 crc); //SD卡发送一个命令 u8 SD_SendCommand_NoDeassert(u8 cmd,u32 arg, u8 crc); u8 SD_Init(void); //SD卡初始化 // u8 SD_ReceiveData(u8 *data, u16 len,u8 release);//SD卡读数据 u8 SD_GetCID(u8 *cid_data); //读SD卡CID u8 SD_GetCSD(u8 *csd_data); //读SD卡CSD u32 SD_GetCapacity(void); //取SD卡容量
u8 SD_ReadSingleBlock(u32 sector, u8*buffer); //读一个sector u8 SD_WriteSingleBlock(u32sector,const u8 *buffer); //写一个sector u8 SD_ReadMultiBlock(u32 sector, u8*buffer, u8 count); //读多个sector u8 SD_WriteMultiBlock(u32 sector,constu8 *data, u8 count);//写多个sector
3、 文件系统的移植 FatFs文件系统主要有以下函数: /*-函数详细的解释请查阅附录,点击链接也可以到----*/ /* FatFs module applicationinterface */
4、 底层接口I/O函数的编写 底层驱动是必须由用户自己完成的,函数均放在文件diskio.c中,函数如下: /* Prototypes for disk controlfunctions */ DSTATUS disk_initialize (BYTE); DSTATUS disk_status (BYTE); DRESULT disk_read (BYTE, BYTE*,DWORD, BYTE); DRESULT disk_write (BYTE, constBYTE*, DWORD, BYTE); DRESULT disk_ioctl (BYTE, BYTE,void*); DWORD get_fattime (void); 6 个接口函数的详细信息如下图所示。
DiskI/O 函数结构图
因为FatFs 模块完全与磁盘I/O 层分开,因此需要下面的函数来实现底层物理磁盘的读写与获取当前时间。底层磁盘I/O 模块并不是FatFs 的一部分,并且必须由用户提供。下面的函数位于diskio.c 中。
5、 应用层函数的编写 我们这个例程要实现的8个功能如下:
每一个功能都对应一个函数,各个函数如下: // 0 读取磁盘容量 The f_getfreefunction gets number of the free clusters void Test_f_getfree(void); //1 读磁盘目录 The f_readdirfunction reads directory entries. void Test_f_readdir(void); //2 创建目录 The f_mkdir function creates a new directory void Test_f_mkdir(void); //3 读取文件 The f_read function reads data from a file. void Test_f_read(void); //4 文件拷贝 The f_write writes data to a file. void Test_f_write(void); //5 重命名 Rename file or directory void Test_f_rename(void); //6 删除文件 The f_unlink removes file or directory void Test_f_unlink(void); //7 格式化 The f_mkfs fucntion creates a file systemon the drive. void Test_f_mkfs(void);
这8个函数的调用是通过一个二维的函数指针数组完成的,该数组如下: void *FATFS_Function[][2]= { (void*)Test_f_getfree,"磁盘容量", (void*)Test_f_readdir,"读目录 ", (void*)Test_f_mkdir, "创建路径", (void*)Test_f_read, "读文件 ", (void*)Test_f_write, "文件拷贝", (void*)Test_f_rename, "重命名 ", (void*)Test_f_unlink, "删除文件", (void*)Test_f_mkfs, "格式化 ", 0x00,0x00 }; 这8个函数完成的功能都是调用FatFs文件系统里的函数,FatFs文件系统的函数前面已经列出了列表,在本节最后面我们也附上了函数的详细定义及用法,请查阅。下面我们着重分析一下这几个应用函数: 0)//The f_getfreefunction gets number of the free clusters void Test_f_getfree(void) { FATFS fs; FATFS *pfs; DWORD clust; FRESULT res; // FatFs function common resultcode
//检测磁盘是否插好 if(disk_detect_OK()==FALSE ) return;
pfs=&fs;//指向 //Register a work area for logical drive 0 //温馨提示:该函数是文件系统FatFs里的函数,详细说明请查阅本章节最后的附录,可以用Ctrl+F快捷键,弹出搜索框,输入该函数名,找到该函数。以下类似函数均可以这样找到详细说明,不再赘述。该类函数我们会标记红色,并加粗,请留意。比如f_mount, 解释如下:
f_mount(0, &fs);
//1 读取目录 The f_readdir function readsdirectory entries. void Test_f_readdir(void)
//2 读取目录 The f_mkdir function creates a new directory void Test_f_mkdir(void)
//3 读文件 The f_readfunction reads data from a file. void Test_f_read(void)
//4 The f_writewrites data to a file. //测试文件拷贝功能 void Test_f_write(void)
//5 重命名 Rename file or directory void Test_f_rename(void)
|