SD卡读写及FATFS(R0.14版本)文件系统测试总结

本文详细介绍了如何在基于FPGA的Cortex-M0系统中手动移植SD卡驱动,包括SD卡的初始化步骤、读写测试以及FATFS文件系统的应用。针对SD2.0版本的SDHC卡,通过CMD0和CMD8命令进行模式切换和版本检测,然后使用CMD55和ACMD41进行初始化。在读写测试中,成功实现了数据的写入和读取。此外,还提及了FATFS文件系统的使用,简化了文件操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

QAQ真不想看


由于使用的是搭建在FPGA上的Cortex-M0内核,不能像STM32的cubemx直接移植使用,所以得手动移植

学习路径

SD理论->读写方式->测试读写->文件系统理论->测试文件读写

SD卡简介

SD卡 Secure Digital Card安全数字卡
再MMC卡的基础上发展而来

所用的SD卡类型
SDHC SD2.0 2GB至32GB FAT32
在这里插入图片描述
工作模式有SDIO模式和SPI模式两种
本文使用模拟SPI

SD卡命令

操作前必须对SD卡进行初始化

SD卡的命令格式由6个字节组成,发送数据时高
位在前
操作命令
在这里插入图片描述

Byte1前两位固定
Byte2~Byte5:命令参数,有些命令参数是保留位,没有定义参数的内容,保留位应设置为0
Byte6:前7位为CRC(循环冗余校验)校验位,最后一位为停止位0。SD卡在SPI模式下默认不开启CRC校验,在SDIO模式下开启CRC校验

SD卡的命令分为标准命令(如CMD0)和应用相关命令(如ACMD41)。ACMD命令是特殊命令,发送方法同标准命令一样,但是在发送应用相关命令之前,必须先发送CMD55命令,告诉SD卡接下来的命令是应用相关命令,而非标准命令。发送完命令后,SD卡会返回响应命令的信息,不同的CMD命令会有不同类型的返回值,常用的返回值有R1类型、R3类型和R7类型(R7类型是CMD8命令专用)

SD卡上电默认是SDIO模式
在接收SD卡返回CMD0的响应命令时,拉低片选CS,进入SPI模式。所以在发送CMD0命令的时候,SD卡处于SDIO模式,需要开启CRC校验。另外CMD8的CRC校验是始终启用的,也需要启用CRC校验。除了这两个命令,其它命令的CRC可以不用做校验

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

初始化步骤(基于SD2.0版本协议的SDHC卡)

1、SD卡完成上电后,主机FPGA先对从机SD卡发送至少74个以上的同步时钟,在上电同
步期间,片选CS引脚和MOSI引脚必须为高电平(MOSI引脚除发送命令或数据外,其
余时刻都为高电平);
2、拉低片选CS引脚,发送命令CMD0(0x40)复位SD卡,命令发送完成后等待SD卡返回
响应数据;
3、SD卡返回响应数据后,先等待8个时钟周期再拉高片选CS信号,此时判断返回的响应
数据。如果返回的数据为复位完成信号0x01,在接收返回信息期间片选CS为低电平,
此时SD卡进入SPI模式,并开始进行下一步,如果返回的值为其它值,则重新执行第
2步;
4、拉低片选CS引脚,发送命令CMD8(0x48)查询SD卡的版本号,只有SD2.0版本的卡
才支持此命令,命令发送完成后等待SD卡返回响应数据;
5、SD卡返回响应数据后,先等待8个时钟周期再拉高片选CS信号,此时判断返回的响应
数据。如果返回的电压范围为4’b0001即2.7V~3.6V,说明此SD卡为2.0版本,进行下
一步,否则重新执行第4步;
6、 拉低片选CS引脚,发送命令CMD55(0x77)告诉SD卡下一次发送的命令是应用相关
命令,命令发送完成后等待SD卡返回响应数据;
7、SD卡返回响应数据后,先等待8个时钟周期再拉高片选CS信号,此时判断返回的响应
数据。如果返回的数据为空闲信号0x01,开始进行下一步,否则重新执行第6步。
8、拉低片选CS引脚,发送命令ACMD41(0x69)查询SD卡是否初始化完成,命令发送
完成后等待SD卡返回响应数据;
9、SD卡返回响应数据后,先等待8个时钟周期再拉高片选CS信号,此时判断返回的响应
数据。如果返回的数据为0x00,此时初始化完成,否则重新执行第6步。

读写测试

	char send_data[150];
	char receiv[150];
	uint16_t sd_i;
	for(sd_i=0;sd_i<150;sd_i++)
     send_data[sd_i]='0'+sd_i;
		 switch(SD_Initialize())
			{
			case 0: 
				printf("\r\nSD Card Init Success!\r\n");
			break;
			case 1:  
						printf("Time Out!\n");
						break;
			case 99: 
						printf("No Card!\n");
						break;
			default: printf("unknown err\n");
			break;
			}
		SD_WriteDisk((uint8_t *)send_data,30,1);
		SD_ReadDisk((uint8_t *)receiv,30,1);
		printf("%s\r\n",receiv);

在这里插入图片描述
测试读写成功

FATFS文件系统

FATFS 是一个完全免费开源的 FAT 文件系统模块

最顶层是应用层,使用者无需理会 FATFS 的内部结构和复杂的 FAT 协议,只需要调用FATFS 模块提供给用户的一系列应用接口函数,如 f_open,f_read,f_write 和 f_close 等,就可以像在 PC 上读/写文件那样简单

在这里插入图片描述
中间层 FATFS 模块,实现了 FAT 文件读/写协议。
FATFS 模块提供的是 ff.c 和 ff.h。
除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可

需要我们编写移植代码的是 FATFS 模块提供的底层接口,它包括存储媒介读/写接口(disk I/O)和供给文件创建修改时间的实时时钟。

注意事项

ROM、RAM不够

  1. 将FIL结构体的两个fread和fwrite变量设置为全局变量,该方法避免了堆栈溢出现象

  2. FF_CODE_PAGE使用437

  3. FF_USE_LFN选择0

待补充

读写测试

在这里插入图片描述
在这里插入图片描述
测试成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花椒且喵酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值