STM32学习笔记之SD卡V2.0协议初始化
STM32F103调试读SD卡经验总结

WL板子EK-STM32F103调试读S D卡经验总结一开始碰到的问题:发送CMD0能执行返回01,CMD1超时没响应。
查到原因:模板程序控制SD供电逻辑反了。
#if 0#define MSD_POWER_ON() GPIO_ResetBits(GPIOD, GPIO_Pi n_10)#define MSD_POWER_OFF() GPIO_SetBits(GPIOD, GPIO_Pin_10)#else#define MSD_POWER_ON() GPIO_SetBits(GPIOD, GPIO_Pin_10)#define MSD_POWER_OFF() GPIO_ResetBits(GPIOD, GPIO_Pin_10)#endif第二个问题:单步执行CMD0,CMD1,有响应,直接运行没响应。
查到原因,上电时间少于1ms,SD卡内部复位没准备好,初始化前加廷时1ms./* delay 1ms*/delay(5000);/* MSD chip select low */MSD_CS_LOW();/* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI m ode */MSD_SendCmd(MSD_GO_IDLE_STATE, 0, 0x95);第三个问题:有时执行还是没有响应。
原因,SD卡初始化SPI时钟要在100kHz到400kHz之间,更改SPI速率为180kHz.第四个问题:读SD卡CSD寄存器没返回数据。
原因:供电不足,平时只有2.9V,SPI通迅时,出现瞬间低于2.7V现像。
短接直接供3.3V,如附图。
继续其它试验。
出处:kimfufree[最后修改于2008-09-03 19:58]。
基于STM32的SD卡设计毕业论文

摘要SD卡(Secure Digital Memory Card)中文翻译为安全数码卡,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。
SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。
大小犹如一张邮票的SD记忆卡,重量只有2克,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性。
由于互联网的飞速发展,各种移动设备的计算能力得到大幅提升,与外界数据通信交换量越来越大,通信的安全性以及数据的真实性尤为重要。
正是因为SD卡具有如此多的优点,才被人们广泛的应用。
根据SD卡的各种优点和特性,而在STM32平台上对其进行开发设计,着重于加强SD卡的数据通信的速度以及与嵌入式产品的通信更加方便,主要对SD卡通信时采集的电压、电流、功率及时间监测及补偿。
包含一些基本的通信及SD卡驱动实现和分析,本文基于STM32就SD卡的硬件和软件作研究设计。
最后,对SD卡课题研究进行阶段性总结和对后续工作进行展望。
关键词:SD卡;移动存储;STM32;SPI接口ABSTRACTSD card (Secure Digital Memory Card) Secure Digital card translated into Chinese, is a flash memory device based on a new generation of semiconductor memory devices, it is widely used in portable devices such as digital cameras, personal digital assistant (PDA) and multimedia players. SD card from Japan Panasonic, Toshiba and SanDisk Corporation in the United States in August 1999 jointly developed. Like a postage stamp size SD memory card, weight only 2 grams, but it has high memory capacity, fast data transfer rates, great flexibility and good mobile security. As the rapid development of Internet, computing power of mobile devices has increased substantially, with the outside world, increasing the amount of data traffic exchange, traffic safety and authenticity of data is particularly important.It is precisely because of the SD card has so many advantages, was only a wide range of applications. The various advantages and features of the SD card, while in the STM32 platform, its development and design, focus on strengthening the SD card data communication speed and more convenient communications and embedded products, mainly collected in the SD card to communicate voltage, current, power and time monitoring and compensation . Contains some basic communication and SD card driver implementation and analysis, SD card hardware and software design based on the STM32.Finally, the stage summary and outlook on the follow-up research of the SD card. Key Words: SD card; Removable Storage; STM32; SPI interface目录第一章绪论1.1 课题背景及意义 (1)1.2 SD卡简介 (1)1.3 SD卡的应用 (2)1.4 SD卡所研究的内容以及特色 (3)第二章 SD卡硬件设计2.1 硬件读写模块 (4)2.2 硬件设计模块 (4)第三章 SD卡软件设计3.1 SPI工作模式: (7)3.2 SD卡初始化: (9)3.3数据块的读写 (10)3.4 SD卡软件设计 (11)第四章调试与效果4.1 STM32连接原理图 (13)4.2 下载与调试 (13)第五章结论与展望参考文献(References) (16)致谢 (17)附录 (18)附录1 (18)附录2 (20)第一章绪论1.1 课题背景及意义21世纪是一信息传递及应用高速的时代,信息在人类社会活动中已经必不可缺,使用嵌入式系统的电子产品已经在人们的日常生活中广泛普及应用。
STM32学习笔记

