STM32CubeMX实战教程(八)——SD卡初始化

SD卡读写

    • 前言
    • 材料
    • SD卡
        • SD卡简介
        • SD管脚简介
    • SDIO介绍
      • 原理图
    • 工程配置
      • 时钟树
      • 基本信息
      • 指示灯和串口
      • SDIO配置
    • 进入代码
      • 一些源码及分析
      • main函数
    • 下载验证
      • 失败可能原因
    • 结语

前言

其实STM32CubeMX这款软件本身只是一个工具,它可以让我们更方便地去开发STM32,让我们更少地去关注硬件底层的关联,但这并不代表着底层硬件就不再重要了。一个优秀的嵌入式工程师往往不仅仅是关注着自己的程序是否实现基本功能,而是从硬件层面去理解整个工程或项目,这样才能尽可能地讲程序优化,用更少的资源,实现功能要求。
同样的,我的文章一般也不会仅仅去告诉大家实现某个功能需要什么操作,因为如果只是这样的话,你看了前两章软件怎么用就可以了,其他部分和标准库无非是照葫芦画瓢罢了。我是在尽量地去给大家解释清楚STM32的外设及其可以用到的资源,让大
彻底地了解STM32的某个外设有什么功能。以下将以SD卡为例展开。

材料

  • STM32F4正点原子探索者
  • 开发板原理图
  • HAL库函数手册
  • 有手就行

SD卡

SD卡简介

  1. MMC:MMC就是MultiMediaCard的缩写,即多媒体卡
  2. SD卡(Secure Digital Memory Card)即:安全数码卡,它是在MMC的基础上发展而来,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。
    SD卡按容量分类,可以分为3类:SD卡、SDHC卡、SDXC卡,如下表所示:
    STM32CubeMX实战教程(八)——SD卡初始化_第1张图片

SD管脚简介

我们现在常用的是Micro SD卡,尺寸非常小的,其管脚图如下。

STM32CubeMX实战教程(八)——SD卡初始化_第2张图片
STM32CubeMX实战教程(八)——SD卡初始化_第3张图片

SD卡的接口可以支持SD卡模式和SPI模式两种操作模式。
SD模式:采用6线制,使用CLK、CMD、DAT0、DAT3。其中CLK为时钟线,CMD为命令控制线,DAT0~DAT3为数据线,允许4线的高速数据传输;
SPI模式:通用的SPI通道接口,使用CS、CLK、DI、DO进行数据通信。
SD模式的数据传输速度比SPI模块要快

使用STM32的SDIO操作SD卡即为SD模式,但部分STM32是不带SDIO的,不过我们也可以使用SPI模式来操作SD卡,还是比较方便的,这里因为主要介绍的是STM32CubeMX的SDIO外设以及HAL库相关函数的用法,所以就不多介绍SPI模式了。

SDIO介绍

SDIO主要特点如下:

  1. 与多媒体卡系统规格书版本4.2全兼容。支持三种不同的数据总线模式:1位(默认)、4位和8位。
  2. 与较早的多媒体卡系统规格版本全兼容(向前兼容)。
  3. 与SD存储卡规格版本2.0全兼容。
  4. 与SD I/O卡规格版本2.0全兼容:支持两种不同的数据总线模式:1位(默认)和4位。
  5. 完全支持CE-ATA功能(与CE-ATA数字协议版本1.1全兼容)。 8位总线模式下数据传输速率可达48MHz。
  6. 数据和命令输出使能信号,用于控制外部双向驱动器。

其他相关介绍我就不在此多费笔墨了,毕竟这些都不是重点,说白了只需要知道SDIO可以帮助我们操作SD卡即可

原理图

在STM32F4的原理图/开发板中,一般SD卡有两种形式,第一种是micro SD,也叫TF卡,即我们最常见到的微型SD卡,另一种是SD卡,就是大卡,这两种除了大小不同之外,在操作上没有任何区别,有些TF卡可以插入SD卡套变成大卡
正点原子开发板上的是SD大卡槽,原理图如下
STM32CubeMX实战教程(八)——SD卡初始化_第4张图片
而另外micro SD一般是这样的
STM32CubeMX实战教程(八)——SD卡初始化_第5张图片

