安全数字输入/输出接口SDIO

SDIO框图

需要总体去浏览sd2.0协议的手册,大概了解每个章节写了什么,再看sd卡功能描述--》再看命令--》再看响应,响应对应的数据位---》响应对应的寄存器或者响应的Rx x==1、2、3、4、5、6

安全数字输入/输出接口SDIO_第1张图片

APB2对于F407来说等于168M/2=84M;

APB2等于PCLK2:提供给适配器寄存器和FIFO使用

SDIOCLK等于PCLK2:控制单元、命令路径、数据路径使用

SDIO_CK:提供给sd卡的时钟;通过SDIO_CLKCR时钟控制寄存器配置可得;公式如下 

一些观察:状态位等一些和响应都通过SDIO响应寄存器得到;

SD卡2.0协议

只做一些关键性的东西记录;其他细节略;

cmd线:命令和响应都靠这根线;0开始,1结束。所以可以配置上拉

dat线:数据线,空闲为高

使用命令前的SDIO配置(补充)

1、配置SDIO时钟

初始化时钟在2.0协议中配置为400k

配置时钟触发源

配置SD卡时钟源

配置数据线:1位数据线通用,支持卡多;

2、电源控制寄存器开启电源

3、使能sdio卡时钟

sd协议讲的操作(使用命令),在协议手册的第四章sd卡的功能描述:

SD卡识别操作流程 

fod卡识别模式的频率=400k

安全数字输入/输出接口SDIO_第2张图片

描述关键的信息,其他细节观察流程图;

  • 上电卡进入idel状态,发送cmd0进行软复位;
  • 操作前先发送cmd8操作条件确认:确认电压,有响应发给卡收到表明主机支持2.0协议
  • 发送CMD55让下个命令为ACMD再发送ACMD41:识别是否符合主机规定的VDD范围的卡             1、通过设置 ACMD41 的参数里面 OCR(工作电压范围)的值为 0,主机可以查询每张         卡,  并且确定通用电压范围,初始化之前不能这样用;

              2、ACMD41响应的ccs位中为1则表示SD卡为高容量卡;否则为普通SD卡

  • 再发送cmd2请求卡CID号:响应发送卡的CID号;进入识别状态
  • 发送cmd3请求卡的新相对地址:响应发送新的相对地址RCA,作为数据传输模式的地址;主机进入到stand by等待状态;

更详细的卡识别和初始化流程

安全数字输入/输出接口SDIO_第3张图片

初始化的详细操作:

如下命令按顺序操作:并且有命令且有对应的响应;所有有响应的需要做计数等待溢出,溢出后没有响应都算卡错误;

cmd0

目的:软复位

4.7.2章的详细命令描述

 无响应,复位所有的卡;

cmd8

主要目的:有响应,卡支持sd2.0协议,否则为SD2.0之下或者mac卡;带参数:参数在2.0协议的4.3.13章节发送接口命令条件说明;推荐参数 0x1AA, 其中检查模式文中推荐AA,电压支持0x01;所以参数0x1AA

4.7.2章的详细命令描述

4.9.6章节的,R7响应

安全数字输入/输出接口SDIO_第4张图片

 cmd55

目标:在卡识别的流程图看到需要发送ACMD41,在发送之前应该发送CMD55,使得下个命令可以发送AMCD41;原文如下,4.2.2章节;并且在 4.7.2章的详细命令描述也重复提到ACMD使用之前,应该发送CMD55;

安全数字输入/输出接口SDIO_第5张图片

 4.7.2章的详细命令描述,如下为简要解析:该命令详细使用在4.3.9章节

 4.9.6章节的,R1响应安全数字输入/输出接口SDIO_第6张图片

acmd41

主要目标:响应就属于sd卡不响应就属于mac卡;区分SD和MAC卡;

 4.7.2章的详细命令描述

安全数字输入/输出接口SDIO_第7张图片

 返回OCR寄存器:寄存器如下