一、GPIO基本功能的使用:GPIO功能文件相关操作:1.使用GPIO功能前,首先要初始化系统,最简单的方法为:添加stm32f10x_rcc.c,打开stm32f10x_conf.h 在第41行将/* #include "stm32f10x_rcc.h""*/两边注释符去掉,在main 函数中添加代码SystemInit();2.添加stm32f10x_gpio.c3.打开stm32f10x_conf.h 在37行将/*#include "stm32f10x_gpio.h"*/两边注释符去掉GPIO口使能:1.定义一个初始化类型结构体变量,我们为这个结构体里的各个变量赋值,GPIO_InitTypeDef GPIO_InitStructure;2. 开启GPIO时钟,只有开启了GPIO时钟,对应端口才可以正常工作,GPIO口对应时钟APB2RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);3. 为结构体赋值设置GPIO口为输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //设置引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出,其它选项GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出最大频率,其它选项设置GPIO口为输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //设置引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//悬空输附:GPIO_Mode值GPIO_Mode_AIN 模拟输入GPIO_Mode_IN_FLOATING 浮空输入GPIO_Mode_IPD 下拉输入GPIO_Mode_IPU 上拉输入GPIO_Mode_Out_OD 开漏输出GPIO_Mode_Out_PP 推挽输出GPIO_Mode_AF_OD 复用开漏输出GPIO_Mode_AF_PP 复用推挽输出GPIO_Speed值GPIO_Speed_10MHz 最高输出速率10MHzGPIO_Speed_2MHz 最高输出速率2MHzGPIO_Speed_50MHz 最高输出速率50MHz4. 使能GPIO口GPIO_Init(GPIOA, &GPIO_InitStructure);例:void GPIOA0_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);}GPIO使用:输出状态:GPIO口置高:GPIO_SetBits(GPIOA,GPIO_Pin_0| GPIO_Pin_1);GPIO口置底:GPIO_ResetBits(GPIOA,GPIO_Pin_0);写数据到GPIO的某个引脚:GPIO_WriteBit(GPIOA, GPIO_Pin_15, Bit_SET); 写数据到GPIO:GPIO_Write(GPIOA, 0x1101);得到GPIO口状态:GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0);u16 ReadValue;ReadValue = GPIO_ReadOutputData(GPIOC);例:#define LED0_OFF GPIO_ResetBits(GPIOA,GPIO_Pin_0)#define LED0_ON GPIO_SetBits(GPIOA,GPIO_Pin_0)#define LED0 GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0)int main(void){while(1){delay();if(LED1)LED0_OFF;else LED0_ON;}}输入状态:得到GPIO口状态:GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)u16 ReadValue;ReadValue = GPIO_ReadInputData(GPIOC);二、USART串口基本功能实现添加stm32f10x_rcc.c stm32f10x_gpio.c stm32f10x_usart.c打开stm32f10x_conf.h 在37行将/*#include "stm32f10x_gpio.h"*/41行/* #include "stm32f10x_rcc.h""*/ 46行/*#include "stm32f10x_usart.h"*/两边注释符去掉USART串口配置1.Gpio引脚配置,将USART的TX口配置为输出,RX配置为浮空输入2.配置时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);3.配置usartUSART_InitTypeDef USART_InitStructure;USART_ART_BaudRate = 115200; //波特率115200USART_ART_WordLength = USART_WordLength_8b; //8位数据USART_ART_StopBits = USART_StopBits_1; //停止位1位USART_ART_Parity = USART_Parity_No ; //无校验位USART_ART_HardwareFlowControl=USART_HardwareFlowControl_None;USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);4.配置中断,可以跳过USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);5.打开串口USART_Cmd(USART1, ENABLE);例:void COM_Init(void){GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);/* 配置USART1 Tx (P A9) */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出最大频率为50MHz GPIO_Init(GPIOA, &GPIO_InitStructure);/* 配置USART1 Rx (P A10) */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入模式GPIO_Init(GPIOA, &GPIO_InitStructure);USART_ART_BaudRate = 115200; //波特率115200 USART_ART_WordLength = USART_WordLength_8b; //8位数据USART_ART_StopBits = USART_StopBits_1; //停止位1位USART_ART_Parity = USART_Parity_No ; //无USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);USART_Cmd(USART1, ENABLE);}USART串口使用1.发送字符USART_SendData(USART1, '1'); //往串口1发送字符1while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待发送结束2.接收字符unsigned char a;if((USART_GetFlagStatus(USART1, USART_IT_RXNE)==RESET))//有数据来{while((USART_GetFlagStatus(USART1, USART_IT_RXNE)==RESET)) ;//等待接收完成a=USART_ReceiveData(USART1);//接收数据}例:unsigned char ch;if((USART_GetFlagStatus(USART1, USART_IT_RXNE)==RESET))//有数据来(在中断中,可去掉){while((USART_GetFlagStatus(USART1, USART_IT_RXNE)==RESET));//等待接收完成;ch=USART_ReceiveData(USART1);//接收数据delay(10); //不加延时会产生堵塞USART_SendData(USART1, ch); //往串口1发送字符1while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);}3.C标准输出函数Printf 的使用:包含头文件#include <stdio.h> //包含标准c库的输入输出头文件添加函数int fputc(int ch, FILE *f){USART_SendData(USART1, (unsigned char) ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) ;return ch;}然后就可以在程序中调用printf()了4.串口中断处理函数在项目中添加misc.c文件,找到stm32f10x_conf.h文件的第48行/*#include "misc.h"*/去掉两边的注释符配置中断优先级例:NVIC_InitTypeDef NVIC_InitStructure; //定义数据结构体NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);//将中断矢量放到Flash的0地址NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//设置优先级配置的模式,详情请阅读原材料中的文章//使能串口中断,并设置优先级NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); //将结构体丢到配置函数,即写入到对应寄存器中打开串口中断(USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);串口接受中断)找到stm32f10x_it.c中USART的中断子函数如void USART1_IRQHandler(void){};也可以将此函数移动到其它文件下。
STM32笔记(六)

