SDIO、SD卡和FATFS文件系统理解

### 一、SDIO接口协议定义说明 #### 1.1 介绍 SDIO 是基于SD标准开发的一种外设接口,其接口定义主要**有时钟线**、**命令/响应线**和**数据线**,数据线分为1位、4位和8位,**半双工通信方式**,可以与MMC(多媒体卡,Mutiny Media Card )卡、SD存储卡和SDIO卡通信。 ![在这里插入图片描述/](https://img-blog.csdnimg.cn/2021061117330754.png#pic_center) 与SD卡和SD IO卡的通信速率(卡时钟)可以设置在0-25MHZ,与MMC卡(V4.0以上)的通信速率可以设置在0-48MHZ,(V3.3以下的设置在0-20Mhz) - SDIO_CK:卡时钟是用来和外部卡进行数据交互的时钟,SDIO_CK = SDIOCLK/(2+CLKDIV) - CLKDIV:分频系数 - SDIOCLK:数据通道到以及控制单元的时钟,用来产生卡时钟 - HCLK/2:寄存器和FIFO的时钟。 ![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611173330206.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)#### 1.2 通信过程 通过**命令线去发送指令**,同样**通过命令线接收响应**,这种类似于IIC通过并转串然后将数据1bit1bit发出来,先传输高位MSB,再传输低位LSB ![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611173411838.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) 如果是多字节传输,先**传输低字节**,后**传输高字节**,低字节在**低数据总线**,高字节在**高数据总线**。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611173432497.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) ![在这里插入图片描述](https://img-blog.csdnimg.cn/2021061117345750.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) 如果是宽字节传输,同样是高位先传输,低位后传输, ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611173515387.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) 如下图所示,可以看到CMD线通过移位寄存器将串行数据接收回来,同样之后会进行CRC校验(硬件),再然后会存入到寄存器中。 ![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611173534317.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) 命令传输过程:中间会有等待状态,发送命令时是有控制器驱动,响应的时候是由卡来驱动。 ![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611173650148.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) 数据线说明:寄存器可以配置数据总线宽度,如果位宽没有限制,只是在SDIO_D0上面有传输,其中FIFO缓存空间是128个字节(32个字,每个字为4字节), ![在这里插入图片描述](https://img-blog.csdnimg.cn/2021061117372555.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) SDIO的有响应操作和无响应操作(比如广播) ![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611173755309.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) 如果是读操作和写操作,则需要有数据线去参与。在进行写操作的时候需要注意判断卡处于繁忙状态,不会被写入数据,最后需要发送停止数据传输 指令。 ![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611173821513.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611173835659.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) 此外也可以进行连续读和连续写操作,即流操作,数据末尾没有CRC校验码,只适用于**多媒体卡** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611173858272.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611173908414.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) #### 1.3 通信协议 (命令格式:发送,**传输位为1**) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611173934564.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) 命令格式:接收(长响应和短响应,**传输位为0**) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611173951898.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) 具体的命令举例说明:见指令表及程序代码。 ### 二、SD卡/SD IO卡/MMC卡 #### 2.1 SD卡 ##### SD卡类型 - 标准卡,内存在2GB(2^31 bytes)以内, - 大容量卡(2GB``` for(i=0;i<74;i++) { SDIO_CmdInitStructure.SDIO_Argument = 0x0;//发送CMD0进入IDLE STAGE模式命令. SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_GO_IDLE_STATE; //cmd0 SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_No; //无响应 SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; //则CPSM在开始发送命令之前等待数据传输结束。 SDIO_SendCommand(&SDIO_CmdInitStructure); //写命令进命令寄存器 errorstatus=CmdError(); //判断是否发送成功 if(errorstatus==SD_OK)break; } if(errorstatus)return errorstatus;//返回错误状态 SD_Error CmdError(void) { SD_Error errorstatus = SD_OK; u32 timeout=SDIO_CMD0TIMEOUT; while(timeout--) { if(SDIO_GetFlagStatus(SDIO_FLAG_CMDSENT) != RESET)break; //命令已发送(无需响应) } if(timeout==0)return SD_CMD_RSP_TIMEOUT; SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记 return errorstatus; } ``` ``` ![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174134326.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)CMD寄存器变为400,代表指令0,不需要响应。1000 0000 之后发送CMD8,检查SD卡接口电压, ```
```
  SDIO_CmdInitStructure.SDIO_Argument = SD_CHECK_PATTERN;    //发送CMD8,短响应,检查SD卡接口特性
  SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_IF_COND;    //cmd8
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;     //r7
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;             //关闭等待中断
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);
  errorstatus=CmdResp7Error();                        //等待R7响应
  if(errorstatus==SD_OK)                                 //R7响应正常
  {
      CardType=SDIO_STD_CAPACITY_SD_CARD_V2_0;        //SD 2.0卡
      SDType=SD_HIGH_CAPACITY;                        //高容量卡
  }
  SD_Error CmdResp7Error(void)
  {
      SD_Error errorstatus=SD_OK;
      u32 status;
      u32 timeout=SDIO_CMD0TIMEOUT;
       while(timeout--)
      {
          status=SDIO->STA;
          if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功)   
      }
       if((timeout==0)||(status&(1<<2)))   //响应超时
      {                                                                                   
          errorstatus=SD_CMD_RSP_TIMEOUT; //当前卡不是2.0兼容卡,或者不支持设定的电压范围
          SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);             //清除命令响应超时标志
          return errorstatus;
      }    
      if(status&1<<6)                     //成功接收到响应
      {                                  
          errorstatus=SD_OK;
          SDIO_ClearFlag(SDIO_FLAG_CMDREND);              //清除响应标志
       }
      return errorstatus;
  }       
```
```
![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174147843.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) CMD寄存器变为448,10001001000,前六位代表指令8,01代表短响应,100代表使能CPSM状态机,进入空闲状态,响应时R7响应,收到响应,代表支持该电压范围,如果超时,则不是2.0卡或者不支持电压范围。ARG寄存器为发送的参数,1AA 代表检查。。。?
 第6位为1,则代表接收响应成功,其他则代表失败
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611174230323.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)
 之后发送CMD55,代表下一条指令是应用指令。
```
```
  SDIO_CmdInitStructure.SDIO_Argument = 0x00;//发送CMD55,短响应    
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);        //发送CMD55,短响应    
  errorstatus=CmdResp1Error(SD_CMD_APP_CMD);             //等待R1响应
  errorstatus=CmdResp1Error(SD_CMD_APP_CMD);         //等待R1响应   
  if(errorstatus!=SD_OK)return errorstatus;       //响应错误
```
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611174245737.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)
CMD寄存器变为477,10001 110111,前6位为55,01则为短响应,100使能CPSM状态机
 接下来发送ACMD41指令,判断SD卡是否为大容量卡,不支持CMD55指令的卡为MMC卡,469,100 01 101001 41指令,短响应
