SD卡引脚定义电路基本原理.docx

上传人:b****5 文档编号:28107990 上传时间:2023-07-08 格式:DOCX 页数:18 大小:2.14MB
下载 相关 举报
SD卡引脚定义电路基本原理.docx_第1页
第1页 / 共18页
SD卡引脚定义电路基本原理.docx_第2页
第2页 / 共18页
SD卡引脚定义电路基本原理.docx_第3页
第3页 / 共18页
SD卡引脚定义电路基本原理.docx_第4页
第4页 / 共18页
SD卡引脚定义电路基本原理.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

SD卡引脚定义电路基本原理.docx

《SD卡引脚定义电路基本原理.docx》由会员分享,可在线阅读,更多相关《SD卡引脚定义电路基本原理.docx(18页珍藏版)》请在冰豆网上搜索。

SD卡引脚定义电路基本原理.docx

SD卡引脚定义电路基本原理

SD卡在现在的日常生活与工作中使用非常广泛,时下已经成为最为通用的数据存储卡。

在诸如MP3、数码相机等设备上也都采用SD卡作为其存储设备。

SD卡之所以得到如此广泛的使用,是因为它价格低廉、存储容量大、使用方便、通用性与安全性强等优点。

既然它有着这么多优点,那么如果将它加入到单片机应用开发系统中来,将使系统变得更加出色。

这就要求对SD卡的硬件与读写时序进行研究。

对于SD卡的硬件结构,在官方的文档上有很详细的介绍(jièshào),如SD卡内的存储器结构、存储单元组织方式等内容。

要实现对它的读写,最核心的是它的时序,笔者在经过了实际的测试后,使用51单片机成功实现了对SD卡的扇区读写,并对其读写速度进行了评估。

下面先来讲解SD卡的读写时序。

(1) SD卡的引脚定义(dìngyì):

 

 

SD卡引脚功能(gōngnéng)详述:

引脚编号

SD模式

       SPI模式

名称

类型

描述

名称

类型

描述

1

CD/DAT3

IO或PP

卡检测/数据线3

#CS

I

片选

2

CMD

PP

命令/回应

DI

I

数据输入

3

VSS1

S

电源地

VSS

S

电源地

4

VDD

S

电源

VDD

S

电源

5

CLK

I

时钟

SCLK

I

时钟

6

VSS2

S

电源地

VSS2

S

电源地

7

DAT0

IO或PP

数据线0

DO

O或PP

数据输出

8

DAT1

IO或PP

数据线1

RSV

 

 

9

DAT2

IO或PP

数据线2

RSV

 

 

注:

S:

电源供给 I:

输入(shūrù)O:

采用推拉驱动的输出

PP:

采用推拉驱动的输入输出

SD卡SPI模式(móshì)下与单片机的连接图:

 

 

   SD卡支持(zhīchí)两种总线方式:

SD方式与SPI方式。

其中SD方式采用6线制,使用CLK、CMD、DAT0~DAT3进行数据通信。

而SPI方式采用4线制,使用CS、CLK、DataIn、DataOut进行数据通信。

SD方式时的数据传输速度与SPI方式要快,采用单片机对SD卡进行读写时一般都采用SPI模式。

采用不同的初始化方式可以使SD卡工作于SD方式或SPI方式。

这里只对其SPI方式进行介绍。

(2) SPI方式驱动(qūdònɡ)SD卡的方法

    SD卡的SPI通信接口使其可以通过SPI通道进行数据读写。

从应用的角度来看,采用SPI接口的好处在于,很多单片机内部自带SPI控制器,不光给开发上带来方便,同时也见降低了开发成本。

然而,它也有不好的地方,如失去了SD卡的性能优势,要解决这一问题,就要用SD方式,因为它提供更大的总线数据带宽。

SPI接口的选用是在上电初始时向其写入第一个命令时进行的。

以下(yǐxià)介绍SD卡的驱动方法,只实现简单的扇区读写。

1) 命令(mìnglìng)与数据传输

1. 命令传输

SD卡自身有完备的命令系统,以实现各项操作。

命令格式如下:

 

     命令的传输过程采用发送应答机制,过程如下:

                       

   每一个命令都有自己命令应答格式。