在有SDIO的芯片上,优先将SD卡接到SDIO引脚,在没有SDIO外设的芯片上,如果使用SD接口,则应当接到SPI接口

工程配置

时钟树

这次做的是SD卡读写实验,时钟配置主时钟仍然是最高的168M,SDIO外设挂载在APB2上,最高只能是48M,这里需要注意
ps:先把SDIO使能后才能修改SDIO的时钟,这里时钟速度用48M
STM32CubeMX实战教程(八)——SD卡初始化_第6张图片

基本信息

基本信息设置,与之前工程的配置完全一样,这里提前提醒一下,如果仅仅是像本工程一样简单读写一下SD卡,则不需要额外的设置,但是如果需要使用到文件系统FATFS,则需要修改堆栈大小,否则导致系统卡死!,当然本工程不需要纠结这些,我这里由于是从其他工程复制过来的就没有将这个值改回去了。
STM32CubeMX实战教程(八)——SD卡初始化_第7张图片

指示灯和串口

使能俩灯,不一定用得到,先配置好放着,这个不懂的看《STM32CubeMX实战教程(二)——按键点个灯》
在这里插入图片描述
STM32CubeMX实战教程(八)——SD卡初始化_第8张图片
使能串口,不懂的童鞋看《STM32CubeMX实战教程(六)——串口通信(为啥你的中文会乱码)》,使能指示灯和串口是每个工程开发必备的好习惯,调试时会方便很多,懂的都懂
STM32CubeMX实战教程(八)——SD卡初始化_第9张图片

SDIO配置

本章重点要来了,打开外设使能的SDIO这一栏,只有一个选项框,点开,长这样。
STM32CubeMX实战教程(八)——SD卡初始化_第10张图片
如果你只想知道现在要选哪个,我告诉你选SD 4 bits Wide bus就行了,但如果你想知道原因以及其他选项的意思还是要好好看下去。

  1. SD 1 bits 单线SD模式
  2. SD 4 bits Wide bus 4线SD模式
  3. MMC 1 bit MMC卡单线模式
  4. MMC 4 bits Wide bus MMC卡4线模式
  5. MMC 8 bits Wide bus MMC卡8线模式
    本文一开始就有提到,MMC为多媒体卡,而SD卡是在MMC卡的基础上演变而来的,两者都是存储介质,外表也并没有很大差异,只是SD卡会更厚一些,但在数据读写操作上是不兼容的,所以这里需要区别。
    单线和多线模式完全取决于引脚资源是否够用,当然用到的引脚越少速度也就越慢,所以这里选则SD 4 bits Wide bus,该模式下通信速度最高可达48MHz。
    接下来看到下面的配置
    STM32CubeMX实战教程(八)——SD卡初始化_第11张图片
    第一行相当于是在时钟的上升沿还是下降沿采集数据,一般都是上升沿
    第二行决定是否使用bypass(旁路),即跳过分频直接从HCLK得到时钟,那样频率会非常高,所以也不需要
    第三行空闲时,也就是在没有数据交互的时候是否关闭时钟电源,在不考虑功耗的情况下还是尽量不要用比较好。
    第四行硬件流控,可用于解决数据量大或者高速传输时的速度匹配和准确率不足等问题,这里不需要。
    第五行,时钟分频,与读写速度有关,这里不多说了,时钟树配好48M的话这里选0就好。
    以上参数都配置完毕后就可以生成代码进入工程了。

进入代码

一些源码及分析

废话不多说,先来一段要用到的源码,添加位置: main.c下主函数之前