STM32笔记(六)SD卡的读写和FatFS文件系统因为要用,学习了一下SPI操作SD卡,同时移植了一个免费开源的FAT 文件系统:FatFS。
感觉挺好,在单片机上实现了读写文件的操作,接下来就可以解释我的G代码咯!我的SD卡底层操作参考了网上几种常见的代码,但又对其结构做了一定的优化,至少看起来用起来比较方便。
既可以作为文件系统的diskio使用,也可以直接使用底层函数,把SD卡作为一块flash读写。
FatFs文件系统体积蛮小,6-7K足矣,对于128Kflash的STM32来说很合适,代价不大。
同时可移植性很高,最少只需要4个函数修改既可以实现文件系统的移植。
相关文件系统的介绍请看这里。
这里给一套比较完整的参考资料,包括fatfs文件系统的原版资料、几个重要的手册和网上下载的代码。
/bbs/bbs_content.jsp?bbs_sn=3210864&bbs_page_no =1&bbs_id=3020下面是我的代码:其中底层的SPI总线对SD卡的操作在SPI_SD_driver.c/h中,而FATFS 的移植文件diskio.c中对磁盘的操作函数中将调用底层的操作函数。
下面是一些底层操作函数:u8 SPI_ReadWriteByte(u8 TxData); //SPI总线读写一个字节u8 SD_WaitReady(void); //等待SD卡就绪u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc); //SD卡发送一个命令u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc); //SD卡发送一个命令,不断线u8 SD_Init(void); //SD卡初始化u8 SD_ReceiveData(u8 *data, u16 len, u8 release); //SD卡读数据u8 SD_GetCID(u8 *cid_data); //读SD卡CID u8 SD_GetCSD(u8 *csd_data); //读SD卡CSD u32 SD_GetCapacity(void); //取SD卡容量u8 SD_ReadSingleBlock(u32 sector, u8 *buffer); //读一个sect oru8 SD_WriteSingleBlock(u32 sector, const u8 *buffer); //写一个sect oru8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count); //读多个sect oru8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count); //写多个se ctor这是diskio.c中的一段代码,在disk初始化中,我们调用了SPI_SD_drive r.c中的SD卡初始化函数。
SD

