SD卡学习笔记

2023-10-26

每个sector为512B,与IDE磁盘一样。通过读写命令读取一个多个sector。主控程序不需要关注SD具体是怎么实现读写与擦写的。

每个sector可以耐受100,000次写操作,无限次读操作。

每当sector被用命令erase命令擦除了,那么写操作将会更快。

1 功能概述

1.1 SD模式

1.1.1 Card ID

    CID是用于存放SD卡识别码的寄存器。在SD出厂之前,CID都被写入了唯一的值。

    通过READ_CID命令读取,只能读取,不能修改。

1.1.2 状态

    Card_Status存放在一个32位的状态寄存器中,作为卡中的一个数据域,返给主机。
    用SEND_STATUS命令读取。
    SD_Status存放在512位的数据块中,当收到主机的SD_STATUS(ACMD13)命令时发出。SD_STATUS包括扩展的与BUS_WIDTH相关的状态位。

1.1.3 存储分区

    SD卡存储的基本单元是BYTE,所有的数据操作都是通过BLOCK为单元进行。

        <1> BLOCK, 块。读写操作的最基本单元。块大小可以设置或固定。关于一块大小的数据存放在CSD寄存器中。
        <2> SECTOR,扇区。擦除操作的基本单元。扇区的大小是固定的。CSD中有相应说明。
        <3> WP Group,写保护组。它指可以用一位保护的组。大小在每都设备中都是固定的。CSD中有说明。

1.1.4 读写操作

    两种模式:单块,多块。

1.1.5 传送速率

    单线(DATA0):25Mbit/s
    四线(DATA0~3):100Mbit/s(12MB)

1.1.6 数据除错

    ECC,Error Correction Code。在数据写入时就会为每个扇区计算一个ECC。在读该扇区数据时,如果出现错误SD会在传给主机前纠正数据。

1.1.7 擦除

    sector是擦除的最小单元,一次性擦除多个扇所需的时间相同。第一个命令是擦除的start address,紧跟着是擦除的end address,那么这个区间的所有扇区都将会被擦除。

1.1.8 写保护

   

1.1.9 Copy bit

    在CSD寄存器的copy bit用于标志SD卡中,哪些内容是原始的,哪些是复制的。
    一旦某位被置1,那么不能清0了。
 

1.1.10 CSD寄存器

    SD卡中的所有配置信息都存储在CSD卡中。
    主机可以通过SEND_CSD命令读取CSD寄存器的值,也可以通过PROGRAM_CSD命令修改。
 

1.2 SPI 模式

1.2.1 工作条件

    OCR是operating condition寄存器。指定了SD卡在哪些状态下可以正常工作,哪些状态下进入非激活状态。

    READ_OCR(CMD58)命令。可以发送GO_INACTIVE命令进入非激活状态。

1.2.2 状态

    只有16位从32位的状态寄存器读出。该寄存器可以通过ACMD13读取。


2 接口特性

2.1 寄存器

 

寄存器列表
寄存器名 位长 说明
CID 128 SD卡唯一的识别码
RCA 16 相对地址(SPI不可见)
CSD 128 卡功能数据
SCR 64 SD卡配置寄存器
OCR 32 操作条件

 

     默认下,上电SD卡自动进入空闲状态。主机也可以发送GO_IDLE(CMD0)重位SD卡。

 

2.1.1 OCR

    指定SD卡的工作电压范围。(CMD1)

2.1.2 CID

    CID寄存器长16B,包含了唯一的卡识别码。其中的值在出产时已固定,不能被修改。
    注:SD卡与MMC卡的结构有所不同。

2.1.3 CSD

    CSD包含配置信息。
    注:SD卡与MMC卡的结构有所不同。

2.1.4 SCR

    SCR是CSD的扩展。也包含了部分配置信息。

2.1.5 状态寄存器

    SD卡支持两种卡状态域:

        <1> Card Status----(32bit)兼容MMC(MultiMediaCard)卡。
        <2> SD_Status----(512bit),在传给主机时附带CRC16。当SD卡收到ACMD13(CMD55+CMD13)命令后会发送该寄存器的值。