安全数字输入/输出接口SDIO_第8张图片

 可以知道30、31位可以读取到卡的卡容量和卡上电状态;ACMD41之后响应中可以读取到卡容量和卡上电状态;

CMD2

目标:返回卡的CID;

 4.7.2章的详细命令描述

 4.9.6章节的,R2响应

安全数字输入/输出接口SDIO_第9张图片

CMD3

目标:让卡发布重新RCA相对地址;

  4.7.2章的详细命令描述

 4.9.6章节的,R6响应

安全数字输入/输出接口SDIO_第10张图片

2.0协议手册的的4.10.1章节的表4-36部分;

 安全数字输入/输出接口SDIO_第11张图片

安全数字输入/输出接口SDIO_第12张图片

程序要检查19、22、23位是否发生错误;

获取卡信息

CMD9

目标:获取卡信息,CSD寄存器

  4.7.2章的详细命令描述

 4.9.6章节的,R2响应

 安全数字输入/输出接口SDIO_第13张图片

 安全数字输入/输出接口SDIO_第14张图片

 选中卡

 CMD7

目标: 通过相对地址RCA选中卡;

  4.7.2章的详细命令描述

安全数字输入/输出接口SDIO_第15张图片

 4.9.6章节的,R1响应

安全数字输入/输出接口SDIO_第16张图片

卡状态在2.0协议手册的4.10.1,这里略;

在stm32f4的28.9.6中,如果设置为短响应,那么返回的RESP1寄存器应该是32宽度的卡状态,所以不会是整个R1寄存器48位返回到主机,而是只有8-39的状态位;

获取SD卡信息

在使用CMD2之后可以在获取到CID:

卡的CID寄存器如下;

安全数字输入/输出接口SDIO_第17张图片

CMD2之后可以在SDIO响应1234寄存器可以读取到CID:

传输数据位高位到低位:每个SDIO响应寄存器32位宽度,所以有:

      SDIO响应寄存器[0]  CID 127--96         
      SDIO响应寄存器[1]  CID 95--64           
      SDIO响应寄存器[2]  CID 63--32                            
      SDIO响应寄存器[3]  CID 31--0           

使用CMD9之后可以获得CSD寄存器;  

CSD寄存器如下:

安全数字输入/输出接口SDIO_第18张图片

 安全数字输入/输出接口SDIO_第19张图片

CMD9之后可以在SDIO响应1234寄存器可以读取到CSD:

传输数据位高位到低位:每个SDIO响应寄存器32位宽度,所以有:

      SDIO响应寄存器[0]  CSD127--96         
      SDIO响应寄存器[1]  CSD95--64           
      SDIO响应寄存器[2]  CSD63--32                            
      SDIO响应寄存器[3]  CSD31--0 

总线宽度选择

总线宽度选择,需要判断通过cmd9,获取的响应判断位25卡锁定状态,卡没有被锁定,就可以改变总线;

获取当前卡支持的总线数据宽度

在卡寄存器SCR中可以,找到;所以要读取卡的SCR寄存器;如下顺序命令操作;

CMD16

目标:设置块长度,因为要面向块的操作;需要先设置块;

  4.7.2章的详细命令描述

安全数字输入/输出接口SDIO_第20张图片

  4.9.6章节的,R1响应

安全数字输入/输出接口SDIO_第21张图片

主机设置长度块大小

在设置卡的块大小后,发送ACDM51之前也可以把主机的SDIO数据控制寄存器也进行相应的长度和块设置,应该是SCR比较特殊?只能用块FIFO传输;

cmd55

为了发送ACMD命令

ACMD51

前提:发送ACDM51之前把主机的SDIO数据控制寄存器也进行相应的长度和块设置;

目标:读取卡SCR寄存器;

   4.7.2章的详细命令描述

 

 响应R1略:

短响应,RESP1只有状态位32宽;