![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174258855.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)```
<pre class="wp-block-code">```
  SDIO_CmdInitStructure.SDIO_Argument = SD_VOLTAGE_WINDOW_SD | SDType;    //发送ACMD41,短响应  
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SD_APP_OP_COND;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;  //r3
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);
  errorstatus=CmdResp3Error();                     //等待R3响应
  response=SDIO->RESP1;;                            //得到响应
  if(response&=SD_HIGH_CAPACITY)     //SD_HIGH_CAPCITY = 0x400 0000
  {
      CardType=SDIO_HIGH_CAPACITY_SD_CARD;  //支持大容量卡
  }
```
```
 OCR寄存器各位定义,倒数第二位是容量卡定义。
![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174314336.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center) 再之后是CMD2和CMD3指令,CMD2获取SD卡信息,4C2 100 11 000010 指令码为2,11为长响应。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611174331476.jpg#pic_center)
```
```
  SDIO_CmdInitStructure.SDIO_Argument = 0x0;//发送CMD2,取得CID,长响应
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_ALL_SEND_CID;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);//发送CMD2,取得CID,长响应      128位
  errorstatus=CmdResp2Error();                     //等待R2响应   
  if(errorstatus!=SD_OK)return errorstatus;       //响应错误          
  CID_Tab[0]=SDIO->RESP1;
  CID_Tab[1]=SDIO->RESP2;
  CID_Tab[2]=SDIO->RESP3;
  CID_Tab[3]=SDIO->RESP4;
```
```
 CID寄存器定义,Manufacture ID = 0x27 = 39.
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611174348672.png#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611174827140.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)
- 数据传输模式: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611174359391.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)
 通过CMD9可以获取CSD寄存器数据,比如块长度,块存储容量等。CMD4指令可以配置总线布局以及卡的数量,之后时钟频率从初始化频率的不大于400K,调节到10-25M这个数据传输频段。
```
```
  RCA = rca;
  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)(rca << 16);//发送CMD9+卡RCA,取得CSD,长响应 
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_CSD;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);
  errorstatus=CmdResp2Error();                     //等待R2响应   
  if(errorstatus!=SD_OK)return errorstatus;       //响应错误          
  CSD_Tab[0]=SDIO->RESP1;
  CSD_Tab[1]=SDIO->RESP2;
  CSD_Tab[2]=SDIO->RESP3;                        
  CSD_Tab[3]=SDIO->RESP4;    
```
```
 CMD7指令可以配置卡进入传输数据状态,但是同时只有一个卡进入传输数据状态,同时发送默认地址0x00,也可以使得卡退出传输状态,重新进入旁路状态。地址由RCA决定,因为在高16位,所以读取的RCA地址需要左移16位,才可以选中该卡 通过RCA来区分各个卡的地址。
```
```
  SDIO_CmdInitStructure.SDIO_Argument =  addr;//发送CMD7,选择卡,短响应    
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEL_DESEL_CARD;//cmd7
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);//发送CMD7,选择卡,短响应
  return CmdResp1Error(SD_CMD_SEL_DESEL_CARD);     
