10 - SD卡读写TXT文本实验

1 实验任务

本实验任务是通过Xilinx SDK自带的FATFS库,完成对TF卡中TXT文本读写的功能,并将读写测试结果通过串口打印出来。

2 系统框图

在这里插入图片描述

3 SD/SDIO简介

3.1 SD存储卡和SDIO设备

  1. SD存储卡
    • 定义:一种基于SD总线接口的存储设备,用于数据的读写和存储
    • 功能:主要用于存储照片、视频、文档等数据
  2. SDIO设备
    • 定义:一种基于SDIO接口的扩展设备,用于扩展主机设备的功能
    • 功能:提供额外的硬件功能,如Wi-Fi、蓝牙、GPS、摄像头等

3.2 SD总线接口

SD卡使用的接口称为SD总线接口(SD Bus Interface),这是一种专门为SD卡设计的总线接口,用于在主机设备(如相机、手机、电脑)和SD卡之间传输数据、命令和状态信息。

3.2.1 核心特性

  1. 物理接口:
    • SD卡使用9个引脚(标准尺寸)或8个引脚(microSD)进行通信
    • 引脚包括数据线(DAT0~DAT3)、命令线(CMD)、时钟线(CLK)、电源线(VDD、VSS)等
  2. 通信协议:
    • SD总线接口基于SD协议,定义了主机与SD卡之间的命令、响应和数据传输方式
    • 支持多种传输模式,包括1位模式和4位模式
  3. 数据传输方式:
    • 1位模式:仅使用DAT0引脚传输数据
    • 4位模式:使用DAT0~DAT3引脚同时传输数据,提高传输速度
  4. 时钟同步:
    • 数据传输由主机提供的时钟信号(CLK)同步
    • 时钟频率决定了数据传输的速度

3.2.2 工作模式

SD总线接口支持多种工作模式,以适应不同的性能需求:

  1. 默认速度模式(Default Speed Mode)
    • 时钟频率:0~25 MHz
    • 传输速度:最高12.5 MB/s(4位模式)
    • 特点:兼容早期的SD卡,适用于标清视频录制和一般数据存储
  2. 高速模式(High Speed Mode)
    • 时钟频率:0~50 MHz
    • 传输速度:最高25 MB/s(4位模式)
    • 特点:适用于高清视频录制和高速数据存储
  3. UHS模式(Ultra High Speed Mode)
    • UHS-I:
      • 时钟频率:0~208 MHz
      • 传输速度:最高104 MB/s(SDR104模式)
    • UHS-II:
      • 引入LVDS差分信号,支持全双工通信
      • 传输速度:最高312 MB/s(半双工模式)
    • UHS-III:
      • 进一步提升时钟频率
      • 传输速度:最高624 MB/s(全双工模式)

3.2.3 通信流程

  1. 初始化:
    • 主机通过CMD命令与SD卡建立通信,获取卡的基本信息(如容量、支持的模式等);
  2. 数据传输:
    • 主机发送读写命令(如CMD17/CMD18/CMD24/CMD25),通过数据线(DAT0~DAT3)传输数据;
  3. 状态检测:
    • 主机通过CMD命令查询SD卡的状态(如是否忙、是否有错误等)。

3.3 SDIO接口

SDIO接口是基于SD总线接口扩展而来的;SDIO接口既能访问SD存储卡,又能访问SDIO设备。

  1. SDIO接口兼容SD总线接口的方面
    • 物理接口:使用相同的引脚(DAT0~DAT3、CMD、CLK、VDD、VSS)
    • 基本协议:支持SD存储协议的命令和响应机制
    • 数据传输:支持1位和4位并行数据传输模式
    • 时钟同步:使用CLK引脚同步数据传输
  2. SDIO接口扩展SD总线接口的方面
    • 协议扩展:
      • 新增**CMD52(IO_RW_DIRECT)和CMD53(IO_RW_EXTENDED)**命令,支持设备寄存器访问和块数据传输
    • 中断机制:
      • 使用DAT1引脚作为中断信号线,支持SDIO设备主动通知主机
    • 设备初始化:
      • 支持通过CMD5命令查询设备能力,并通过CMD52/CMD53命令配置设备
        多功能支持:
      • 支持多种设备类型(如Wi-Fi、蓝牙、GPS),每种设备有特定的寄存器映射和功能定义

