文章目录
- 一、SD基础知识
- 二、SD卡控制器
- 三、文件系统(FATFS)
- 四、 SD卡控制任务:
- 4.1 txt文本任务:
- 4.1.1 硬件部分:
- 4.1.2 软件部分:
- 1.板级支持包中加入FATFS文件系统
- 2.C设计
一、SD基础知识
1.SD卡的类型、协议规范、容量等级及支持的文件系统
Micro SD卡,是一种极细小的快闪存储器卡,MicroSD 卡插入适配器(Adapter)可以转换成 SD 卡,其操作时序和 SD卡是一样的。
开发板原理图如下,可知本开发板使用的是SDIO模式的SD卡。
标准 SD 卡 2.0 版本中,工作时钟频率可以达到 50Mhz。
在 SDIO 模式下采用 4 位数据位宽,理论上可以达到 200Mbps(50Mx4bit)的传输速率;
在 SPI 模式下采用 1 位数据位宽,理论上可以达到 50Mbps 的传输速率。
因此 SD 卡在 SDIO 模式下的传输速率更快,同时其操作时序也更复杂。
二、SD卡控制器
ZYNQ 中的 SD 卡控制器符合 SD2.0 协议规范,接口兼容 eMMC、MMC3.31、SDIO2.0、SD2.0、SPI,
支持 SDHC、SDHS 器件。SD 卡控制器支持 SDMA(单操作 DMA)、ADMA1(4K 边界限制 DMA)和
ADMA2(在 32 位系统中允许任何位置和任意大小)。ARM 处理器通过 AHB 总线访问 SD 卡控制器,SD
控制器采用读和写通道各自双缓冲 FIFO 的机制提高吞吐带宽。其内部框图如下图所示:
值得一提的是,ZYNQ 内部集成了两个 SD 卡控制器,并且 Xilinx SDK 的 standalone 已经移植好了 FATFS(SDK 软件中叫做 xilffs)文件系统,因此在 SDK 中添加 xilffs 库后,就可以在程序中使用 FATFS 中的 API 函数来操作 SD 卡。
SD 控制器读写通道采用独立的 512 字节深度的双缓冲 FIFO 执行读和写操作。
在写操作时,处理器向其中一个 FIFO 写数据,将另一个 FIFO 的数据写到 SD 总线;
在读操作时,SD 总线上的数据向其中一个FIFO 写数据,处理器将数据从另一个 FIFO 读出数据。
SD 卡控制器通过双缓冲机制以保证最大带宽。
三、文件系统(FATFS)
FATFS 是一个完全开源免费的 FAT 文件系统模块,专门为小型的嵌入式系统而设计。它完全用标准 C语言编写,所以具有良好的硬件平台独立性,可以很方便的移植到各种嵌入式处理器中。Xilinx SDK 的standalone 已经移植好了 FATFS 文件系统,因此在 SDK 中添加 xilffs 后,就可以在程序中使用 FATFS 中的 API 函数来操作 SD 卡。
FATFS 的特点如下:
1、 结构清晰,代码量少,文件系统和 IO 底层分开,特别适合新手入门学习;
2、 支持最多 10个逻辑盘符和两级文件夹;
3、 支持 FAT12/FAT16 和 FAT32 文件系统;
4、 支持长文件名称。
四、 SD卡控制任务:
FATFS文件系统设计参考
4.1 txt文本任务:
通过Xilinx SDK自带的FATFS库,完成对TF卡中TXT文本读写的功能,并将读写测试结果通过串口打印出来。
4.1.1 硬件部分:
UART、SD接口、DDR3存储器
4.1.2 软件部分:
1.板级支持包中加入FATFS文件系统
出现下列bsp则说明添加成功,里面包含各种需要的函数:
2.C设计
流程:
代码:
#include "xparameters.h"
#include "xil_printf.h"
#include "ff.h" //FATFS
#include "xdevcfg.h" //参数#define FILE_NAME "ZDYZ.txt" //定义文件名const char src_str[30] = "www.openedv.com"; //定义文本内容
static FATFS fatfs; //文件系统//初始化文件系统
int platform_init_fs()
{FRESULT status;TCHAR *Path = "0:/";BYTE work[FF_MAX_SS];//注册一个工作区(挂载分区文件系统)//在使用任何其它文件函数之前,必须使用f_mount函数为每个使用卷注册一个工作区status = f_mount(&fatfs, Path, 1); //挂载SD卡if (status != FR_OK) {xil_printf("Volume is not FAT formated; formating FAT\r\n");//格式化SD卡status = f_mkfs(Path, FM_FAT32, 0, work, sizeof work);if (status != FR_OK) {xil_printf("Unable to format FATfs\r\n");return -1;}//格式化之后,重新挂载SD卡status = f_mount(&fatfs, Path, 1);if (status != FR_OK) {xil_printf("Unable to mount FATfs\r\n");return -1;}}return 0;
}//挂载SD(TF)卡
int sd_mount()
{FRESULT status;//初始化文件系统(挂载SD卡,如果挂载不成功,则格式化SD卡)status = platform_init_fs();if(status){xil_printf("ERROR: f_mount returned %d!\n",status);return XST_FAILURE;}return XST_SUCCESS;
}//SD卡写数据
int sd_write_data(char *file_name,u32 src_addr,u32 byte_len)
{FIL fil; //文件对象UINT bw; //f_write函数返回已写入的字节数//打开一个文件,如果不存在,则创建一个文件f_open(&fil,file_name,FA_CREATE_ALWAYS | FA_WRITE);//移动打开的文件对象的文件读/写指针 0:指向文件开头f_lseek(&fil, 0);//向文件中写入数据f_write(&fil,(void*) src_addr,byte_len,&bw);//关闭文件f_close(&fil);return 0;
}//SD卡读数据
int sd_read_data(char *file_name,u32 src_addr,u32 byte_len)
{FIL fil; //文件对象UINT br; //f_read函数返回已读出的字节数//打开一个只读的文件f_open(&fil,file_name,FA_READ);//移动打开的文件对象的文件读/写指针 0:指向文件开头f_lseek(&fil,0);//从SD卡中读出数据f_read(&fil,(void*)src_addr,byte_len,&br);//关闭文件f_close(&fil);return 0;
}//main函数
int main()
{int status,len;char dest_str[30] = "";status = sd_mount(); //挂载SD卡if(status != XST_SUCCESS){xil_printf("Failed to open SD card!\n");return 0;}elsexil_printf("Success to open SD card!\n");len = strlen(src_str); //计算字符串长度//SD卡写数据sd_write_data(FILE_NAME,(u32)src_str,len);//SD卡读数据sd_read_data(FILE_NAME,(u32)dest_str,len);//比较写入的字符串和读出的字符串是否相等if (strcmp(src_str, dest_str) == 0)xil_printf("src_str is equal to dest_str,SD card test success!\n");elsexil_printf("src_str is not equal to dest_str,SD card test failed!\n");return 0;}
结果:运行程序后,SD卡中存在名为ZDYZ的txt文件,且文件中的字符串就是我们自定义的内容。