在SPI模式中定义了三种应答格式,如下表所示:

字节

含义

   1

7

开始位,始终为0

6

参数错误

5

地址错误

4

擦除序列错误

3

CRC错误

2

非法命令

1

擦除复位

0

闲置状态

字节

含义

   1

7

开始位,始终为0

6

参数错误

5

地址错误

4

擦除序列错误

3

CRC错误

2

非法命令

1

擦除复位

0

闲置状态

   2

7

溢出,CSD覆盖

6

擦除参数

5

写保护非法

4

卡ECC失败

3

卡控制器错误

2

未知错误

1

写保护擦除跳过,锁/解锁失败

0

锁卡

字节

含义

   1

7

开始位,始终为0

6

参数错误

5

地址错误

4

擦除序列错误

3

CRC错误

2

非法命令

1

擦除复位

0

闲置状态

2~5

全部

操作条件寄存器,高位在前

 

写命令的例程:

//-----------------------------------------------------------------------------------------------

 向SD卡中写入命令,并返回回应(huíyīnɡ)的第二个字节

//-----------------------------------------------------------------------------------------------

unsignedcharWrite_Command_SD(unsignedchar*CMD)

{

  unsignedchartmp;

  unsignedcharretry=0;

  unsignedchari;

  //禁止SD卡片选

  SPI_CS=1;

  //发送(fāsònɡ)8个时钟信号

  Write_Byte_SD(0xFF);

  //使能SD卡片选

  SPI_CS=0;

  //向SD卡发送6字节(zìjié)命令

  for(i=0;i<0x06;i++)

  {

     Write_Byte_SD(*CMD++);

  }

  

  //获得16位的回应

  Read_Byte_SD();//readthefirstbyte,ignoreit.

  do

  { //读取后8位

     tmp=Read_Byte_SD();

     retry++;

  }

  while((tmp==0xff)&&(retry<100));

  return(tmp);

}

2) 初始化

SD卡的初始化是非常重要的,只有进行了正确的初始化,才能进行后面的各项操作。

在初始化过程中,SPI的时钟不能太快,否则会造初始化失败。

在初始化成功后,应尽量提高(tígāo)SPI的速率。

在刚开始要先发送至少74个时钟信号,这是必须的。

在很多读者的实验中,很多是因为疏忽了这一点,而使初始化不成功。

随后就是写入两个命令CMD0与CMD1,使SD卡进入SPI模式

          初始化时序图:

  

 

 

          初始化例程:

//--------------------------------------------------------------------------

   初始化SD卡到SPI模式(móshì)

//--------------------------------------------------------------------------

unsignedcharSD_Init()

  unsignedcharretry,temp;

  unsignedchari;

  unsignedcharCMD[]={0x40,0x00,0x00,0x00,0x00,0x95};

  SD_Port_Init();//初始化驱动(qūdònɡ)端口

  

  Init_Flag=1;//将初始化标志置1

  for(i=0;i<0x0f;i++)

  {

     Write_Byte_SD(0xff);//发送至少74个时钟信号

  }

 

  //向SD卡发送CMD0

  retry=0;

  do

  {//为了能够成功写入CMD0,在这里写200次

    temp=Write_Command_SD(CMD);

    retry++;

    if(retry==200)

    {//超过200次

      return(INIT_CMD0_ERROR);//CMD0Error!

    }

  }

  while(temp!

=1); //回应01h,停止写入

  

  //发送CMD1到SD卡

  CMD[0]=0x41;//CMD1

  CMD[5]=0xFF;

  retry=0;

  do

  {//为了能成功写入CMD1,写100次

    temp=Write_Command_SD(CMD);

    retry++;

    if(retry==100)

    {//超过100次

      return(INIT_CMD1_ERROR);//CMD1Error!

    }

  }

  while(temp!

=0);//回应00h停止写入

  

  Init_Flag=0;//初始化完毕,初始化标志(biāozhì)清零

  

  SPI_CS=1; //片选无效

  return(0);//初始化成功

}

3) 读取CID

CID寄存器存储了SD卡的标识码。

每一个卡都有唯一的标识码。

CID寄存器长度(chángdù)为128位。

它的寄存器结构如下:

 