2.2 电气特性

2.2.1 上电

    上电或热插拔后,SD卡自动进入IDLE状态。在接收到ACMD41(ACMD类型命令发送之前要发送CMD55命令)之前,SD卡忽略所有指令。
    ACMD41是一种特殊的同步命令,用于判断是否在电压范围。如果不在操作电压范围,ACMD41的应答中包含busy位,以示SD卡还未准备好。主机必须等待busy位清0了才能进行下一步操作。busy位的等待时间不会超出1秒。

    在启动后,主机要在CMD线上发送初始化序列。不要超过1ms,74个时钟;再加上10同步时钟。

    主机都能够通过执行CMD1与ACMD41。CMD1用于询问MMC(MultiMediaCards)的操作条件。

 

3 总线协议

3.1 SD总线

    (略)

3.2 SPI总线

    与SD总线协议不同,SPI总线是以字节为单位进行通信,不需要起始位与结束位。

    主机数据传递都是通过CS位低开始。

    与SD总线不同之处有三:

        <1> 被选择(CS被拉低)的卡响应请求。
        <2> 使用8位或16位数据格式。
        <3> 当通信出错,SD卡会应答error,而不是像SD卡那样等待超时。

    在卡正在执行写操作时,向卡发送每一个数据块都会返回特定的响应标志。

3.2.1 模式选择

    SD卡唤醒后进入SD总线模式。如果CS信号线在应答命令CMD0时被拉低,那么就进入SPI模式。

    只有重新上电才能恢复SD总线模式。在SPI模式下,SD卡协议机制不可见。支持SPI模式的SD卡命令均可用。

    CRC校验默认在SPI模式下为关闭。

    CMD0是一个静态命令,CRC值为0x4A不变。CMD0命令完整的序列为:40 00 00 00 00 95

3.2.2 总线数据传递保护

    SPI接口默认下是无保护传输模式。主机可以通过CRC_ON_OFF(CMD59)命令打开或关闭此项。

 

3.3 协议功能

     本节主要描述SD卡的各个命令的功能与操作方法。

    SD卡发送两类命令:广播命令、点对点命令。

    SD卡有两种操作模式:卡识别模式、数据传输模式。

      <1> 卡识别模式,从卡复位到接收到SEND_RCA(CMD3),卡处于该模式。

      <2> 一旦卡的RCA确定了,就进入数据传输模式。

3.3.1 卡识别模式

    主机通过SD卡的CMD线发送(CMD3)命令告诉SD卡RCA(相对卡地址)。

3.3.1.1 复位

    复位,不论当前是什么状态,收到CMD0时,都会进入空闲状态。
    在上电后,在进行通信之前,CLK要给至少74个时钟,MOSI为高。

3.3.1.2 操作电压范围

    主机发送SEND_OP_COND(ACMD41)可以让SD卡发送OCR。由于ACMD41是应用命令,故在之前一定要发送CMD55。

    MMC不响应ACMD41,主要原因是MMC不识别CMD55。MMC中CMD1的功能与ACMD1等效。

    实际运用中,可以使用ACMD41与CMD1来区别当前卡是SD卡还是MMC卡。

    ACMD41应答中的busy位用于告诉主机当前还不能进行数据通信。因此,主机要重复发送ACMD41,直到busy位为0为止。

    GO_INACTIVE_STATE (CMD15) 可以将向已标记地址的卡转入非激活态。这个命令用于解除一张卡。

3.3.1.3 卡识别过程

    在总线被激活后,主机发送ACMD41(CMD55+CMD41)。
    主机发送CMD2获取每张卡的CID。SD卡进入卡识别状态。
    主机发送CMD3让SD卡公布新的相对地址RCA。相对地址比CID短,再在今后的通信中都会使用到。SD卡进入空闲状态。从此之后,如果主机要求更换SD卡的RCA,则再次发送CMD3即可。RCA以最后一次有准。

    MMC是用CMD2与CMD3实现上述过程。