```
```
 读写之前的一些操作指令:CMD16设置读写块的大小,一次读多少个字节,CMD32,CMD33,擦除开始和擦除结束指令,ACMD6,设置总线数据宽度,(1bit 4bit 8bit),ACMD23,设置即将擦除块的大小等,ACMD42设置或者清除50K欧姆的上拉电阻。
```
```
  SDIO_CmdInitStructure.SDIO_Argument =  blksize;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);//发送CMD16+设置数据长度为blksize,短响应
  errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN);    //等待R1响应  
```
```
```
```
  SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;//发送CMD13,查询卡的状态,短响应     
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);    
  errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS);        //等待R1响应 
```
```
```
```
  SDIO_CmdInitStructure.SDIO_Argument =nblks;        //发送CMD23,设置块数量,短响应      
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCK_COUNT;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);
  errorstatus=CmdResp1Error(SD_CMD_SET_BLOCK_COUNT);//等待R1响应 
```
```
 写数据块:CMD24(单块写入):写入一个块的大小,在标准容量卡有效,大容量卡,固定512字节。CMD25(多块写入):直到CMD12 停止写入指令。
CMD42:上锁或者解锁,设置密码或者复位密码。CMD56:主机设置读卡或者写卡。
CMD254单块写入
```
```
  SDIO_CmdInitStructure.SDIO_Argument = addr;//发送CMD24,写单块指令,短响应     
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);    
  errorstatus=CmdResp1Error(SD_CMD_WRITE_SINGLE_BLOCK);//等待R1响应 
  StopCondition=0;                                    //单块写,不需要发送停止传输指令 
  SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4; ;    //blksize, 控制器到卡    
  SDIO_DataInitStructure.SDIO_DataLength= blksize ;
  SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
  SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  SDIO_DataConfig(&SDIO_DataInitStructure);
```
```
CMD25 多块写入
```
```
  SDIO_CmdInitStructure.SDIO_Argument =addr;    //发送CMD25,多块写指令,短响应       
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);    
  errorstatus=CmdResp1Error(SD_CMD_WRITE_MULT_BLOCK);    //等待R1响应           
  if(errorstatus!=SD_OK)return errorstatus;
  SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4; ;    //blksize, 控制器到卡    
  SDIO_DataInitStructure.SDIO_DataLength= nblks*blksize ;
  SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
  SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  SDIO_DataConfig(&SDIO_DataInitStructure);
```
```
CMD12 停止写入。
```
```
  SDIO_CmdInitStructure.SDIO_Argument =0;//发送CMD12+结束传输       
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_STOP_TRANSMISSION;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);    
  errorstatus=CmdResp1Error(SD_CMD_STOP_TRANSMISSION);//等待R1响应   
  if(errorstatus!=SD_OK)return errorstatus;     
```
```
 读数据块:CMD17读单个块,CMD18读多个块,CMD30,写保护,大容量卡 不支持改指令。ACMD13:发送卡状态,ACMD:22:发送写入块的数量,ACMD51:读取SCR寄存器内容。
```
```
  SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4 ;//配置读取的数据个数
  SDIO_DataInitStructure.SDIO_DataLength= blksize ;
  SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToSDIO;
  SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  SDIO_DataConfig(&SDIO_DataInitStructure);
  SDIO_CmdInitStructure.SDIO_Argument =  addr;   //参数
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_READ_SINGLE_BLOCK;  //指令码
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);//发送CMD17+从addr地址出读取数据,短响应 
```
```
##### 各指令定义表。
![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174425133.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174445397.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174454474.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174504414.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174512495.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174520398.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174534521.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174542865.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174554760.png#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174604289.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174622166.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174633112.png#pic_center)![在这里插入图片描述/](https://img-blog.csdnimg.cn/20210611174641127.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)#### 2.2 SD I/O卡
 SDIO卡就是支持SDIO接口的卡,其卡的功能多种多样,比如支持WIFI或者BlueTooth等,SDIO卡和SD存储卡是兼容的,在机械、电气指令和软件上面,SDIO卡对于移动电子设备,提供了一个高速度的数据传输,可以作为SIOD设备被识别。
SDIO卡分为两种:高速和低速。
- 高速:支持SPI模式和SDIO(1bit、4bit(必须))0-25MHZ
- 低速:支持SPI模式和SDIO(1bit、4bit(可选)) 0-400KHZ
SD卡以及SDIO卡不同的指令,因为对于SDIO卡来说,SD卡的有些指令没用,比如擦除指令等。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210611174706788.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDMwMzcx,size_16,color_FFFFFF,t_70#pic_center)
#### 2.3 MMC卡(多媒体卡)
再续
### 三、FATFS文件系统
再续                

版权声明:
作者:ZhangYixi
链接:http://zyixi.xyz/sdio%e3%80%81sd%e5%8d%a1%e5%92%8cfatfs%e6%96%87%e4%bb%b6%e7%b3%bb%e7%bb%9f%e7%90%86%e8%a7%a3/
来源:一西站点
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
< <上一篇
下一篇>>
文章目录
关闭
目 录