名称

数据宽度

CID划分

生产标识号

MID

8

[127:

120]

OEM/应用标识

OID

16

[119:

104]

产品名称

PNM

40

[103:

64]

产品版本

PRV

8

[63:

56]

产品序列号

PSN

32

[55:

24]

保留

4

[23:

20]

生产日期

MDT

12

[19:

8]

CRC7校验合

CRC

7

[7:

1]

未使用,始终为1

1

[0:

0]

它的读取时序(shíxù)如下:

 

 

       与此时(cǐshí)序相对应的程序如下:

//------------------------------------------------------------------------------------

   读取SD卡的CID寄存器  16字节  成功返回0

//-------------------------------------------------------------------------------------

unsignedcharRead_CID_SD(unsignedchar*Buffer)

{

  //读取CID寄存器的命令

  unsignedcharCMD[]={0x4A,0x00,0x00,0x00,0x00,0xFF};

  unsignedchartemp;

  temp=SD_Read_Block(CMD,Buffer,16);//read16bytes

  return(temp);

}

4)读取CSD

CSD(Card-SpecificData)寄存器提供了读写SD卡的一些信息。

其中的一些单元可以(kěyǐ)由用户重新编程。

具体的CSD结构如下:

名称

数据宽度

单元类型

CSD划分

CSD结构

CSD_STRUCTURE

2

R

[127:

126]

保留

-

6

R

[125:

120]

数据读取时间1

TAAC

8

R

[119:

112]

数据在CLK周期内读取时间2(NSAC*100)

NSAC

8

R

[111:

104]

最大数据传输率

TRAN_SPEED

8

R

[103:

96]

卡命令集合

CCC

12

R

[95:

84]

最大读取数据块长

READ_BL_LEN

4

R

[83:

80]

允许读的部分块

READ_BL_PARTIAL

1

R

[79:

79]

非线写块

WRITE_BLK_MISALIGN

1

R

[78:

78]

非线读块

READ_BLK_MISALIGN

1

R

[77:

77]

DSR条件

DSR_IMP

1

R

[76:

76]

保留

-

2

R

[75:

74]

设备容量

C_SIZE

12

R

[73:

62]

最大读取电流@VDDmin

VDD_R_CURR_MIN

3

R

[61:

59]

最大读取电流@VDDmax

VDD_R_CURR_MAX

3

R

[58:

56]

最大写电流@VDDmin

VDD_W_CURR_MIN

3

R

[55:

53]

最大写电流@VDDmax

VDD_W_CURR_MAX

3

R

[52:

50]

设备容量乘子

C_SIZE_MULT

3

R

[49:

47]

擦除单块使能

ERASE_BLK_EN

1

R

[46:

46]

擦除扇区大小

SECTOR_SIZE

7

R

[45:

39]

写保护群大小

WP_GRP_SIZE

7

R

[38:

32]

写保护群使能

WP_GRP_ENABLE

1

R

[31:

31]

保留

-

2

R

[30:

29]

写速度因子

R2W_FACTOR

3

R

[28:

26]

最大写数据块长度

WRITE_BL_LEN

4

R

[25:

22]

允许写的部分部

WRITE_BL_PARTIAL

1

R

[21:

21]

保留

-

5

R

[20:

16]

文件系统群

FILE_OFRMAT_GRP

1

R/W

[15:

15]

拷贝标志

COPY

1

R/W

[14:

14]

永久写保护

PERM_WRITE_PROTECT

1

R/W

[13:

13]

暂时写保护

TMP_WRITE_PROTECT

1

R/W

[12:

12]

文件系统

FIL_FORMAT

2

R/W

[11:

10]

保留

-

2

R/W

[9:

8]

CRC

CRC

7

R/W

[7:

1]

未用,始终为1

-

1

 

[0:

0]

 

读CSD的时序(shíxù):

  

          相应的程序(chéngxù)例程如下:

//-----------------------------------------------------------------------------------------

   读SD卡的CSD寄存器  共16字节   返回0说明读取成功

//-----------------------------------------------------------------------------------------

