本文主要利用STM32F103完成对SD卡的数据读取,介绍该实验的详细操作

  • 一、题目要求
  • 二、SD卡协议原理
    • 1、SD卡简述
    • 2、SD卡物理结构
    • 3、SD卡寄存器
    • 4、SD卡操作模式
    • 5、SD卡初始化(SPI模式)
    • 6、SD卡读取与写入(SPI模式)
  • 三、实验操作
    • 1、硬件准备
    • 2、连线
    • 3、HAL库配置
    • 4、代码分析
    • 5、实验结果分析
  • 四、SD卡累计写入及速率分析
    • 1、题目要求
    • 2、硬件准备
    • 3、实验操作
  • 五、总结

一、题目要求

掌握SD卡协议原理,用STM32F103完成对SD卡的数据读取(fat文件模式)。

二、SD卡协议原理

1、SD卡简述

很多单片机系统都需要大容量存储设备,以存储数据。目前常用的有 U 盘,FLASH 芯片,SD 卡等。他们各有优点,综合比较,最适合单片机系统的莫过于 SD 卡了,它不仅容量可以做到很大(32GB 以上),支持 SPI/SDIO 驱动,而且有多种体积的尺寸可供选择(标准的 SD 卡尺寸,以及 TF 卡尺寸等),能满足不同应用的要求。
只需要少数几个 IO 口即可外扩一个高达 32GB 以上的外部存储器,容量从几十 M 到几十G 选择尺度很大,更换也很方便,编程也简单,是单片机大容量外部存储器的首选。

2、SD卡物理结构

一般SD卡包括有存储单元、存储单元接口、电源检测、卡及接口控制器和接口驱动器 5个部分。


  • 存储单元是存储数据部件,存储单元通过存储单元接口与卡控制单元进行数据传输;
  • 电源检测单元保证SD卡工作在合适的电压下,如出现掉电或上状态时,它会使控制单元和存储单元接口复位;
  • 卡及接口控制单元控制SD卡的运行状态,它包括有8个寄存器; 接口驱动器控制SD卡引脚的输入输出。

3、SD卡寄存器

SD卡总共有8个寄存器,用于设定或表示SD卡信息。
这些寄存器只能通过对应的命令访问,SDIO定义64个命令,每个命令都有特殊意义,可以实现某一特定功能,SD卡接收到命令后,根据命令要求对SD卡内部寄存器进行修改,程序控制中只需要发送组合命令就可以实现SD卡的控制以及读写操作。

名称 bit宽度 描述
CID 128 卡识别号(Card identification number):用来识别的卡的个体号码(唯一的)
RCA 16 相对地址(Relative card address):卡的本地系统地址,初始化时,动态地由卡建议,主机核准
DSR 16 驱动级寄存器(Driver Stage Register):配置卡的输出驱动
CSD 128 卡的特定数据(Card Specific Data):卡的操作条件信息
SCR 64 SD配置寄存器(CD Configuration Register):SD卡特殊特性信息
OCR 32 操作条件寄存器(Operation conditiongs register)
SSR 512 SD状态(SD Status):SD卡专有特征的信息
CSR 32 卡状态(Card Status):卡状态信息

4、SD卡操作模式

SD卡一般都支持 SDIO 和 SPI 这两种接口。
其中SD卡模式的信号线有:CLK、CMD、DAT0-DAT3,6根线。
SPI模式的信号线有:CS、CLK、MISO(DATAOUT)、MOSI(DATAIN),4根线。
SD卡的命令格式:命令CMD0就是0,CMD16就是16,以此类推。
SD卡的命令总共有12类,下表为几个比较重要的命令:

命令 参数 回应 描述
CMD0(0X00) NONE R1 复位SD卡
CMD8(0X08) VHS+Check Pattern R7 发送接口状态命令
CMD9(0X09) NONE R1 读取卡特定数据寄存器
CMD10(0X0A) NONE R1 读取卡标志数据寄存器
CMD16(0X10) 块大小 R1 设置块大小(字节数)
CMD17(0X11) 地址 R1 读取一个块的数据
CMD24(0X18) 地址 R1 写入一个块的数据
CMD41(0X29) NONE R3 发送给主机容量支持信息和激活卡初始化过程
CMD55(0X37) NONE R1 告诉SD卡,下一个是特定应用命令
CMD58(0X3A) NONE R3 读取OCR寄存器