在进行SD卡初始化前,应先配置STC单片机的SPI。
这部分请参照例程(27)。
SD卡(Secure Digital Memory Card)中文翻译为安全数码卡,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。
SD 卡由日本松下、东芝及美国SanDisk 公司于1999 年8 月共同开发研制。
大小犹如一张邮票的SD记忆卡,重量只有2克,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性。
SD卡一般支持2 种操作模式:1,SD卡模式;2,SPI模式;主机可以选择以上任意一种模式同SD 卡通信,SD 卡模式允许4 线的高速数据传输。
SPI 模式允许简单的通过SPI 接口来和SD 卡通信,这种模式同SD 卡模式相比就是丧失了速度。
SD卡的引脚排序如下图所示:SD卡引脚功能描述如下表所示: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!。
下面介绍一下SPI模式下几个重要的操作命令:其中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 card初始化时的总线设置

#define HIGH_SPEED_MAX_DTR 50000000 // HS模式的最大频率是50MHz,3.3V #define UHS_SDR104_MAX_DTR 208000000 // SDR104模式的最大频率是208MHz,1.8V #define UHS_SDR50_MAX_DTR 100000000 // SDR50模式的最大频率是100MHz,1.8V #define UHS_DDR50_MAX_DTR
50000000 // DDR50模式的最大频率是50MHz,1.8V #define UHS_SDR25_MAX_DTR UHS_DDR50_MAX_DTR // SDR模式的最大频率是50MHz,1.8V #define UHS_SDR12_MAX_DTR 25000000 // HS模式的最大频率是25MHz,1.8V DS模式的最大频率是25Mhz,3.3V,但是在代码里面并没有定义出来?? (1)对于uhs来说,会在设置总线速度模式的时候,把最大频率设置到card->sw_caps.uhs_max_dtr中 static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status) case UHS_SDR104_BUS_SPEED: card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; case UHS_DDR50_BUS_SPEED: card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; case UHS_SDR50_BUS_SPEED: card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; case UHS_SDR25_BUS_SPEED: card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; case UHS_SDR12_BUS_SPEED: card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; (2)对于HS模式的card来说,最大频率会设置到card->sw_caps.hs_max_dtr中
STM32学习笔记(初学者快速入门)a

#include "stm32f10x_conf.h" //#endif 再次编译,果然就 OK 了。可是,可是,也不能就这么去掉啊,怎么办呢?万能 的网啊,一搜果然就有了。
说说我怎么学的吧。 找个例子,如 GPIO,可以看到其结构如下: SOURCE(文件夹)
- APP(文件夹) -CMSIS(文件夹) -STM32F10x_StdPeriph_Driver(文件夹) Lis(文件夹) OBJ(文件夹) 其中 SOURCE 中保存的是应用程序,其中又有好多子文件夹,而 CMSIS 文件 夹中和 STM32F10x_StdPeriph_Driver 文件夹中是 ST 提供的库,这样,如果要 做新的工程只要将这个文件夹整个复制过来就行,其中 APP 中保存自己的代码。 因为我们用 51 单片机时一般比较简单,有时就一个文件,所以通常不设置专 门的输出文件夹,而这里做开发,通常会有很多个文件加入一个工程中,编译过 程中会产生很多中间文件,因此设置专门的文件夹 LIS 和 OBJ 用来保存中间文 件。 下面就将设置简单描述一下。 将复到过来的 GPIO 根目录下的所有文件删除,因为我们要学着自己建立工程。
到设置 C/C++页面 在那个 define 中加入“USE_STDPERIPH_DRIVER,STM32F10X_HD” 当然,去掉条件编译前面的注释,回到原样。 再次编译,一切顺利。可是,原来的工程例子也没有加这个啊,怎么回事呢?再 次打开原来的例子,找到 stm32f10x.h,可以看到有这么一行:
sd卡协议分析

