您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > STM32读写SD卡
2953.20SD卡实验很多单片机系统都需要大容量存储设备,以存储数据。目前常用的有U盘,FLASH芯片,SD卡等。他们各有优点,综合比较,昀适合单片机系统的莫过于SD卡了,它不仅容量可以做到很大(32Gb以上),而且支持SPI接口,方便移动,有几种体积的尺寸可供选择(标准的SD卡尺寸,以及TF卡尺寸),能满足不同应用的要求。只需要4个IO口,就可以外扩一个昀大达32GB以上的外部存储器,容量选择尺度很大,更换也很方便,而且方便移动,编程也比较简单,是单片机大容量外部存储器的首选。ALIENTKEMiniSTM3开发板就带有SD卡接口,利用STM32自带的SPI接口,昀大通信速度可达18Mbps,每秒可传输数据2M字节以上,对于一般应用足够了。本节将向大家介绍,如何在ALIENTEKMiniSTM32开发板上读取SD卡。本节分为如下几个部分:3.20.1SD卡简介3.20.2硬件设计3.20.3软件设计3.20.4下载与测试2963.20.1SD卡简介SD卡(SecureDigitalMemoryCard)中文翻译为安全数码卡,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。大小犹如一张邮票的SD记忆卡,重量只有2克,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性。SD卡一般支持2种操作模式:1,SD卡模式;2,SPI模式;主机可以选择以上任意一种模式同SD卡通信,SD卡模式允许4线的高速数据传输。SPI模式允许简单的通过SPI接口来和SD卡通信,这种模式同SD卡模式相比就是丧失了速度。SD卡的引脚排序如下图所示:图3.20.1.1SD卡引脚排序图SD卡引脚功能描述如下表所示:表3.20.1.1SD卡引脚功能表SD卡只能使用3.3V的IO电平,所以,MCU一定要能够支持3.3V的IO端口输出。注意:在SPI模式下,CS/MOSI/MISO/CLK都需要加10~100K左右的上拉电阻。SD卡要进入SPI模式很简单,就是在SD卡收到复位命令(CMD0)时,CS为有效电平(低电平)则SPI模式被启用。不过在发送CMD0之前,要发送74个时钟,这是因为SD卡内部有个供电电压上升时间,大概为64个CLK,剩下的10个CLK用于SD卡同步,之后才能开始CMD0的操作,在卡初始化的时候,CLK时钟昀大不能超过400Khz!。ALENTEKMiniSTM32开发板使用的是SPI模式来读写SD卡,下面我们就重点介绍一下SD卡在SPI模式下的相关操作。首先介绍SPI模式下几个重要的操作命令,如下表所示:297命令参数回应描述CMD0(0X00)NONER1复位SD卡CMD9(0X09)NONER1读取卡特定数据寄存器CMD10(0X0A)NONER1读取卡标志数据寄存器CMD16(0X10)块大小R1设置块大小(字节数)CMD17(0X11)地址R1读取一个块的数据CMD24(0X18)地址R1写入一个块的数据CMD41(0X29)NONER1引用命令的前命令CMD55(0X37)NONER1开始卡的初始化CMD59(0X3B)仅昀后一位有效R1设置CRC开启(1)或关闭(0)表3.20.1.2SPI模式下SD卡部分操作指令其中R1的回应格式如下表所示:表3.20.1.3SD卡R1回应格式接着我们看看SD卡的初始化,SD卡的典型初始化过程如下:1、初始化与SD卡连接的硬件条件(MCU的SPI配置,IO口配置);2、上电延时(74个CLK);3、复位卡(CMD0);4、激活卡,内部初始化并获取卡类型(CMD1(用于MMC卡)、CMD55、CMD41);5.、查询OCR,获取供电状况(CMD58);6、是否使用CRC(CMD59);7、设置读写块数据长度(CMD16);8、读取CSD,获取存储卡的其他信息(CMD9);9、发送8CLK后,禁止片选;这样我们就完成了对SD卡的初始化,这里面我们一般设置读写块数据长度为512个字节,并禁止使用CRC。在完成了初始化之后,就可以开始读写数据了。SD卡读取数据,这里通过CMD17来实现,具体过程如下:1、发送CMD17;2、接收卡响应R1;3、接收数据起始令牌0XFE;4、接收数据;5、接收2个字节的CRC,如果没有开启CRC,这两个字节在读取后可以丢掉。6、8CLK之后禁止片选;以上就是一个典型的读取SD卡数据过程,SD卡的写于读数据差不多,写数据通过CMD24来实现,具体过程如下:1、发送CMD24;2、接收卡响应R1;3、发送写数据起始令牌0XFE;2984、发送数据;5、发送2字节的伪CRC;6、8CLK之后禁止片选;以上就是一个典型的写SD卡过程。关于SD卡的介绍,我们就介绍到这里,更详细的介绍请参考SD卡的参考资料。3.20.2硬件设计本节实验功能简介:开机的时候先初始化SD卡,如果SD卡初始化完成,则读取扇区0的数据,然后通过串口打印到电脑上。如果没初始化通过,则在LCD上提示初始化失败。同样用DS0来指示程序正在运行。所要用到的硬件资源如下:1)STM32F103RBT6。2)DS0(外部LED0)。3)串口1。4)TFTLCD液晶模块。5)SD卡。前面四部分,在之前的实例已经介绍过了,这里我们介绍一下SD卡在开发板上的连接方式,SD卡与MCU的连接原理图如下:图3.20.2.1SD卡与STM32连接电路图2993.20.3软件设计打开上一节的工程,首先在HARDWARE文件夹下新建一个SD的文件夹。然后新建一个MMC_SD.C和MMC_SD.H的文件保存在SD文件夹下,并将这个文件夹加入头文件包含路径。打开MMC_SD.C文件,输入如下代码:#includesys.h#includemmc_sd.h#includespi.h#includeusart.h#includedelay.hu8SD_Type=0;//SD卡的类型//MiniSTM32开发板//SD卡驱动//正点原子@ALIENTEK//2010/5/13//增加了一些延时,实测可以支持TF卡(1G/2G),金士顿2G,4G16GSD卡//2010/6/24//加入了u8SD_GetResponse(u8Response)函数//修改了u8SD_WaitDataReady(void)函数//增加了USB读卡器支持的u8MSD_ReadBuffer(u8*pBuffer,u32ReadAddr,u32NumByteToRead);//和u8MSD_WriteBuffer(u8*pBuffer,u32WriteAddr,u32NumByteToWrite);两个函数//等待SD卡回应//Response:要得到的回应值//返回值:0,成功得到了该回应值//其他,得到回应值失败u8SD_GetResponse(u8Response){u16Count=0xFFF;//等待次数while((SPIx_ReadWriteByte(0XFF)!=Response)&&Count)Count--;//等待得到准确的回应if(Count==0)returnMSD_RESPONSE_FAILURE;//得到回应失败elsereturnMSD_RESPONSE_NO_ERROR;//正确回应}//等待SD卡写入完成//返回值:0,成功;//其他,错误代码;u8SD_WaitDataReady(void){u8r1=MSD_DATA_OTHER_ERROR;300u32retry;retry=0;do{r1=SPIx_ReadWriteByte(0xFF)&0X1F;//读到回应if(retry==0xfffe)return1;retry++;switch(r1){caseMSD_DATA_OK://数据接收正确了r1=MSD_DATA_OK;break;caseMSD_DATA_CRC_ERROR://CRC校验错误returnMSD_DATA_CRC_ERROR;caseMSD_DATA_WRITE_ERROR://数据写入错误returnMSD_DATA_WRITE_ERROR;default://未知错误r1=MSD_DATA_OTHER_ERROR;break;}}while(r1==MSD_DATA_OTHER_ERROR);//数据错误时一直等待retry=0;while(SPIx_ReadWriteByte(0XFF)==0)//读到数据为0,则数据还未写完成{retry++;//delay_us(10);//SD卡写等待需要较长的时间if(retry=0XFFFFFFFE)return0XFF;//等待失败了};return0;//成功了}//向SD卡发送一个命令//输入:u8cmd命令//u32arg命令参数//u8crccrc校验值//返回值:SD卡返回的响应u8SD_SendCommand(u8cmd,u32arg,u8crc){u8r1;u8Retry=0;SD_CS=1;SPIx_ReadWriteByte(0xff);//高速写命令延时SPIx_ReadWriteByte(0xff);SPIx_ReadWriteByte(0xff);301//片选端置低,选中SD卡SD_CS=0;//发送SPIx_ReadWriteByte(cmd|0x40);//分别写入命令SPIx_ReadWriteByte(arg24);SPIx_ReadWriteByte(arg16);SPIx_ReadWriteByte(arg8);SPIx_ReadWriteByte(arg);SPIx_ReadWriteByte(crc);//等待响应,或超时退出while((r1=SPIx_ReadWriteByte(0xFF))==0xFF){Retry++;if(Retry200)break;}//关闭片选SD_CS=1;//在总线上额外增加8个时钟,让SD卡完成剩下的工作SPIx_ReadWriteByte(0xFF);//返回状态值returnr1;}//向SD卡发送一个命令(结束是不失能片选,还有后续数据传来)//输入:u8cmd命令//u32arg命令参数//u8crccrc校验值//返回值:SD卡返回的响应u8SD_SendCommand_NoDeassert(u8cmd,u32arg,u8crc){u8Retry=0;u8r1;SPIx_ReadWriteByte(0xff);//高速写命令延时SPIx_ReadWriteByte(0xff);SD_CS=0;//片选端置低,选中SD卡//发送SPIx_ReadWriteByte(cmd|0x40);//分别写入命令SPIx_ReadWriteByte(arg24);SPIx_ReadWriteByte(arg16);SPIx_ReadWriteByte(arg8);SPIx_ReadWriteByte(arg);SPIx_ReadWriteByte(crc);302//等待响应,或超时退出while((r1=SPIx_ReadWriteByte(0xFF))==0xFF){Retry++;if(Retry200)break;}//返回响应值returnr1;}//把SD卡设置到挂起模式//返回值:0,成功设置//1,设置失败u8SD_Idle_Sta(void){u16i;u8retry;for(i=0;i0xf00;i++);//纯延时,等待SD卡上电完成//先产生74个脉冲,让SD卡自己初始化完成for(i=0;i10;i++)SPIx_ReadWriteByte(0xFF);//-----------------SD卡复位到idle开始-----------------//循环连续发送CMD0,直到SD卡返回0x01,进入IDLE状态//超时则直接退出
本文标题:STM32读写SD卡
链接地址:https://www.777doc.com/doc-6022703 .html