3.3.2 数据传输模式

     主机发送CMD9获取CSD中的数据。

    CMD7用于在空闲状态传输状态下切换。当CMD7的RCA为0x0000时,所有的卡切换成空闲状态。

    <> 读操作。
         所有的读命令都可以通过CMD12取消。
         CMD17读单一块,CMD18读多块。写保护CMD30。ACMD51,CMD56。

    <> 写操作
          所有的写命令都可以通过CMD12取消。写命令以CMD7终止。
          块写(CMD24,CMD25),锁与解锁(CMD42),CMD56。
        

     (详见《SD卡说明》P61)

3.3.2.1 读格式

    读一块的大小定义在CSD (READ_BL_LEN)中。读出的数据块后都会跟一个CRC校验码。
    CMD17启动单块读操作,读完后自动回到传递状态。CMD18启动多块读操作,SD卡连续发送数据,直至收到停止命令。

3.3.2.2 写格式

     (CMD24—27,42,56(w))开启单个或多个块的写操作。主机向SD卡发送的数据都必须跟CRC校验码。SD卡允许的最小写单位为512B。
    在需要连续写入多块数据时,建议使用多块写入命令。对于小于512B的块写入是不允许的。

    当主机尝试向已保护的区域写数据时,SD卡不执行该操作,在状态寄存器上值WP_VIOLATION位,并忽略后面的操作。

3.3.2.3 预擦操作

    在执行多块写操作之前执行了预擦命令(ACMD23),告诉卡将要写入的块数。这样会让写速度更快。
    主机通过该命令告知SD卡,接下来将会写入多少块数据。如果主机在写操作实际没有写那么多块,那么剩下的块数据是不确定的。如果实际写入的大于预定的,那么卡将一块一块地擦除。

    建议使用CMD25命令,让多块写操作更快。

3.3.2.4 擦除

    (详见P64)

3.3.2.5 应用功能命令

(1)APP_CMD(CMD55)

    该命令会告诉卡,下一条命令是ACMD。

    在APP_CMD命令发送之后立即发送ACMD会导致APP_CMD命令被覆盖。应该等卡响应后方可。
    <1> 发送APP_CMD。应答中APP_CMD位置位,表示卡已准备好。
    <2> 发送ACMD。应答中APP_CMD位置位,否则该位清0。

    如果是非合法命令(不是ACMD也不是CMD),则卡会当作错误命令处理。

(2)GEN_CMD(CMD56)

    类似块读写命令(CMD24与CMD17)。

 

3.3.2.6 命令类型

    命令有以下四种类型:

    * 广播(bc)
    * 广播需要应答(bcr)
    * 点对点命令(ac)
    * 点对点数据传输命令(actr)

3.3.2.7 命令功能详解

    (详见《SD卡手册》P72)

序列 类型 参数 应答 缩写 功能
CMD0 bc ---- ---- GO_IDLE_STATE 复位卡到空闲状态
CMD2 bcr ---- R2 ALL_SEND_CID  
CMD3 bcr ---- R6 SEND_RELATIVE_ ADDR  
CMD9 ac [31:16] RCA R2 SEND_CSD  
CMD10 ac [31:16] RCA R2 SEND_CID  
CMD11 adtc [31:0] data address R1 READ_DAT_UNTIL_ STOP  
CMD12 ac ---- R1b STOP_ TRANSMISSION  
CMD13 ac [31:16] RCA R1 SEND_STATUS  
CMD15 ac [31:16] RCA -- GO_INACTIVE_ STATE  

读块

序列 类型 参数 应答 缩写 功能
CMD16 ac [31:0] block length R1 SET_BLOCKLEN  
CMD17 adtc [31:0] data address R1 READ_SINGLE_ BLOCK  
CMD18 adtc [31:0] data address R1 READ_MULTIPLE_BLOCK  

写块

序列 类型 参数 应答 缩写 功能
CMD24 adtc [31:0] data address R1 WRITE_BLOCK  
CMD25 adtc [31:0] data address R1 WRITE_MULTIPLE_ BLOCK  

 写保护

    CMD28,CMD29,CMD30