5、SD卡初始化(SPI模式)

SPI操作模式下:在SD卡收到复位命令时,CS为有效电平(低电平),则SPI模式被启用,在发送CMD之前要先发送74个时钟,64个为内部供电上升时间,10个用于SD卡同步;之后才能开始CMD操作,在初始化时CLK时钟不能超过400KHz。

1、初始化与SD卡连接的硬件条件(MCU的SPI配置,IO口配置);

2、上电延时(>74个CLK);

3、复位卡(CMD0),进入IDLE状态;

4、发送CMD8,检查是否支持2.0协议;

5、根据不同协议检查SD卡(命令包括:CMD55、CMD41、CMD58和CMD1等);

6、取消片选,发多8个CLK,结束初始化

这样我们就完成了对SD卡的初始化,注意末尾发送的8个CLK是提供SD卡额外的时钟,完成某些操作。通过SD卡初始化,我们可以知道SD卡的类型(V1、V2、V2HC或者MMC),在完成了初始化之后,就可以开始读写数据了。

6、SD卡读取与写入(SPI模式)

1、发送CMD17;
2、接收卡响应R1;
3、接收数据起始令牌0XFE;
4、接收数据;
5、接收2个字节的CRC,如果不使用CRC,这两个字节在读取后可以丢掉。
6、禁止片选之后,发多8个CLK;

以上就是一个典型的读取SD卡数据过程,SD卡的写于读数据差不多,写数据通过CMD24来实现,具体过程如下:

1、发送CMD24;
2、接收卡响应R1;
3、发送写数据起始令牌0XFE;
4、发送数据;
5、发送2字节的伪CRC;
6、禁止片选之后,发多8个CLK;

以上就是一个典型的写SD卡过程。

三、实验操作

1、硬件准备

SD卡模块及SD卡

内部结构:

部分 说明
控制接口 共 6 个引脚(GND、VCC、MISO、MOSI、SCK、CS),GND 为地,VCC 为供 电电源,MISO、MOSI、SCK 为 SPI 总线,CS 为片选信号脚
3.3V 稳压电路 LDO 稳压输出的 3.3V 为电平转换芯片、Micro SD 卡供电
电平转换电路 往 Micro SD 卡方向的信号转换成 3.3V,MicroSD 卡往控制接口方向的 MISO 信号也转换成了 3.3V,一般 AVR 单片机系统都能读取该信号
Micro SD 卡座 是自弹式卡座,方便卡的插拔
定位孔 4 个 M2 螺丝定位孔,孔径为 2.2mm,使模块便于安装定位,实现模块间组合

2、连线

stm32 SD卡模块
PA4 SDCS
PA5 SCK
PA7 MOSI
PA6 MISO
VCC VCC
GND GND

3、HAL库配置

因为STM32要连接SD卡模块,所以我们要进行相应配置。




之后导出即可。

4、代码分析

完整工程代码如下(hal库版本)
链接:https://pan.baidu.com/s/1YxLpaIM6HMQ4d_9yh4M4ww
提取码:276d

针对main主函数进行分析

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(" main \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 */
}

说明:


这里我们看下write_cnt初始定义的值,计算写入次数循环要求。
(在main.c文件头部)
从0开始,write_cnt=0,因此要写入超过11次,之后不再写入内容。
写入函数WritetoSD

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);      //取消挂载
}

从写入函数中,我们可以知道,针对SD卡文件的每个步骤,我们都进行了相应的字段输出,来具体判断究竟进行到了什么地步。

5、实验结果分析

最开始,要么初始化失败,要么没反应,要么初始化成功之后没反应,各种情况吧。

之后改变了接线电压,SD卡模块接5v,STM32也接了5v,还是失败。
然后重新接线,换成了新的杜邦线,然后就成功了,只能说这个实验很玄学

就很秃然

然后打开sd卡确实看到了hello文本文件写入了内容。
这里有两个情况
我最开始在SD卡下建立了hello.txt文件(里面最开始写了数字1),因为担心初始化不成功,然后SD卡写入成功后,SD卡内容是这样的:


之后,我把hello.txt文件删了,看看SD卡能不能自己建立一个txt文本文件:

果然是成功的,而且内容是一样的。