sdMmc目录第一章 SD卡系统概念 3§1.1 SD卡概述 3§1.2 SD卡的系统特征 3§1.3 SD卡的系统概念 4§1.4 SD卡的总线传输 6§1.5 SD卡的引脚 10§1.6 SD卡主要寄存器介绍 12§1.7 SD卡子系统结构 14第二章 SD卡初始化及状态转换 16§2.1SD卡状态及初始化过程 16§2.2SD卡数据传输过程 181.SD卡基础1.SD卡概述SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制,同时三个公司联合成立了SD协会,并制定SD卡相关的协议标准。
SD卡协议主要包括物理层协议、SD卡控制器设计手册、SDIO卡手册三部分。
其中SDIO指的是安全数字输入输出卡(Secure Digital Input and Output Card),是在SD标准上定义了一种外设接口,通过SD的I/O接脚来连接外围设备,并且通过SD上的 I/O数据接位与这些外围设备进行数据传输。
相关的一些设备为:GPS、相机、Wi-Fi、调频广播、条形码读卡器、蓝牙等。
SDIO本质上是一种接口,通过该接口可以连接一些其他功能的设备而非仅仅是存储设备。
1.2 SD卡的系统特征(SD物理层协议v2.0)∙针对移动和固定应用;∙存储容量:标准容量SD存储卡:最高2G高容量SD存储卡:2G以上(在该规范版本中,最高32G)∙电压范围:高电压SD存储卡—操作电压范围:2.7~3.6V双电压SD存储卡—操作电压范围:低电压范围(T.B.D)和2.7~3.6V∙分为只读卡和读/写卡;∙默认模式:时钟频率可在0~25MHz间变化,高达12.5MB/s 的接口速度(使用4条并行数据线) ;∙高速模式:时钟频率可在0~50MHz间变化,高达25MB/s 的接口速度(使用4条并行数据线) ;∙支持高速,电子商务和将来功能的转换功能命令;∙存储域错误纠正;∙读操作期间移去卡,内容不损坏;∙内容保护机制—符合SDMI标准的最高安全性;∙卡的密码保护(CMD42 - LOCK_UNLOCK);∙机械开关的写保护特性;∙内嵌的写保护特性(永久或暂时) ;∙卡检测(插入/移去) ;∙应用特定命令;∙舒适的擦除机制∙通信通道协议属性;∙SD存储卡外形尺寸:标准尺寸SD存储卡(32*24*2.1mm) 。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
while(1)世界STM32学习笔记
STM32学习笔记
----SD卡V2.0协议初始化
《STM32学习笔记》由while(1)世界会员所总结的学习笔记,
供大家参考学习,有问题可以在while(1)世界的STM32版块提问,
共同讨论。
这一笔记是有会员liklon总结的学习笔记,如果有问题可以在
while(1)世界的STM32版块发帖提问!STM32版块也提供源代码下
载。笔记具体类容如下:
while(1)世界STM32学习笔记
现在使用的4G的SD卡,小于或等于2G的卡是属于标准SD卡,而大于2G的卡
小于32G的卡是大容量SD卡,也就是SDHC卡。对于SDHC卡的初始化和操作要
使用V2.0协议。看了几天的SD卡v2.0协议,现在总结一下啊。
首先是一个流程图,这个图在官方资料上有:
SPI模式下SD卡部分操作指令
命令参数回应描述
CM0(0X00)NONER1
复位SD卡
CMD9(0X09)NONER1
读取卡特定寄存器
CMD10(0X0A)NONER1读取卡标志寄存器
CMD16(0X10)块大小R1设置块的大小(字节数)
CMD17(0X11)地址R1
读取一块的数据
CMD24(0X18)地址R1
写入一块的数据
while(1)世界STM32学习笔记
CMD41(0X29)NONER1开始卡的初始化
CMD55(0X37)NONER1
引用命令的前命令
CMD59(0X3B)最后一位有效R1
设置CRC开启(1)或关闭(0)
SD卡R1回应格式:
BIT
7
BIT6BIT5BIT4BIT3BIT2BIT1BIT0
0参数错误地址错误连续擦除错误命令CRC错误非法命令擦除复位IDLE状态
卡会根据不同的时候处在不同的状态
第一步操作:复位 第二步操作发送CMD8来分辨卡的类型,是V2.0卡还是V1.0卡或MMC卡,还可 ApplicationNote: 判断Checkvoltage按照如下标准: 根据流程图就可以看出发送CMD8后SD卡的类型基本上分了两类。 SD_WriteCommand(CMD41,0x40000000,0X01);//发送ACMD41,流程图写的如果主 前面的R1应该为0。 对于V1.0和MMC卡的初始化应该照着流程图搞也是一样的。
SD卡上电后先发送(>74个时钟),因为SD卡有个供电电压上升过程需要大约
64个时钟,之后的10个时钟是用来与SD卡同步(参考《例说STM32》)。参考代
码:
for(count=0;count<15;count++)
SPI_WriteReadByte(0xff);//产生74个以上的脉冲
SD卡默认是SD模式,现在用STM32去操作,切换为SPI模式后更好操作。所以
while(1)世界STM32学习笔记
在片选为低时发送CMD0,此时卡进入IDLE状态,因为CMD0回应的命令是R1,
根据上面R1的回应格式可以看出我们自需要检查最低位就知道是否处于IDLE
状态。参考代码:
do
{
tmp=SD_WriteCommand(CMD0,0,0X95);//发送SD
count++;
}while((tmp!=0x01)&&(count
以检测CMD8响应返回的数据判断是否支持给定的工作电压范围。
根据流程图可以看出。
1.如果SD卡支持当前的电压就会返回R7,并包含CMD8的参数部分,其中包括:
Checkvoltage和checkpattern。
2.如果SD卡不支持当前的工作电压则不会返回任何响应信息,继续处在IDLE
状态。如果是V1.0x的SD卡也不会有响应。
3.在PLV2.0(physicallayerversion2.0)下,在首次执行ACMD41之前,必须
执行CMD8指令,用以初始化SDHC卡,SDHC卡根据是否接收到CMD8指令来鉴别
控制器是否支持PLV2.0协议。使用低电压的控制器也必须在ACMD41命令之前发
送CMD8,避免可以工作在两种电压模式下的SD卡因为没有接收到CMD8,而默
认工作在高电压环境下,被误认为是只支持高电压工作模式。
Itisrecommendedtouse‘10101010b’forthe‘checkpattern’.
R7的格式:
while(1)世界STM32学习笔记
从上面可以看到,R7为5个字节,在发送CMD8后,SD卡响应,发送回来的第一
个字节就是R1,之后的4个字节中就包含了Checkvoltage和checkpattern。
下面是仿真的结果:
第三步:由ACMD41来初始化SD卡,SD卡的初始化从收到ACMD41开始。
ACMD指令的HCS(HostCapacitySupport)位如果设定为1的话,表明控制器
支持SDHC卡,否则表示不支持。
SD卡初始化和识别过程:
在CMD8命令发送之后的ACMD41指令其功能有所扩展,在参数里多了HCS部分,
在响应里面多了CCS(CardCapacityStatus)部分。HCS参数会被不响应CMD8
命令的SD卡所抛弃。控制器向不响应CMD8的卡发送ACMD41指令时,HCS位应
while(1)世界STM32学习笔记
该设置为零0。如果向SDHC卡发送HCS位为0的ACMD41命令,SDHC卡返回的响
应,其busy标识位永远为0,代表忙状态。HCS标识位用来表明SD卡是否已经
完成初始化,如果未完成,HCS为零,否则为1,如果HCS为0,控制器会重复
发送ACMD41指令,SD卡只检查首次接收到的ACMD41指令的HCS位。
按照流程图,现在发送ACMD41可以用来分辨是否为高容量卡。
机支持大容量就将HCS置1.所以发送0x40000000
因为ACMD41为应用型指令,所以前面要加上CMD55一起使用。
SD_WriteCommand(CMD55,0,0x01);
SD_WriteCommand(CMD41,0x40000000,0X01);
一直发送这两条指令,直到卡准备好。处于Ready状态。
所以接收到响应为0之后就可以开始读取OCR信息。并检测bit30位(CCS位),
如果此位是1就是高容量卡,如果为0则是标准SD卡。读取OCR的指令是CMD58,
其响应是R3:
之后再接收4个字节的数据。并判断bit30位。就可以判断是SDV2.0还是
SDV2.0HC。初始化完成
上面的只是个人的理解,参考了《SD卡2.0协议》,《SD卡协议学习点滴》,《例
说STM32》.