SD卡协议原理并用STM32F103 完成对SD卡的数据读取(FAT文件模式)

一、SD卡

1.SD卡简述

SD存储卡(Secure Digital Memory Card)是一种基于半导体快闪存储器的新一代高速存储设备。SD存储卡的技术是从MMC卡(MultiMedia Card格式上发展而来,在兼容SD存储卡基础上发展了SDIO(SD Input/ Output)卡,此兼容性包括机械,电子,电力,信号和软件,通常将SD、SDIO卡俗称SD存储卡。

2.SD卡的特点

SD卡具有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性,它被广泛地应用于便携式装置上,例如数码相机、平板电脑和多媒体播放器等。
SD卡的结构能保证数字文件传送的安全性,也很容易重新格式化,所以有着广泛的应用领域。音乐、电影等多媒体文件都可以方便地保存到SD卡中。目前市场上SD卡的品牌很多诸如:SANDISK、Kingmax、Panasonic和Kingston。

SD卡作为一种新型的存储设备,具有以下特点:

SD卡特点
高存储容量,最常用的容量:8GB、16GB、32GB、128GB、256GB等
内置加密技术,适应基于SDMI协议的著作版权保护功能
高速数据传送;最大读写速率为100MB/s
体积轻小,便于携带,具有很强的抗冲击能力

3.SD卡的寄存器

SD卡总共有8个寄存器,用于设定或表示SD卡信息。
这些寄存器只能通过对应的命令访问,SDIO定义64个命令,每个命令都有特殊意义,可以实现某一特定功能。

寄存器及功能描述如下

寄存器名称简述
OCR(Operating Conditions Register)寄存器32位的操作条件寄存器主要存储了VDD电压范围,SD卡操作电压范围为2~3.6V
CID(Card IDentification Register)寄存器卡识别码寄存器,长度为16个字节,存储SD卡唯一标识号,该号在卡生产厂家编程后无法修改
CSD(Card-Specific Data Register)寄存器卡特性数据寄存器,包含了访问该卡数据时的必要配置信息
SCR(SD Card Configuration Register)寄存器SD卡配置寄存器(SCR),提供了SD卡的一些特殊特性在这张卡内,长度为64位,这个寄存器内容由制造商在生产厂内设置
RCA(Relative Card Address)寄存器卡相对地址寄存器是一个16位可写的地址寄存器,控制器可通过地址选择对应地址的SD卡
DSR(Driver Stage Register)寄存器驱动级寄存器,属于可选寄存器,用于配置卡的驱动输出

4.SPI协议

SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是MISO(主设备数据输入)、MOSI(主设备数据输出)、SCLK(时钟)、CS(片选)。

  • SPI物理层
    在这里插入图片描述
总线名称简介
SCK(Serial Clock)时钟信号线,用于通讯数据同步。它由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,两个设备之间通讯时,通讯速率受限于低速设备
MOSI(Master Output, Slave Input)主设备输出/从设备输入引脚。这条线上的数据从主机传送到从机
MISO(Master Input,,Slave Output)主设备输入/从设备输出引脚。这条线上的数据从从机传送到主机
SS(Slave Select)又叫NSS,片选信号线。低电平时该从设备被选中
  • SPI协议层
    与 I2C的类似,SPI协议定义了通讯的起始和停止信号、数据有效性、时钟同步等环节。
    SPI通信时序
    在这里插入图片描述

二、实验操作——对SD卡进行数据读取

1.硬件连接

主要用到两个硬件:STM32F103和SD卡

  • SD卡
    在这里插入图片描述
  • 硬件连接方式
stm32SD卡模块
PA4SDCS
PA5SCK
PA6MISO
PA7MOSI
VCCVCC
GNDGND

注意:VCC要接5V!!!
在这里插入图片描述

2.建立工程文件

详细的工程文件获取:
链接:https://pan.baidu.com/s/1MFVI8M022kbmuOlGbAl6aw
提取码:xhc1

工程文件是基于CubeMX得到的,下面介绍一下本次实作需要注意的地方

  • USART1选择Asynchronous,异步模式
    在这里插入图片描述
  • SPI1选择Full-Duplex Master,全双工主模式
    在这里插入图片描述
  • FATFS中勾选User-defined
    在这里插入图片描述

3.代码部分

代码如下:

int fputc(int ch, FILE *f)    
{
    HAL_UART_Transmit(&huart1, (unsigned char *)&ch, 1, 0xFFFF);   
    return ch;
}
uint16_t uart_value[3];
uint8_t aRxBuffer1;	//uart rx buff 





void WritetoSD(BYTE write_buff[],uint8_t bufSize);
char SD_FileName[] = "hello.txt";
uint8_t WriteBuffer[] = "01 write buff to sd \r\n";

//uint8_t test_sd =0;	//用于测试格式化
uint8_t write_cnt =0;	//写SD卡次数




void WritetoSD(BYTE write_buff[],uint8_t bufSize)
{
	FATFS fs;
	FIL file;
	uint8_t res=0;
	UINT Bw;	
	
	res = SD_init();		//SD卡初始化
	
	if(res == 1)
	{
		printf("SD卡初始化失败! \r\n");		
	}
	else
	{
		printf("SD卡初始化成功! \r\n");		
	}
	
	res=f_mount(&fs,"0:",1);		//挂载
	
//	if(test_sd == 0)		//用于测试格式化
	if(res == FR_NO_FILESYSTEM)		//没有文件系统,格式化
	{
//		test_sd =1;				//用于测试格式化
		printf("没有文件系统! \r\n");		
		res = f_mkfs("", 0, 0);		//格式化sd卡
		if(res == FR_OK)
		{
			printf("格式化成功! \r\n");		
			res = f_mount(NULL,"0:",1); 		//格式化后先取消挂载
			res = f_mount(&fs,"0:",1);			//重新挂载	
			if(res == FR_OK)
			{
				printf("SD卡已经成功挂载,可以进进行文件写入测试!\r\n");
			}	
		}
		else
		{
			printf("格式化失败! \r\n");		
		}
	}
	else if(res == FR_OK)
	{
		printf("挂载成功! \r\n");		
	}
	else
	{
		printf("挂载失败! \r\n");
	}	
	
	res = f_open(&file,SD_FileName,FA_OPEN_ALWAYS |FA_WRITE);
	if((res & FR_DENIED) == FR_DENIED)
	{
		printf("卡存储已满,写入失败!\r\n");		
	}
	
	f_lseek(&file, f_size(&file));//确保写词写入不会覆盖之前的数据
	if(res == FR_OK)
	{
		printf("打开成功/创建文件成功! \r\n");		
		res = f_write(&file,write_buff,bufSize,&Bw);		//写数据到SD卡
		if(res == FR_OK)
		{
			printf("文件写入成功! \r\n");			
		}
		else
		{
			printf("文件写入失败! \r\n");
		}		
	}
	else
	{
		printf("打开文件失败!\r\n");
	}	
	
	f_close(&file);						//关闭文件		
	f_mount(NULL,"0:",1);		 //取消挂载
	
}


void Get_SDCard_Capacity(void)
{
	FRESULT result;
	FATFS FS;
	FATFS *fs;
	DWORD fre_clust,AvailableSize,UsedSize;  
	uint16_t TotalSpace;
	uint8_t res;
	
	res = SD_init();		//SD卡初始化
	if(res == 1)
	{
		printf("SD卡初始化失败! \r\n");		
	}
	else
	{
		printf("SD卡初始化成功! \r\n");		
	}
	
	/* 挂载 */
	res=f_mount(&FS,"0:",1);		//挂载
	if (res != FR_OK)
	{
		printf("FileSystem Mounted Failed (%d)\r\n", result);
	}

	res = f_getfree("0:", &fre_clust, &fs);  /* 根目录 */
	if ( res == FR_OK ) 
	{
		TotalSpace=(uint16_t)(((fs->n_fatent - 2) * fs->csize ) / 2 /1024);
		AvailableSize=(uint16_t)((fre_clust * fs->csize) / 2 /1024);
		UsedSize=TotalSpace-AvailableSize;              
		/* Print free space in unit of MB (assuming 512 bytes/sector) */
		printf("\r\n%d MB total drive space.\r\n""%d MB available.\r\n""%d MB  used.\r\n",TotalSpace, AvailableSize,UsedSize);
	}
	else 
	{
		printf("Get SDCard Capacity Failed (%d)\r\n", result);
	}		
} 

针对SD卡文件的每个步骤,我们都进行了相应的字段输出,来具体判断究竟进行到了什么地步

4.烧录与输出结果

  • 当我们执行程序后,就可以将生成的hex文件烧录进入单片机中
    在这里插入图片描述
  • 打开串口助手,观察输出结果
    在这里插入图片描述
  • 通过读卡器,接入SD卡,发现有输出,打开输出文本,结果显示乱码
    在这里插入图片描述
  • 更改代码部分如下
    在这里插入图片描述
  • 再次观察,结果显示正常
    在这里插入图片描述

总结

这篇博客主要简述了SD卡的特点和其寄存器的类型和作用,再一次阐释了SD卡中的SPI协议,并将SPI协议分为物理层和协议层进行论述。最后通过实际的例子,显示出的结果,展示了SD卡的工作特点。其实践过程有不少的困难,但是只要注意到一些细节,回过头来总结,发现也没有特别困难。

参考资料

SD卡
SPI (SPI协议)
详细图解SD卡的结构及其引脚功能

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值