但是左侧出现了乱码情况,因此对主函数进行修改

再烧录一次试试

有序写入,说明是成功的。

然后分析一下串口收到的内容:



可以证明,确实写入次数超过11次后,会不断返回while值,而txt文本里有11行内容,之后也不会再写入了。

四、SD卡累计写入及速率分析

1、题目要求

在SD卡创建一个test-speed.txt文件,循环(不加延时)分批一次写入256字节,累计写入不少于64KB字节;然后读取此文件数据,通过串口显示出来。分析写入和读取的速率。

2、硬件准备

闪迪16GB的SD卡(下图介绍了市面产品的读写测试数据)

SD卡模块
资料下载:https://pan.baidu.com/s/1WJZ3NpnaxqubPRC3XNLy1Q 提取码:6bsu
单片机采用STM32F103C8T6最小核心板


接线

3、实验操作

因为要分批一次写入256个字节,也就是128个字,除了最开始用序号标识写入次数,内容都是一致的,随便找一些内容放上就好。

目的要累计写入超过64KB字节,1KB=1024bytes,64KB=65536bytes,每次写入256bytes,那么至少要写入65536/256=256次才可以。

修改内容及文件名

char SD_FileName[] = "test-speed.txt";
uint8_t WriteBuffer[] = "001君不见黄河之水天上来奔流到海不复回君不见高堂明镜悲白发朝如青丝暮成雪人生得意须尽欢莫使金樽空对月天生我材必有用千金散尽还复来烹羊宰牛且为乐会须一饮三百杯岑夫子丹丘生将进酒杯莫停与君歌一曲请君为我倾耳听钟鼓馔玉不足贵但愿长醉不复醒古来圣贤皆寂寞\r\n";