unsignedcharRead_CSD_SD(unsignedchar*Buffer)

  //读取CSD寄存器的命令

  unsignedcharCMD[]={0x49,0x00,0x00,0x00,0x00,0xFF};

  unsignedchartemp;

  temp=SD_Read_Block(CMD,Buffer,16);//read16bytes

  return(temp);

}

4) 读取SD卡信息(xìnxī)

综合上面对CID与CSD寄存器的读取,可以知道很多关于SD卡的信息,以下程序可以获取这些信息。

如下:

//-----------------------------------------------------------------------------------------------

//返回

// SD卡的容量(róngliàng),单位为M

// sectorcountandmultiplierMBarein

u08==C_SIZE/(2^(9-C_SIZE_MULT))

// SD卡的名称

//-----------------------------------------------------------------------------------------------

voidSD_get_volume_info()

{  

   unsignedchari;

   unsignedcharc_temp[5];

   VOLUME_INFO_TYPESD_volume_Info,*vinf;

   vinf=&SD_volume_Info;//Initthepointoer;

/读取CSD寄存器

   Read_CSD_SD(sectorBuffer.dat);

//获取总扇区数

 vinf->sector_count=sectorBuffer.dat[6]&0x03;

 vinf->sector_count<<=8;

 vinf->sector_count+=sectorBuffer.dat[7];

 vinf->sector_count<<=2;

 vinf->sector_count+=(sectorBuffer.dat[8]&0xc0)>>6;

 //获取multiplier

 vinf->sector_multiply=sectorBuffer.dat[9]&0x03;

 vinf->sector_multiply<<=1;

 vinf->sector_multiply+=(sectorBuffer.dat[10]&0x80)>>7;

//获取SD卡的容量

 vinf->size_MB=vinf->sector_count>>(9-vinf->sector_multiply);

 //getthenameofthecard

 Read_CID_SD(sectorBuffer.dat);

 vinf->name[0]=sectorBuffer.dat[3];

 vinf->name[1]=sectorBuffer.dat[4];

 vinf->name[2]=sectorBuffer.dat[5];

 vinf->name[3]=sectorBuffer.dat[6];

 vinf->name[4]=sectorBuffer.dat[7];

 vinf->name[5]=0x00;//endflag 

}

        以上程序将信息装载到一个结构体中,这个结构体的定义如下:

typedefstructSD_VOLUME_INFO

{//SD/SDCardinfo

 unsignedint size_MB;

 unsignedcharsector_multiply;

 unsignedint sector_count;

 unsignedcharname[6];

}VOLUME_INFO_TYPE;

5) 扇区读

扇区读是对SD卡驱动的目的(mùdì)之一。

SD卡的每一个扇区中有512个字节,一次扇区读操作将把某一个扇区内的512个字节全部读出。

过程很简单,先写入命令,在得到相应的回应后,开始数据读取。

扇区读的时序:

 

 

     扇区读的程序例程:

unsignedcharSD_Read_Sector(unsignedlongsector,unsignedchar*buffer)

  unsignedcharretry;

  //命令(mìnglìng)16

  unsignedcharCMD[]={0x51,0x00,0x00,0x00,0x00,0xFF};

  unsignedchartemp;

  

  //地址变换  由逻辑块地址转为字节地址

  sector=sector<<9;//sector=sector*512

  CMD[1]=((sector&0xFF000000)>>24);

  CMD[2]=((sector&0x00FF0000)>>16);

  CMD[3]=((sector&0x0000FF00)>>8);

  //将命令16写入SD卡

  retry=0;

  do

  { //为了保证(bǎozhèng)写入命令 一共写100次

     temp=Write_Command_MMC(CMD);

     retry++;

     if(retry==100)

     {

       return(READ_BLOCK_ERROR);//blockwriteError!

     }

  }

  while(temp!

=0);

     

  //ReadStartByteformMMC/SD-Card(FEh/StartByte)

  //Nowdataisready,youcanreaditout.

  while(Read_Byte_MMC()!

=0xfe);

  readPos=0;

 SD_get_data(512,buffer); //512字节被读出到buffer中

 return0;

}

其中(qízhōng)SD_get_data函数如下:

//----------------------------------------------------------------------------

   获取数据到buffer中

//----------------------------------------------------------------------------

voidSD_get_da

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 材料科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1