擦除

    CMD32,CMD33,CMD38

应用功能命令(CMD55+)

    以下不一一举列,

 

3.3.3 应答

 

学习总结

(标题5)

1. SD卡是怎么识别SD总线与SPI总线模式的?

    SD卡的CMD/MISO引脚在SD总线模式扮演CMD线,在SPI模式是MISO线。无论是什么模式,该脚都能接收数据。
    在SD卡上电后,SD卡并不知道自己处于什么通信模式。这并不防碍CMD/MISO脚输入数据。主机通过该脚发送CMD0命令。
    如果SD卡在应答CMD0命令时,CS引脚为低电平,则认为当前的通信模式为SPI总线模式。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SD卡学习笔记 的相关文章

  • 模块路径格式错误...第一个路径元素中缺少点

    我有一个包含 2 个不同可执行文件的项目 每个可执行文件都有自己的依赖项以及对根的共享依赖项 如下所示 Root gt server gt main go gt someOtherFiles go gt go mod gt go sum g
  • 限制 FormFile 中的文件大小

    我让用户使用 FormFile 上传文件 我应该在什么时候检查文件大小是否太大 当我做 file header fileErr r FormFile file 文件对象已经创建 那么我是否已经产生了读取整个文件的成本 https golan
  • 无法将字符串解组为 int64 类型的 Go 值

    我有结构 type tySurvey struct Id int64 json id omitempty Name string json name omitempty I do json Marshal在 HTML 页面中写入 JSON
  • Go 编程 - 使用指针绕过访问权限

    假设我的项目有以下层次结构 fragment fragment go main go 并且在fragment go我有以下代码 只有一个 getter 没有 setter package fragment type Fragment str
  • 如何使用 golang 和 mgo 库在 mongodb 中创建文本索引?

    我正在尝试对集合进行全文搜索 但为了做到这一点 我需要创建一个文本索引 http docs mongodb org manual tutorial create text index on multiple fields http docs
  • Google App Engine Golang 没有这样的文件或目录

    我正在用 Go 开发一个 Google App Engine 项目 并陷入了读取文件的困境 事实上 应用程序在本地运行得很好 然而 部署时 它会恐慌告诉我没有这样的文件或目录 这是我的 fileValue 方法 func fileValue
  • 使用 set /p 更新批处理脚本的变量始终包含最后一个值

    我正在尝试使用 set p 命令在循环内调整 Windows 批处理变量 键盘输入后 变量仍然包含旧值 我读到通过 set p 设置的变量仅具有本地范围 但我不明白 本地 在这里的真正含义 echo off setlocal EnableD
  • 数据库连接最佳实践

    我有一个使用 net http 的应用程序 我使用 http 注册了一些处理程序 这些处理程序需要从数据库中获取一些内容 然后才能继续编写响应并完成请求 我的问题是连接到该数据库的最佳实践是什么 我希望它能够以每分钟 1 个请求或每秒 10
  • 如何自定义解析错误的 HTTP 400 响应?

    我编写了一个 REST API 服务 要求所有响应均为 JSON 但是 当 Go HTTP 请求解析器遇到错误时 它会返回 400 作为纯文本响应 而不会调用我的处理程序 例子 gt curl i H Authorization Basic
  • go 中的属性更改通知

    如何在 go 中向多个接收器发出 属性 更改信号 类似于在 Qt 中使用通知信号定义属性的方式 例如 如果您想象有一些值需要以多种方式显示 例如进度值可以同时显示为进度条和文本 当基础值发生变化时 两者都需要更新 一种方法可能是利用chan
  • 当变量更新时动态刷新模板的一部分golang

    在Golang中 当变量更新时可以刷新模板的一部分吗 例如 我们可以在 Angular js 中找到这一点 基本上在我的代码中 我通过 ajax 中的邮政编码查找地址 它显示我找到的该邮政编码的用户列表 Here is a sample o
  • 如何在 Visual Studio Code 中为 Golang 启用竞争检测器?

    我搜索了很多网页来找到我应该放入哪个短语settings json在 VS Code Golang 扩展 由 Microsoft 发布 中添加构建标志 在我的例子中是竞赛检测器 I added go buildFlags race 在扩展名
  • Curl 不被识别为内部或外部命令、可运行程序或批处理文件

    我已经安装了curl并将其设置为environment variable在我的系统中 但是当运行curl命令它给出一个错误 curl is not recognized as an internal or external command
  • Go API 在 html 中显示 swagger api 规范 (json) (Swagger UI)

    我有一个服务于特定端口的应用程序 gorilla mux 我也有一个 json 文件形式的 swagger API 规范 是否有任何 go API 可以像 spring boot 一样从 JSON 文件生成 swagger UI 定义 我正
  • 如何在 Go 中表示可选字符串?

    我希望建模一个可以有两种可能形式的值 不存在或字符串 执行此操作的自然方法是Maybe String or Optional
  • 如何在 Windows 中增加 JVM 运行时内存

    我正在尝试通过命令行运行脚本 因为我正在使用以下命令 C apache jmeter 4 0 apache jmeter 4 0 bin gt jmeter f n t C apache jmeter 4 0 apache jmeter 4
  • 在处理程序之后访问 HTTP 请求上下文

    在我的日志记录中间件 链中的第一个 中 我需要访问一些在链下游的某些身份验证中间件中编写的上下文 并且仅在处理程序本身执行之后 旁注 需要首先调用日志记录中间件 因为我需要记录请求的持续时间 包括在中间件中花费的时间 此外 当权限不足时 身
  • 在golang中获取TTFB(第一个字节的时间)值

    我正在尝试获取 TTFB 值和 Connect 值 c exec Command curl w Connect time connect TTFB time starttransfer Total time time total o dev
  • Gorm 总是返回带有 nil 值的结构

    我正在使用 Gorm 构建 Go Web API 作为 Amazon RDS 中 Postgresql 数据库的 ORM 问题是 Gorm 总是返回一片结构 其值全部为零 尽管数据库已经填充了数据 切片中的结构体数量是否合适取决于LIMIT
  • 如何从非英语字符串解析go中的月份

    我想将以下字符串解析为 go 中的日期 This item will be released on March 9 2014 我跟着this https stackoverflow com questions 14106541 go par