修改序号的循环,使之能够最少从001到999

  while (1){ WritetoSD(WriteBuffer,sizeof(WriteBuffer)); t=write_cnt + 1;if(t<10){WriteBuffer[0] = WriteBuffer[0]+0;WriteBuffer[1] = WriteBuffer[1]+0;WriteBuffer[2] = WriteBuffer[2]+1;}else if(t<100){WriteBuffer[0] = WriteBuffer[0]+0;WriteBuffer[1] = t / 10;WriteBuffer[2] = t % 10;}else{WriteBuffer[0] = t /100;WriteBuffer[1] = (t/10) % 10;WriteBuffer[2] = t % 10;}write_cnt ++;if(write_cnt > 255)//写入超过256次后提示{   printf(" while \r\n");}       /* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

五、总结

为了让这个实验成功还是花费了蛮多的时间,做实验可能就是这样的跌宕起伏,毕竟人生不如意十有八九,八九才是大多数。

整个实验操作很简单,了解了SPI协议,按部就班去做,并不难实现,但是很容易卡死在初始化的环节,线务必接好,接触不良就很容易失败,多按压一下板子也会有用可能。

祝各位好运。

参考

[1] https://blog.csdn.net/m0_53089598/article/details/121985861

[2] https://blog.csdn.net/lqmlmo/article/details/80830082

[3] https://blog.csdn.net/fengxiaocheng/article/details/81411117

【嵌入式20】STM32F103完成对SD卡的数据读取详细操作相关推荐

  1. STM32F103完成对SD卡的数据读取详细操作

    SD卡协议原理 SD卡简述 关于SPI协议 通讯的起始和停止信号. 数据有效性 连线 代码完整工程 修改代码 烧录结果 总结 SD卡简述 很多单片机系统都需要大容量存储设备,以存储数据.目前常用的有 ...

  2. STM32F103完成对SD卡的数据读取(fat文件模式)

    目录 一.关于SD卡 1.简介 2.SD卡的寄存器 3.SD卡读取与写入(SPI模式) 二.实验操作 1.仪器 2.代码 3.连线 4.烧录程序 5.串口调试助手初始化并写入文件 6.sd卡里hell ...

  3. 使用Altium Designer 绘制原理图并且使用STM32F103完成对SD卡的数据读取

    使用Altium Designer 绘制原理图并且使用STM32F103完成对SD卡的数据读取 前言 实验要求 一. 电路原理图绘制 软件安装配置过程 (一)绘制stm32最小系统的电路原理图 1.新 ...

  4. 基于STM32F103完成对SD卡的数据读取(fat文件模式)

    文章目录 实验内容 一.SD卡协议 (一).SD卡简介 (二).SD 卡物理结构 (三).SD卡总线 二.基于STM32F103完成对SD卡的数据读取 (一).创建工程 (二).修改代码 (三).串口 ...

  5. STM32F103完成对SD卡的数据读取

    目录 一.SD卡介绍 1.概述 2.SD模式 3.SD卡读取与写入(SPI模式) 二. STM32F103完成对SD卡的数据读取 1.代码部分 2.U盘格式化 3.电路连接 4.具体实现 三.参考资料 ...

  6. 用STM32F103完成对SD卡的数据读取

    目录 SD卡协议原理 STM32+SD卡 的系统原理图设计 具体原理 代码 所用软件及硬件: 成果 参考文献 SD卡协议原理 功能 SD卡是存储卡,它的功能就是存储. 分类 SD卡按容量分类,可以分为 ...

  7. STM32+SD卡的原理图绘制以及用32完成对SD卡的数据读取(fat文件模式)

    目录 一.下载安装AD 1.1安装方法一 1.2安装方法二 二.绘制STM32最小系统原理图 2.1元件库 2.2新建工程 2.3绘制原理图 三.SD卡协议原理 3.1SD卡简介 3.2SD卡接口 3 ...

  8. STM32F103之完成对SD卡的数据读取

    文章目录 一. 认识SD卡 1. 介绍SD卡 2. SD卡的物理结构 3. SD卡寄存器 4. SD卡模式 5. 初始化SD卡过程 6. SD卡读取数据 二. 实验操作--对SD卡进行数据读取 1. ...

  9. STM32F103最小板完成对SD卡的数据读取(fat文件模式)

    目录 一.SD卡协议原理介绍 1.SD卡简介 2.SDIO设备分类 3.SD卡物理结构 4.SD卡寄存器 5.SD模式 驱动模式 传输模式 二. 实现对SD卡的数据读取 1.硬件准备 2.芯片模块与S ...

最新文章

  1. postfix导入extmail.sql时报错
  2. 03_TF2 Guide、文档清单(数据输入、估计器、保存模型、加速器、性能调优等)、TF2库和扩展库(TensorBoard、数据集、TensorFlow Hub、概率和统计分析库、图像处理库)
  3. 电磁波传播相位是否会变化_民众纷纷转向网上购物,却又担心包裹信件是否会传播病毒?!...
  4. C#通用验证类:邮箱,电话,手机,数字,英文,日期,身份证,邮编,网址,IP
  5. 香橙派 OrangPi PC 安装Lakka游戏系统及使用指南
  6. 什么模拟器可以完全模拟真机_什么是模拟器?
  7. opencv基于MultiTracker的多目标跟踪
  8. 关于电子发票打印报销最优美的姿势——发票大师网页版
  9. 【量化笔记】移动均线
  10. 常用的的身份证校验方法
  11. java打印日志的几种方式
  12. C# 微信证书签名,WECHATPAY2-SHA256-RSA2048 签名方式
  13. 5.1.2 消费者的加入组和同步组
  14. 面试:第十二章:所有总结
  15. 【人工智能实验】运用贝叶斯决策理论实现手写数字识别
  16. flutter 实现圆形图片
  17. 【QPSK中频】基于FPGA的QPSK中频信号产生模块verilog设计
  18. 闲侃自己的人生观与价值观
  19. c/c++动态检测内存错误利器 - ASan
  20. mysql workbench 1142,eclipse window 10 64位 jdk 1.8 亲测

热门文章

  1. 秒杀99.99%大学生!看看清华的学霸到底有多牛?
  2. linux ftok()
  3. 电脑技巧 之 Discord翻译插件(PC端)(保姆级教程)
  4. SQL语句模糊查询 JavaWeb 项目 dao层 【常用来做搜索框】
  5. Linux攻关之基础模块五 Vim
  6. 【学习日志】2022.10.16 万用头文件 sstream C++进制转换
  7. 本地计算机无法启动wireless,win7系统使用无线时提示:“windows无法启动wireless”的解决办法...
  8. 同步,异步的区别 异步操作同步化
  9. 80X86汇编—存储器的变址寻址
  10. 如何在linux下查看服务器的型号