读取SCR需要进行FIFO读取:

 /*  因为fifo传输是按字节来传输,不像响应一样按照32位,字传输,所以FIFO:先传的是高字节进来像数组一样组成32位,组成一个字;所以最高字节在字的的前八位;
        然后四个字节组成一个字,再到下一个字;在列程序是这样操作;
 */    

CMD55

此时可以带参数RCA卡相对地址,表明下一条为ACMD外,还使用RCA表明那张卡操作;

ACMD6

读到SCR之后,进行判断宽位支持,支持就进行发送ACMD,带参数宽度,

ACMD6进行修改卡总线宽;

附上SCR寄存器,详细解析在2.0协议中的5.3章节中

安全数字输入/输出接口SDIO_第22张图片

主机使能宽度允许

SDIO_CLKCR寄存器中;

时钟供给配置

在SDIO_CLKCR寄存器中

SDIO_CK 频率 = SDIOCLK / [CLKDIV + 2]。

在stmf4手册看到框图SDIOCLK =APB2:

APB2是多少,可以从工程文件中的启动文件中找到,上电默认84M

stm32的一些技巧+小总结_qq_36658033的博客-CSDN博客

参考 APB2默认分频查找

SD卡传输模式流程

fpp数据传输模式时钟频率25M

安全数字输入/输出接口SDIO_第23张图片

 cmd3命令后进入传输模式,cmd0和cmd15都可以返回到卡识别模式;

  • 发送cmd9获取卡的具体数据:块长度、存储容量、传输模式的状态;
  • 发送cmd4:根据总线上卡的数量,数据传输频率,配置它们的DSR寄存器;同时频率从400k识别,到数据传输的25M;
  • cmd7选中一张卡进入传输模式,带参数相对地址RCA,其他卡进入等待stand by状态;

各种数据传输模式的关系总结如下:2.0协议的4.3章节,略

读数据

读取数据分为单块和多块读;

单块读取

cmd17

目标:读取一个块;

安全数字输入/输出接口SDIO_第24张图片

 响应是R1,短响应返回32位宽状态,略;

实际操作

1、数据控制寄存器清零

2、判断上个命令的响应返回的卡状态,卡锁不可以读;

3、校验块大小数据,需要是2的幂

4、cmd16给卡设置块大小,并响应正确;

6、设置主机块大小

7、cmd17发送读取块命令,附带单元地址,512个字节一个单元

8.1轮询接收

  •   8.1.0关中断,为了其他中断不影响
  •   8.1.1 查询SIDO_STA寄存器的:上溢/CRC/超时/完成(标志)/起始位错误,进行循环查询,直到以上错误或者完成传输;
  •   8.1.2 轮询接收半满状态,就接收8个字
  •  知识点:SDIO的fifo宽为32,深度为32,也就是32个字FIFO,其中包括收发的。所以接收满是16个字;
  •   8.1.3计数超时,接收设置超时,不接收时候计时减减;
  •   8.1.4退出轮询后,错误状态解析,查询是否有fifo还有小于8字节的数据,有就接收;
  • 开中断

8.2DMA接收

  • 配置需要的中断  数据CRC失败 、数据超时 、数据块结束、结束上益、起始位错误
  •  SDIO DMA使能 ,配置DMA,数据方向,数据块大小(接收的字数)等,
  • 直到DMA数据块传输结束;或者超时;

多块读取

cmd18

目标:读取多个块,直到cmd12停止;

 实际操作

1、这与单块读取的实际操作的1-5都相同;校验长度不得超过SDIO数据长度寄存器的值;且长度为块大小的倍数

2、主机设置的块大小,以及块大小*块数的长度;

3、cmd18开始多块传输,带参数扇区地址(大容量卡一个单元512字节),直到cmd12结束,

