STM32的SD卡读取Word格式.docx
- 文档编号:4109432
- 上传时间:2023-05-02
- 格式:DOCX
- 页数:20
- 大小:154.76KB
STM32的SD卡读取Word格式.docx
《STM32的SD卡读取Word格式.docx》由会员分享,可在线阅读,更多相关《STM32的SD卡读取Word格式.docx(20页珍藏版)》请在冰点文库上搜索。
SPI模式允许简单的通过SPI接口来和SD卡通信,这种模式同SD卡模式相比就是丧失了速度。
SD卡的引脚排序如下图44.1.1所示:
图44.1.1SD卡引脚排序图
SD卡引脚功能描述如表45.1.2所示:
表45.1.2SD卡引脚功能表
SD卡只能使用3.3V的IO电平,所以,MCU一定要能够支持3.3V的IO端口输出。
注意:
在SPI模式下,CS/MOSI/MISO/CLK都需要加10~100K左右的上拉电阻。
SD卡有5个寄存器,如表45.1.3所示:
名称
宽度
描述
CID
128
卡标识寄存器
RCA
16
相对卡地址(Relativecardaddress)寄存器:
本地系统中卡的地址,动态变化,在主机初始化的时候确定
*SPI模式中没有
CSD
卡描述数据:
卡操作条件相关的信息数据
SCR
64
SD配置寄存器:
SD卡特定信息数据
OCR
32
操作条件寄存器
表45.1.3SD卡相关寄存器
关于这些寄存器的详细描述,请参考光盘相关SD卡资料。
我们在这里就不描述了。
接下来,我们看看SD卡的命令格式,如表45.1.4所示:
字节1
字节2--5
字节6
7
6
5
31
0
7
1
1
command
命令参数
CRC
表45.1.4SD卡命令格式
SD卡的指令由6个字节组成,字节1的最高2位固定为01,低6位为命令号(比如CMD16,为10000即16进制的0X10,完整的CMD16,第一个字节为01010000,即0X10+0X40)。
字节2~5为命令参数,有些命令是没有参数的。
字节6的高七位为CRC值,最低位恒定为1。
SD卡的命令总共有12类,分为Class0~Class11,本章,我们仅介绍几个比较重要的命令,如表45.1.5所示:
命令
参数
回应
CMD0(0X00)
NONE
R1
复位SD卡
CMD8(0X08)
VHS+Checkpattern
R7
发送接口状态命令
CMD9(0X09)
读取卡特定数据寄存器
CMD10(0X0A)
读取卡标志数据寄存器
CMD16(0X10)
块大小
设置块大小(字节数)
CMD17(0X11)
地址
读取一个块的数据
CMD24(0X18)
写入一个块的数据
CMD41(0X29)
R3
发送给主机容量支持信息和激活
卡初始化过程
CMD55(0X37)
告诉SD卡,下一个是特定应用命令
CMD58(0X3A)
读取OCR寄存器
表45.1.5SD卡部分命令
上表中,大部分的命令是初始化的时候用的。
表中的R1、R3和R7等是SD卡的回应,SD卡和单片机的通信采用发送应答机制,如图45.1.2所示:
图45.1.2SD卡命令传输过程
每发送一个命令,SD卡都会给出一个应答,以告知主机该命令的执行情况,或者返回主机需要获取的数据。
SPI模式下,SD卡针对不同的命令,应答可以使R1~R7,R1的应答,各位描述如表45.1.6所示:
R1响应格式
位
5
4
3
2
含义
开始位
始终为0
错误
擦除序列
CRC错误
非法
擦除
复位
闲置
状态
表45.1.6R1响应各位描述
R2~R7的响应,我们就不介绍了,请的大家参考SD卡2.0协议。
接下来,我们看看SD卡初始化过程。
因为我们使用的是SPI模式,所以先得让SD卡进入SPI模式。
方法如下:
在SD卡收到复位命令(CMD0)时,CS为有效电平(低电平)则SPI模式被启用。
不过在发送CMD0之前,要发送>
74个时钟,这是因为SD卡内部有个供电电压上升时间,大概为64个CLK,剩下的10个CLK用于SD卡同步,之后才能开始CMD0的操作,在卡初始化的时候,CLK时钟最大不能超过400Khz!
。
接着我们看看SD卡的初始化,SD卡的典型初始化过程如下:
1、初始化与SD卡连接的硬件条件(MCU的SPI配置,IO口配置);
2、上电延时(>
74个CLK);
3、复位卡(CMD0),进入IDLE状态;
4、发送CMD8,检查是否支持2.0协议;
5、根据不同协议检查SD卡(命令包括:
CMD55、CMD41、CMD58和CMD1等);
6、取消片选,发多8个CLK,结束初始化
这样我们就完成了对SD卡的初始化,注意末尾发送的8个CLK是提供SD卡额外的时钟,完成某些操作。
通过SD卡初始化,我们可以知道SD卡的类型(V1、V2、V2HC或者MMC),在完成了初始化之后,就可以开始读写数据了。
SD卡读取数据,这里通过CMD17来实现,具体过程如下:
1、发送CMD17;
2、接收卡响应R1;
3、接收数据起始令牌0XFE;
4、接收数据;
5、接收2个字节的CRC,如果不使用CRC,这两个字节在读取后可以丢掉。
6、禁止片选之后,发多8个CLK;
以上就是一个典型的读取SD卡数据过程,SD卡的写于读数据差不多,写数据通过CMD24来实现,具体过程如下:
1、发送CMD24;
3、发送写数据起始令牌0XFE;
4、发送数据;
5、发送2字节的伪CRC;
以上就是一个典型的写SD卡过程。
关于SD卡的介绍,我们就介绍到这里,更详细的介绍请参考光盘SD卡的参考资料(SD卡2.0协议)。
44.2
硬件设计
本章实验功能简介:
开机的时候先初始化SD卡,如果SD卡初始化完成,则提示LCD初始化成功。
按下KEY0,读取SD卡扇区0的数据,然后通过串口发送到电脑。
如果没初始化通过,则在LCD上提示初始化失败。
同样用DS0来指示程序正在运行。
本实验用到的硬件资源有:
1)
指示灯DS0
2)
KEY0按键
3)
串口
4)
TFTLCD模块
5)
SD卡
前面四部分,在之前的实例已经介绍过了,这里我们介绍一下战舰STM32开发板板载的SD卡接口和STM32的连接关系,如图44.2.1所示:
图44.2.1SD卡接口与STM32连接原理图
我们用跳线帽将P10的SD_DT3、SD_CMD、SD_SCK、SD_DT0分别同P12的SD_CS、SPI2_MOSI、SPI2_SCK、SPI2_MISO连接起来,即实现SD卡的SPI模式连接。
硬件连接示意图如图44.2.2所示:
图44.2.2SD卡SPI方式硬件连接示意图
将图中所示的4处,用跳线帽短接,接口实现SD卡与STM32的SPI连接。
最后,你还得自备一个SD卡,将其插入板子下面的SD卡接口。
44.3
软件设计
打开上一章的工程,首先在HARDWARE文件夹下新建一个SD的文件夹。
然后新建一个MMC_SD.C和MMC_SD.H的文件保存在SD文件夹下,并将这个文件夹加入头文件包含路径。
打开MMC_SD.C文件,在该文件里面,我们输入与SD卡相关的操作代码,这里由于篇幅限制,我们不贴出所有代码,仅介绍两个最重要的函数,第一个是SD_Initialize函数,该函数源码如下:
//初始化SD卡
u8SD_Initialize(void)
{
u8r1;
//存放SD卡的返回值
u16retry;
//用来进行超时计数
u8buf[4];
u16i;
SD_SPI_Init();
//初始化IO
SD_SPI_SpeedLow();
//设置到低速模式
for(i=0;
i<
10;
i++)SD_SPI_ReadWriteByte(0XFF);
//发送最少74个脉冲
retry=20;
do
{
r1=SD_SendCmd(CMD0,0,0x95);
//进入IDLE状态
}while((r1!
=0X01)&
&
retry--);
SD_Type=0;
//默认无卡
if(r1==0X01)
if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SDV2.0
4;
i++)buf=SD_SPI_ReadWriteByte(0XFF);
//得到R7相应值
if(buf[2]==0X01&
buf[3]==0XAA)//卡是否支持2.7~3.6V
retry=0XFFFE;
SD_SendCmd(CMD55,0,0X01);
//发送CMD55
r1=SD_SendCmd(CMD41,0x40000000,0X01);
//发送CMD41
}while(r1&
retry--);
if(retry&
SD_SendCmd(CMD58,0,0X01)==0)//鉴别SD2.0卡版本开始
//得到OCR值
if(buf[0]&
0x40)SD_Type=SD_TYPE_V2HC;
//检查CCS
elseSD_Type=SD_TYPE_V2;
}
}
}else//SDV1.x/MMC
V3
//发送CMD55
r1=SD_SendCmd(CMD41,0,0X01);
if(r1<
=1)
{
SD_Type=SD_TYPE_V1;
do//等待退出IDLE模式
}else//MMC卡不支持CMD55+CMD41识别
SD_Type=SD_TYPE_MMC;
//MMCV3
{
r1=SD_SendCmd(CMD1,0,0X01);
//发送CMD1
if(retry==0||SD_SendCmd(CMD16,512,0X01)!
=0)SD_Type=SD_TYPE_ERR;
//错误的卡
SD_DisSelect();
//取消片选
SD_SPI_SpeedHigh();
//高速
if(SD_Type)return0;
elseif(r1)returnr1;
return0xaa;
//其他错误
}
该函数先设置与SD相关的IO口及SPI初始化,然后发送CMD0,进入IDLE状态,并设置SD卡为SPI模式通信,然后判断SD卡类型,完成SD卡的初始化,注意该函数调用的SD_SPI_Init等函数,实际是对SPI2的相关函数进行了一层封装,方便移植。
另外一个要介绍的函数是SD_ReadDisk,该函数用于从SD卡读取一个扇区的数据(这里一般为512字节),该函数代码如下:
//读SD卡
//buf:
数据缓存区
//sector:
扇区
//cnt:
扇区数
//返回值:
0,ok;
其他,失败.
u8SD_ReadDisk(u8*buf,u32sector,u8cnt)
if(SD_Type!
=SD_TYPE_V2HC)sector<
<
=9;
//转换为字节地址
if(cnt==1)
r1=SD_SendCmd(CMD17,sector,0X01);
//读命令
if(r1==0)r1=SD_RecvData(buf,512);
//命令发送成功,接收512个字节
}else
r1=SD_SendCmd(CMD18,sector,0X01);
//连续读命令
do
r1=SD_RecvData(buf,512);
//接收512个字节
buf+=512;
}while(--cnt&
r1==0);
SD_SendCmd(CMD12,0,0X01);
//发送停止命令
}
returnr1;
//
此函数先发送CMD17命令,然后读取一个扇区的数据,详细见代码,这里我们就不多介绍了。
保存MMC_SD.C文件,并加入到HARDWARE组下,然后打开MMC_SD.H,在该文件里面输入如下代码:
#ifndef_MMC_SD_H_
#define_MMC_SD_H_
#include\"
sys.h\"
#include
//SD卡类型定义
#defineSD_TYPE_ERR
0X00
#defineSD_TYPE_MMC
0X01
#defineSD_TYPE_V1
0X02
#defineSD_TYPE_V2
0X04
#defineSD_TYPE_V2HC
0X06
//SD卡指令表
#defineCMD0
0
//卡复位
#defineCMD1
#defineCMD8
8
//命令8,SEND_IF_COND
#defineCMD9
9
//命令9,读CSD数据
#defineCMD10
10
//命令10,读CID数据
#defineCMD12
12
//命令12,停止数据传输
#defineCMD16
16
//命令16,设置SectorSize应返回0x00
#defineCMD17
17
//命令17,读sector
#defineCMD18
18
//命令18,读Multisector
#defineCMD23
23
//命令23,设置多sector写入前预先擦除N个block
#defineCMD24
24
//命令24,写sector
#defineCMD25
25
//命令25,写Multisector
#defineCMD41
41
//命令41,应返回0x00
#defineCMD55
55
//命令55,应返回0x01
#defineCMD58
58
//命令58,读OCR信息
#defineCMD59
59
//命令59,使能/禁止CRC,应返回0x00
//数据写入回应字意义
#defineMSD_DATA_OK
0x05
#defineMSD_DATA_CRC_ERROR
0x0B
#defineMSD_DATA_WRITE_ERROR
0x0D
#defineMSD_DATA_OTHER_ERROR
0xFF
//SD卡回应标记字
#defineMSD_RESPONSE_NO_ERROR
0x00
#defineMSD_IN_IDLE_STATE
0x01
#defineMSD_ERASE_RESET
0x02
#defineMSD_ILLEGAL_COMMAND
0x04
#defineMSD_COM_CRC_ERROR
0x08
#defineMSD_ERASE_SEQUENCE_ERROR
0x10
#defineMSD_ADDRESS_ERROR
0x20
#defineMSD_PARAMETER_ERROR
0x40
#defineMSD_RESPONSE_FAILURE
0xFF
//这部分应根据具体的连
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- STM32 SD 读取