关于SDIO接口支持的设备类型,如下图所示:
在这里插入图片描述

4 硬件设计

4.1 Block Design

  1. 添加ZYNQ7 Processing System IP核
    • (1)在Peripheral I/O页面
      • 1)勾选SD
      • 2)勾选UART
      • 3)正确选择Bank 0和Bank 1的电压
    • (2)在DDR Configuration页面
      • 1)DDR Controller Configuration下,合理配置Memory Type、Memory Part和Bus Width等参数

在这里插入图片描述

4.2 注意事项

无。

5 软件设计

5.1 注意事项

  1. 在main.c程序中,并未对sd卡外设进行显示初始化,但是
    • (1)f_mkfs函数➡disk_initialize函数➡XSdPs_CfgInitialize函数
    • (2)f_mount函数➡find_volume函数➡disk_initialize函数➡XSdPs_CfgInitialize函数

5.2 函数详解

  1. 基本概念
    在这里插入图片描述
  2. f_mkfs函数
    • (1)函数原型
      在这里插入图片描述
    • (2)参数详解​​
      • 1)​​path​​:指定要格式化的卷的路径
        • 格式​​:逻辑驱动器号 + 根目录,如 “0:/”、“1:/”
        • 驱动器号范围​​:由 ffconf.h 头文件中的参数 FF_VOLUMES(卷或逻辑驱动器的数量) 定义;例如,FF_VOLUMES = 2,可用的逻辑驱动器号范围是0 ~ 1
        • 若路径为空字符串(“”),则使用默认驱动器
      • 2)​​opt​​ :格式化选项,可通过位掩码组合
        • ​​FM_FAT​​:强制格式化为 FAT12/16
        • ​​FM_FAT32​​:强制格式化为 FAT32
        • ​​FM_EXFAT​​:强制格式化为 exFAT(需启用 _FS_EXFAT)
        • ​​FM_ANY​​:自动选择 FAT 类型(默认行为)
        • ​​FM_SFD​​:创建“超级软盘”(无 MBR,卷从首扇区开始)
      • 3)​​au​​:分配单元(簇)大小(字节)
        • 若设为 0,FatFs 自动选择最优值
        • 必须为扇区大小的整数倍(如 512、1024、4096)
      • 4)​​work​​​​:工作缓冲区指针
        • 指向临时缓冲区的指针,用于在格式化过程中存储临时数据(如 FAT 表、目录结构等)
      • 5)size:工作缓冲区大小
        • 缓冲区大小至少为 1 个扇区(建议 FF_MAX_SS,即最大扇区大小)。
  3. f_mount函数
    • (1)函数原型
      在这里插入图片描述
    • (2)参数详解
      • 1)fs​​:指向一个用户定义的 FATFS 结构体实例,用于存储文件系统信息
        • ​挂载时​​:传入已分配内存的 FATFS 对象指针
        • ​卸载时​​:传入 NULL
        • 生命周期​​:需在挂载期间保持有效,卸载后可释放( free(fs) )
      • 2)path​​:指定要挂载的卷的路径
        • 格式​​:逻辑驱动器号 + 根目录,如 “0:/”、“1:/”
        • 驱动器号范围​​:由 ffconf.h 头文件中的参数 FF_VOLUMES(卷或逻辑驱动器的数量) 定义;例如,FF_VOLUMES = 2,可用的逻辑驱动器号范围是0 ~ 1
        • 若路径为空字符串(“”),则使用默认驱动器
      • 3)opt​​:选项​​
        • ​​0​​:延迟挂载​​,注册逻辑驱动器但不立即挂载,首次访问卷时自动挂载
        • 1​​:​​立即挂载​​,强制挂载并检查文件系统有效性,若卷未准备好则返回错误
    • (3)使用示例
      • 1)挂载
        在这里插入图片描述
      • 2)卸载
        在这里插入图片描述
  4. f_open函数
    • (1)mode参数
      在这里插入图片描述