HAL_SD_CardInfoTypeDef  SDCardInfo;  
void show_sdcard_info(void)
{
	uint64_t CardCap;	//SD卡容量
	HAL_SD_CardCIDTypeDef SDCard_CID;

	HAL_SD_GetCardCID(&hsd,&SDCard_CID);	//获取CID
	HAL_SD_GetCardInfo(&hsd,&SDCardInfo);					//获取SD卡信息
	switch(SDCardInfo.CardType)
	{
		case CARD_SDSC:
		{
			if(SDCardInfo.CardVersion == CARD_V1_X)
				printf("Card Type:SDSC V1\r\n");
			else if(SDCardInfo.CardVersion == CARD_V2_X)
				printf("Card Type:SDSC V2\r\n");
		}
		break;
		case CARD_SDHC_SDXC:printf("Card Type:SDHC\r\n");break;
	}	
	CardCap=(uint64_t)(SDCardInfo.LogBlockNbr)*(uint64_t)(SDCardInfo.LogBlockSize);	//计算SD卡容量
  printf("Card ManufacturerID:%d\r\n",SDCard_CID.ManufacturerID);					//制造商ID
 	printf("Card RCA:%d\r\n",SDCardInfo.RelCardAdd);								//卡相对地址
	printf("LogBlockNbr:%d \r\n",(uint32_t)(SDCardInfo.LogBlockNbr));					//显示逻辑块数量
	printf("LogBlockSize:%d \r\n",(uint32_t)(SDCardInfo.LogBlockSize));					//显示逻辑块大小
	printf("Card Capacity:%d MB\r\n",(uint32_t)(CardCap>>20));							//显示容量
 	printf("Card BlockSize:%d\r\n\r\n",SDCardInfo.BlockSize);						//显示块大小
}

HAL_SD_CardInfoTypeDef是获取SD卡基本信息的结构体,另外每行的作用都已经注释清楚了,用来打印SD卡的基本信息,也就是作为观察SD卡初始化是否成功的标志,PS:别忘了将串口重定向好,否则打印了个寂寞

main函数

在各外设初始化后,while循环前调用上述函数,另外在while循环中加入LED灯的闪烁以指示系统的正常运转,具体如下

{
  /* 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_SDIO_SD_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	show_sdcard_info();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
		HAL_Delay(1000);
    /* USER CODE END WHILE */

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

下载验证

至此,SD实验的工作已经全部完成,需先将SD卡插入开发板后下载,先后顺序不能错,因为本次实验尚未涉及SD卡插拔的检测问题,开发板也没有设计支持插拔检测的电路,需要此功能得先修改一下电路,其实也不难,就飞一条线而已,下载后串口调试助手就会打印如下字样(不同型号SD卡会有所区别)STM32CubeMX实战教程(八)——SD卡初始化_第12张图片
另外由于SD卡读写往往先跟文件系统和内存管理结合,这里暂时先不提供SD卡读写的代码了
具体下载方法这里不再重复,可查看《STM32CubeMX实战教程(一)——软件入门》,工程源文件我已经上传,有串口测试版本《基于STM32CubeMX和F407的SD卡初始化实验(串口打印)》及液晶测试版本在《基于STM32CubeMX和STM32F4的SD卡初始化实验》

非常抱歉由于CSDN官网上传的资源必须要设定积分,否则几乎无法通过审核,这里就没有办法免费开发给大家,不过源码在教程里已经非常详细了。

失败可能原因

  1. 步骤错误,仔细检查核对上述步骤
  2. SD卡不支持,少数SD卡因格式或大小等问题可能会不支持,建议更换不同厂商的SD卡后再测试,也最好不要用年代过于久远的SD卡
  3. SD卡损坏,建议用电脑将此SD卡格式化后再测试,仍不行则更换SD卡
  4. 硬件问题,有没有可能是SD卡的大卡套是坏的呢
  5. 非本实验问题,开发环境啊,其他基本配置啊这些

结语

SD卡也是开发过程中常用到的功能,同时会涉及到文件系统和内存管理等知识,使其变得比较复杂,所以本章也只是SD卡学习的第一步,大家继续加油呀!
非常感谢大家的阅读,如有不当或者错误的地方,欢迎指正,谢谢支持。
一个字一个字敲出来不容易,如果觉得有帮助,点个赞再走呗
祝大家事业蒸蒸日上!
奥里给~

你可能感兴趣的:(stm32,单片机,arm)