4.1轮询接收

  •   4.1.0关中断,为了其他中断不影响
  •   4.1.1 查询SIDO_STA寄存器的:上溢/CRC/超时/完成(标志)/起始位错误,进行循环查询,直到以上错误或者完成传输;
  •   4.1.2 轮询接收半满状态,就接收8个字。
  •  知识点:SDIO的fifo宽为32,深度为32,也就是32个字FIFO,其中包括收发的。所以接收满是16个字;
  •   4.1.3计数超时,接收设置超时,不接收时候计时减减;
  •   4.1.4退出轮询后,错误状态解析,查询是否有fifo还有小于8字节的数据,有就接收;
  • 4.1.5数据完成标记位,和主机设置的长度参数有关;但是仍然在读数据,这时候需要cmd12命令停止读取;发送cmd12
  • 开中断,清除sdio所有标志位;

5.1DMA传输

  • 与单款读取操作一样,就是配置的dma长度参数==块*块数(即长度)
  • SDIO中断函数中,加上如果SDIO传输完成,发送cmd12结束传输;以及需要正确响应;这里考虑,有没有不占用查询状态时间的CDM12响应;(命令响应接收中断
  • 附加:也可以考虑DMA完成中断之类的;

写数据

没有数据传输dat总线拉高;

块长度和RCA错误时读命令不能执行;

cmd13

目标:让卡进入发送状态

R1响应略

cmd24一个块传输

cmd25 多个块传输,直到cmd12命令后才停止

安全数字输入/输出接口SDIO_第25张图片

 R1响应略,R1中有返回的卡状态,详情在SD2.0协议中文手册的4.9章节

cmd12 次命令后多块传输才会停止

命令详情略;

单块写

实际操作

1、清空数据控制寄存器

2、清除状态机配置

3、判断锁卡状态,锁卡无法操作

4、校验块大小,应该为2的幂;设置发送cmd16,带参数块的大小,设置卡的块大小

5、发送cmd13使得卡进入发送状态,查卡状态,R1响应,取得卡的状态,直到非空闲状态,进入发送态

6、主机设置块大小,长度等;

7、轮询发送

   7.1 进入轮询   //数据块发送成功/下溢/CRC/超时/起始位错误  这些条件真则退出轮询体

   7.2查询传输FIFO没半空,至少可以写入8个字

   7.3 如果不够8个字,计算剩余的字长度,如果多出一个字节,字节,不是字,那么就增加一个发送字的长度;把数据送给发送fifo

     如果够8个字,那么就把8个字直接放到发送fifo中

8、DMA发送

  • 配置需要的中断  数据CRC失败 、数据超时 、数据块结束、结束上益、起始位错误
  •  SDIO DMA使能 ,配置DMA,数据方向,数据块大小(接收的字数)等,
  • 直到DMA数据块传输结束;或者超时;

多块写

CMD23

带参数,块数量

目标:设置块数量;

CMD25

目标:开始多块传输

CMD12

中断有有cmd12指令停止传输

实际操作:

1、清空数据控制寄存器

2、清除状态机配置

3、判断锁卡状态,锁卡无法操作

4、校验块大小,应该为2的幂;设置发送cmd16,带参数块的大小,设置卡的块大小

5、CMD23、CMD25

6、主机设置块大小,长度等

7、轮询发送

  • //下溢/CRC/数据结束/超时/起始位错误,退出轮询体
  • 发送fifo不够8字发送。并且按照4字节送进一个FIFO,不够4字节的按照一个字,一个字送进fifo;
  • 够8字,直接把8个放进fifo中;
  • 超时计数

8、DMA发送

  • 配置需要的中断  数据CRC失败 、数据超时 、数据块结束、结束上益、起始位错误
  •  SDIO DMA使能 ,配置DMA,数据方向,数据块大小(接收的字数)等,
  • 直到DMA数据块传输结束;传输完成中断,发送CMD12结束传输;
  • 超时计数;

你可能感兴趣的:(单片机,c++,stm32,嵌入式硬件,笔记)