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卡学习笔记 的相关文章

  • 跳出选择循环?

    我正在尝试使用select在循环中接收消息或超时信号 如果收到超时信号 则循环应中止 package main import fmt time func main done time After 1 time Millisecond num
  • 使用Golang登录私有站点并提取信息

    我尝试使用 golang 登录网站的私人区域并提取一些信息 但我似乎不太正确 我设法获取登录页面以获取 csrf 令牌 然后将 csrf 令牌与登录信息一起发布到登录页面 然后我就可以正常登录了 如果我在此时停止 我可以看到我被重定向的页面
  • 无法以管理员身份运行

    我必须执行ewfmgr exe仅当以管理员身份打开命令窗口时才能执行 如果我去Start gt type cmd exe gt Right click gt Run as Administrator然后出现以下命令提示符窗口 在这个窗口中
  • 在 Windows 上安装 gokogiri 时找不到错误 libxml2

    我正在尝试安装gokogiri https github com moovweb gokogiri在 Windows 8 机器上按照 github 页面中的说明进行操作 安装 sudo apt get install libxml2 dev
  • 如何在golang中$push嵌套数组?

    我尝试使用以下方法将一些数据推送到嵌套数组中 push 这是我的 json 文件 id ObjectId 57307906f051147d5317984e user firstName chetan lastName kumar age 2
  • 如何在不使用依赖注入的情况下模拟另一个包中的函数?

    有点像 golang 初学者 但我以前曾使用过测试框架 如何在不注入依赖项的情况下模拟和伪造依赖方法返回的内容 我不想使用依赖项注入的原因是因为正在使用许多外部包方法 并且在构造函数中注入所有方法很麻烦 我已经在线 stackoverflo
  • Powershell命令:rm -rf

    rm是删除item 但是参数是多少 rf做或表示 每当我输入 help rf 时 它都会打印 powershell 中可用命令的完整列表 如果您输入会发生什么rm rf在 powershell 中 通过阅读周围的资料 我发现它会删除驱动器上
  • golang 交换两个数字

    我正在尝试了解 Go 的内部结构 考虑下面的代码 a b 10 5 b a a b 上面的代码完美地交换了 2 个数字 a 变成了 5 b 变成了 10 我无法理解这是如何工作的 考虑到第二行代码 如果a先分配给b 那么b将是10 现在 如
  • 多个docker容器日志

    我试图一次从多个 Docker 容器获取日志 顺序无关紧要 这将按预期工作 如果types ContainerLogsOption Follow设置为 false If types ContainerLogsOption Follow设置为
  • 启动套接字服务器会干扰 gRPC/http 客户端服务器通信 Golang

    我有一个很大程度上基于此的服务器tutorial https www golinuxcloud com go grpc crud api postgresql db 在我对其应用了额外的更改后 它工作得很好 但现在我想添加socket io
  • 命令提示符中的代码在批处理文件中不起作用

    当我在命令提示符中执行下面的代码时 它会执行我想要的操作 但当我将其放入 bat 文件并尝试执行它时 它不会执行我想要的操作 for f a in dir b csv do for f tokens b in a do echo b a g
  • Gorilla mux,“捕获”响应代码的最佳方式

    我所有的路由都使用 Gorilla mux 现在我的应用程序工作正常 我想找到一种方法将我的所有响应代码记录到 例如 statds 我找到了这个包 https godoc org github com gorilla handlers Lo
  • 将 nil 字符串指针设置为空字符串

    如何将类型中字符串指针的引用值设置为空字符串 考虑这个例子 package main import fmt type Test struct value string func main t Test nil if t value nil
  • 为什么net.DialTimeout一半的时候会超时?

    这是我的测试代码 我设置了6s超时 但是程序只执行了3s 为什么 package main import net import time import fmt func main fmt Println time Now conn err
  • 代理 golang https

    我正在努力让一个人进来https www google com https www google com使用带有身份验证的代理 我已经传递了标头参数 代理授权 但代理服务器返回 需要代理身份验证 code package main impo
  • ERRORLEVEL 与 %ERRORLEVEL% 与感叹号 ERRORLEVEL 感叹号

    我想我对 ERRORLEVEL 与 ERRORLEVEL 有基本的了解 但是 ERRORLEVEL 让我困惑 我正在制作一个调用可执行文件的脚本 然后使用任务列表来查看它是否正在运行 然后使用taskkill来杀死它 如果是 然后尝试输出错
  • 在 Go 中设置引用

    如何通过引用传递接口并让方法为我填充它 像这样的东西 var i CustomInterface Get title ref i i SomeOperationWithoutTypeAssertion i is nil here my pr
  • Go(lang): 如何使用 PPROF 堆分析来查找内存泄漏?

    我正在尝试使用 pprof 来验证内存泄漏 能否解释一下如何读取您在以下位置找到的堆配置文件 http localhost 6060 debug pprof heap debug 1 另外 通过键入web启动后命令go tool pprof
  • 指定共享对象(共享库)的名称

    Go 编译器为共享对象生成的名称是错误的 例子 go install buildmode shared linkshared github com apache thrift lib go thrift code google com p
  • RuntimeError:使用 docker 关闭连接后无法重用套接字

    我正在关注本教程 https github com getamis eth indexer blob master README md fbclid IwAR3g3SAjJ9ik hHCFkol2k8YXo0GvBL15oSNC hIU38

随机推荐

  • 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命令擦除了