5.3 工程源码

/***************************** Include Files *********************************/

#include "stdio.h"
#include "string.h"
#include "xparameters.h"
#include "xstatus.h"
#include "ff.h"

/************************** Constant Definitions *****************************/

#define FILE_NAME 	"test.txt"

/**************************** Type Definitions *******************************/

/***************** Macros (Inline Functions) Definitions *********************/

/************************** Function Prototypes ******************************/

FRESULT SdCardInit(FATFS* FatFsObjPtr);

/************************** Variable Definitions *****************************/

char SrcStrBuffer[30] = "Hello Ryan, Good Luck.";
char DestStrBuffer[30] ={0};

FATFS FileSysObj;
FIL   FileObj;

/*****************************************************************************/

int main()
{
	//
	FRESULT Status;
	UINT BytesWrite;
	UINT BytesRead;

	//
	printf("SD Card Test.\n");

	// 挂载SD卡
	Status = SdCardInit(&FileSysObj);
	if (Status != FR_OK) {
		printf("Error : failed to mount fatfs.\n");
		return XST_FAILURE;
	}

	/*
	 * 写文件
	 */
	Status = f_open(&FileObj, FILE_NAME, FA_CREATE_ALWAYS | FA_WRITE);
	if (Status != FR_OK) {
		printf("Error : failed to open file.\n");
		return XST_FAILURE;
	}


	f_write(&FileObj, SrcStrBuffer, (UINT)strlen(SrcStrBuffer), &BytesWrite);
	if (Status != FR_OK) {
		printf("Error : failed to write file.\n");
		return XST_FAILURE;
	}
	else {
		puts(SrcStrBuffer);
		printf("%u bytes were written into file.\n", BytesWrite);
	}

	f_close(&FileObj);

	/*
	 * 读文件
	 */
	Status = f_open(&FileObj, FILE_NAME, FA_READ);
	if (Status != FR_OK) {
		printf("Error : failed to open file.\n");
		return XST_FAILURE;
	}

	f_read(&FileObj, DestStrBuffer, (UINT)30, &BytesRead);
	if (Status != FR_OK) {
		printf("Error : failed to read file.\n");
		return XST_FAILURE;
	}
	else {
		puts(DestStrBuffer);
		printf("%u bytes were read from file.\n", BytesRead);
	}
	f_close(&FileObj);

	// 比较字符串
	if (strcmp(SrcStrBuffer, DestStrBuffer) == 0) {
		printf("SD Card Test Completed.\n");
	}
	else {
		printf("SD Card Test Failed.\n");
	}

	//
	return XST_SUCCESS;
}

/*****************************************************************************/

FRESULT SdCardInit(FATFS* FatFsObjPtr)
{
	//
	FRESULT Status;
	TCHAR *Path = "0:/";
	BYTE work[FF_MAX_SS];

	// 挂载SD卡(到一个具体的文件系统对象上)
	Status = f_mount(FatFsObjPtr, Path, 1);
	if (Status != FR_OK) {
		printf("Error : logical drive needs to be formatted.\n");

		//格式化SD卡
		Status = f_mkfs(Path, FM_FAT32, 0, work, sizeof(work));
		if (Status != FR_OK) {
			printf("Error : failed to format logical drive.\n");
			return Status;
		}

		//格式化之后,重新挂载SD卡
		Status = f_mount(FatFsObjPtr, Path, 1);
		if (Status != FR_OK) {
			printf("Error : failed to mount logical drive.\n");
			return Status;
		}
	}

	//
	return Status;
}

/*****************************************************************************/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值