随机推荐

  • C++中的++i 与 i++详解

    一 区别 i 与 i 的主要区别有两个 1 i 返回原来的值 i 返回加1后的值 2 i 不能作为左值 而 i 可以 二 原理 毫无疑问大家都知道第一点 我们重点说下第二点 首先解释下什么是左值与右值 通俗地说 以赋值符号 为界 左边的就是
  • CUDA小白 - NPP(6) 图像处理 Geometry Transforms (2)

    cuda小白 原始API链接 NPP GPU架构近些年也有不少的变化 具体的可以参考别的博主的介绍 都比较详细 还有一些cuda中的专有名词的含义 可以参考 详解CUDA的Context Stream Warp SM SP Kernel B
  • npm包的发布和删除

    登录npm发布包 1 终端 输入npm login 可以登录npm账号 依次输入用户名 密码 密码盲打 邮箱 2 输入nrm use npm通过命令更改npm服务 需将npm切换为npm官方服务 不能使用taobao镜像 注 可以通过npm
  • 基于虚拟机的集群冗余简化

    为了实现高可用性 企业使用中间软件例如微软和 Veritas 的集群软件 把两台服务器绑定在一个热备环境 即使运行在服务器上的应用程序有集群 感知能力 万一主服务器遭遇硬件或软件错误 这样的安排仍然会导致非应 用程序当机 冗余能消除单点失败
  • 面经——嵌入式软件工程师ARM体系与架构相关

    参考 嵌入式软件工程师笔试面试指南 ARM体系与架构 作者 嵌入式与Linux那些事 发布时间 2021 04 28 15 22 06 网址 https blog csdn net qq 16933601 article details 1
  • Windows下配置nginx+php(wnmp)

    Windows下配置nginx php wnmp waynewuzhenbo 博客园 http www cnblogs com wuzhenbo p 3493518 html Windows下配置nginx php wnmp 第一部分 准备
  • GraphPad Prism 9 for mac/win 安装教程

    GraphPad Prism集生物统计 化学统计 以及科技绘图于一身 其中医学所能用到的绘图需要它几乎都能满足 Prism 现在被各种生物学家以及社会和物理科学家广泛使用 超过110个国家的超过20万名科学家依靠 Prism 来分析 绘制和
  • 删除节点后从新加入的错误

    ERR Node 172 168 63 202 7001 is not empty Either the nodealready knows other nodes check with CLUSTER NODES or contains
  • Qt中绘制直线

    绘制多条直线 直接上代码 绘制直线的部分 QPen pen Qt lightGray 1 pen setStyle Qt DashDotDotLine pen setWidth 1 painter setPen pen painter tr
  • JVM【八股文】

    JVM 八股文 JVM内存区域划分 程序计数器 栈 堆 方法区 一块大的区域 需要根据功能 来划分不同的小区域 JVM内存是从操作系统里申请来的 之后堆这部分区域进行了划分 1 程序计数器 内存中最小的区域 保存了下一条要执行指令的地址 指
  • Spring 如何使用注解装配Bean呢?

    转自 Spring 如何使用注解装配Bean呢 我们都知道在Spring中 可以使用xml可实现 Bean状态操作 但是如果有非常多的Bean时 就会出现大量的xml 这样就会导致配置文件非常的大 并且容易出错及难维护 Java 从JDK5
  • PHP取整,四舍五入取整、向上取整、向下取整、小数截取。

    PHP取整数函数常用的四种方法 1 直接取整 舍弃小数 保留整数 intval 2 四舍五入取整 round 3 向上取整 有小数就加1 ceil 4 向下取整 floor 一 intval 对变数转成整数型态 intval如果是字符型的会
  • 迭代器iterator

    能进行算术运算的迭代器只有随即访问迭代器 要求容器元素存储在连续内存空间里 vector string deque的迭代器是有加减法的 但是map set multimap multiset的迭代器是没有加减法的 list也不可以
  • minio老版本集成到k8s的yaml

    apiVersion apps v1 kind StatefulSet metadata name minio spec replicas 1 serviceName minio selector matchLabels name mini
  • Android WebView使用详解及注意事项

    未经本人授权 不得转载 否则必将维权到底 目前很多公司的 App 就只使用一个 WebView 作为整体框架 App 中的所有内容全部使用 HTML5 进行展示 这样只需要写一次 HTML5 代码 就可以在 Android 和 iOS 平台
  • Android textAppearance的属性设置及TextView属性详解

    http blog csdn net jaycee110905 article details 8762238 textAppearance的属性设置 android textAppearance android attr textAppe
  • html实现蜂窝菜单

    效果图 CSS样式 keyframes fade in mkmxd 1 0 filter blur 20px opacity 0 to filter none opacity 1 keyframes drop in mkmxd 1 0 tr
  • 【图片+代码】:GCC 链接过程中的【重定位】过程分析

    目录 示例代码 sub o 文件内容分析 段信息 符号表信息 main o 文件分析 段信息 符号表信息 绝对寻址 相对寻址 重定位表信息 可执行程序 main 段信息 符号表信息 绝对地址重定位 相对地址重定位 总结 别人的经验 我们的阶
  • 看京东架构师如何解决,数据库读写分离与事务纠缠的坑

    本篇文章讨论在数据库读写分离时使用事务的那些坑 1 在读写分离时会不会造成事务主从切换错误 一个线程在Serivcie时Select时选择的是从库 DynamicDataSourceHolder中ThreadLocal对应线程存储的是sla
  • SD卡学习笔记

    每个sector为512B 与IDE磁盘一样 通过读写命令读取一个多个sector 主控程序不需要关注SD具体是怎么实现读写与擦写的 每个sector可以耐受100 000次写操作 无限次读操作 每当sector被用命令erase命令擦除了