SD卡数据读取

本文详细介绍了如何使用STM32F103C8T6通过SPI接口与CH376SSPI模块连接SD卡,进行初始化、读写操作。内容涵盖SPI模式、命令格式、初始化步骤以及读写数据流程。实验配置中提供了硬件连接图和源代码链接,代码分析部分展示了主函数的关键步骤。实验结果显示烧录和写入SD卡成功。
摘要由CSDN通过智能技术生成

本文使用到的硬件:STM32F103C8T6、Micro SD卡模块CH376S SPI接口、杜邦线、USB转TTL接口
本文使用到的软件:Keil MDK、串口调试助手


一、SPI读写SD卡介绍

SPI外设只具有两条数据线MISO和MOSI,分别用作数据的输入和输出,由于引脚较少,所以控制相对较容易。
在这里插入图片描述

1.1 SPI模式

在SPI模式下,数据都是以 字节(Byte)为单位进行传输的。此时SD卡作为从机设备,一般的操作是MCU发送带有参数的命令,SD卡接收到命令和参数后进行操作,并且返回响应,MCU根据返回的响应进行下一步操作。

在这里插入图片描述

1.2 命令

SD卡的命令有6个字节(48位),由以下几部分组成:
第一字节的最高位b7为起始位,始终为0
接下来为传输位,始终为1
b5-b0为命令代码
第2~5字节为命令的参数,共4个字节
最后一个字节的前7为CRC7校验位,最后一位为停止位,始终为1

常用命令:

命令参数响应类型简写描述
CMD00R1GO_IDLE_STATE软件复位
CMD8(*1)R7SEND_IF_COND发送MCU的电压范围,检测SD卡是否满足MCU的电压范围
ACMD41(*2)(*3)R1SD_SEND_OP_COND开始SD卡初始化和检测SD卡是否完成初始化
CMD90R1SEND_CSD读取CSD寄存器的值
CMD100R1SEND_CID读取CID寄存器的值
CMD120R1bSTOP_TRANSMISSION停止读取操作
CMD16数据块长度[31:0]R1SET_BLOCKLEN设置数据块长度(*4)
CMD17地址[31:0]R1READ_SINGLE_BLOCK读取单个数据块
CMD18地址[31:0]R1READ_MULTIPLE_BLOCK读取多个块数据
CMD24地址[31:0]R1WRITE_BLOCK写单个块数据
CMD25地址[31:0]R1WRITE_MULTIPLE_BLOCK写多个块数据
CMD550R1APP_CMD定义下一条命令为ACMD命令
CMD580R3READ_OCR读取OCR寄存器

1.3 初始化操作

SPI模式下的初始化操作有:上电->进入SPI模式(CMD0)->检测当前MCU电压是否符合SD卡的要求(CMD8)->开始初始化(ACMD41)->读取卡类型(CMD58)

初始化过程中,SD卡时钟信号周期需为100KHz~400KHz之间,不能大于400KHz。

  • 上电

    当电压达到SD卡的最小工作电压的后,MCU必须使CS,DI为高电平,输出最少74个时钟脉冲后,才能开始发送第一个命令。

  • 初始化过程

    SD卡上电后处于SD Bus模式,使CS保持为0,并且发送CMD0命令,SD卡就会进入到SPI模式。在SPI模式下,命令的CRC校验功能默认是禁止的(CMD8命令除外),但是发送第一个CMD0命令时,SD卡是处于SD Bus模式,该模式下CRC校验功能是启动的,因此第一个CMD0命令必须要有正确的CRC校验。正确的CMD0命令应为:0x40, 0x00, 0x00, 0x00, 0x00, 0x95。

    CMD8用于检测SD卡接口电压是否满足要求,该命令的参数包括当前MCU接口的电压范围VHS([11:8]),以及用于检测通信的Check Pattern([7:0])。如果SD卡能满足当前MCU的接口电压,它就会返回VHS和Check Pattern的值。需要注意的是,CMD8的CRC校验值必须正确,假如CRC校验不对,SD卡返回的R1值中的CRC错误位就会置1。
    ACMD41命令用于开始初始化SD卡及检测其是否完成初始化。该命令的参数HCS([30])表示MCU是否支持SDHC和SDXC,若支持HCS置1,反之置0。如果ACDM41命令返回R1的值为0x01,说明SD卡正在初始化,MCU需要重复发送ACMD41,直到返回值R1为0。
    初始化完成后,通过发送CMD58指令读取卡的类型(OCR寄存器的CCS位[30]), CCS为1表示当前卡的类型为SDXC或者SDHC,为0表示卡的类型为SDSC。

在这里插入图片描述

1.4 读写数据(多数据)

  • 读取数据
    读取多个数据块操作和读取单个数据块的相似,先发送命令CMD18,然后开始等待数据块的起始标识符。需要停止读取操作时,发送CMD12命令,返回响应为0表示SD卡处于忙碌状态,只有返回任何不为0的值后,MCU才能发送下一条命令。
    在这里插入图片描述

  • 写入数据
    当SD卡接收到写入多个数据块命令CMD25后,发送数据包起始符为(0xFC), 只有当DO不为0时,才能继续发送第二个数据包。如果要结束写入操作,则发送停止发送标识符(0xFD)
    在这里插入图片描述

二、实验配置

2.1 源代码

链接:https://pan.baidu.com/s/1lXiepBi4sLZra6uo3yJgOw
提取码:dnjs

2.2 硬件连线

STM32SD卡模块
PA4SDCS
PA5SCK
PA7MOSI
PA6MISO
VCCVCC
GNDGND

2.3 部分代码分析

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */
  

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  MX_FATFS_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	
	HAL_UART_Receive_IT(&huart1,&aRxBuffer1,1); 	//enable uart	

	printf(" mian \r\n");

	Get_SDCard_Capacity();	//得到使用内存并选择格式化



  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		
		
		
		WritetoSD(WriteBuffer,sizeof(WriteBuffer));		

		
		
		HAL_Delay(500);
		WriteBuffer[0] = WriteBuffer[0] +10;
		WriteBuffer[1] = WriteBuffer[1] +10;
		write_cnt ++;
		
		while(write_cnt > 10)
		{	
			printf(" while \r\n");
			HAL_Delay(500);
		}		
		
		
		
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

  • WritetoSD(WriteBuffer,sizeof(WriteBuffer));
    写入SD卡程序,我们可以在文件的开始定义我们要写入SD卡的内容
    在这里插入图片描述
  • SD_init();
    SD初始化函数,完成发送命令及鉴别SD卡
    在这里插入图片描述
  • while
    在这里插入图片描述
    write_cnt>10,write_cnt我们设置的初始值为0,表示当写入的次数达到11次我们就不再写入,输出while表示写入完成。

三、实验结果分析

  • 烧录成功

在这里插入图片描述

  • 初始化及写入SD卡成功

在这里插入图片描述

  • 查看文档
    在这里插入图片描述

四、总结

注意在接线时一定要保证5V电压,否则无法初始化,只可以完成烧录程序。虽然得到了最终结果,但理解原理是最重要的。


参考文章:
https://www.cnblogs.com/mr-bike/p/3546228.html
https://blog.csdn.net/qq_46467126/article/details/122033766
https://blog.csdn.net/IssacMi/article/details/102785961

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值