STM32学习笔记之SD卡V2.0协议初始化
- 格式:pdf
- 大小:452.48 KB
- 文档页数:6
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]。
摘要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世纪是一信息传递及应用高速的时代,信息在人类社会活动中已经必不可缺,使用嵌入式系统的电子产品已经在人们的日常生活中广泛普及应用。
一、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笔记(六)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卡初始化前,应先配置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。
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) 。
STM32单片机的复用端口初始化的步骤及方法STM32有好几个串口。
比如说STM32F103ZET6有5个串口,串口1的引脚对应的IO为PA9,PA10.PA9,PA10默认功能是GPIO,所以当PA9,PA10引脚作为串口1的TX,RX引脚使用的时候,那就是端口复用。
复用端口初始化有几个步骤:1)GPIO端口时钟使能。
要使用到端口复用,当然要使能端口的时钟了。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);2)复用的外设时钟使能。
比如你要将端口PA9,PA10复用为串口,所以要使能串口时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);3)端口模式配置。
在IO复用位内置外设功能引脚的时候,必须设置GPIO端口的模式,至于在复用功能下GPIO的模式是怎么对应的,这个可以查看手册。
所以,我们在使用复用功能的是时候,最少要使能2个时钟:1)GPIO时钟使能;2)复用的外设时钟使能同时要初始化GPIO以及复用外设功能串口设置的一般步骤可以总结为如下几个步骤:1)串口时钟使能,GPIO时钟使能2)串口复位3)GPIO端口模式设置4)串口参数初始化5)开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)6)使能串口7)编写中断处理函数端口重映射:(暂略)中断量控制:STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。
而我们常用的就是这68个可屏蔽中断,但是STM32的68个可屏蔽中断,在。
手把手教你STM32笔记stm32f1031、io口处理io口包含7个寄存器配置寄存器两个:crl(32),crh(32)数据寄存器两个:idr(32),odr(32),但是他们就用了16边线位登位寄存器:bsrr(32)登位寄存器:brr(16)锁存寄存器:lckr(32)常用的有前面四个:其中前面两个是用来设置的,后面两个是用来操作的。
每个io 口占用四位进行设置(低两位是mode,高两位是cnf),每组16个,总共需要64个位设置,分别从crl低位开始,到crh的高位结束。
每个io口四位二进制的常用布局:演示输出模式(adc):0x0;推挽输出模式(输出口50mhz):0x3;上/下拉输入模式(输入口用):0x8;复用输出(第二供能):0xb;stm32f407自学笔记1、系统时钟的设置:stm32_clock_init(168,4,2,7);参数分别就是:plln,pllm,pllp,pllqhse分频pllm之后为vco的输入,一般vco的输入要求为1~2mhz,一般建议取为2mhz,防止pll抖动。
vco输出是输入的plln倍频,sysclk在去pll输出时,sysclk=pll=hse/pllm*plln/pllp而pllq是为48mhz时钟配置用的,clk48=hse/pllm*plln/pllq所以要设置系统时钟为168mhz时候推荐的参数取值为sysclk=pll=hse/pllm*plln/pllp=8/4*168/2=168mhzclk48=hse/pllm*plln/pllq=8/4*168 /7=48mhz2、延时函数设置:delay_init(168);延时函数参数为系统时钟sysclk初始化后就可以调用延时函数:delay_ms(ms);参数不能大于65536,因为参数是16位数delay_us(us);参数不能大于7989153、普通io的使用a.首先是使能时钟rcc->ahb1enr|=1<<5;在该寄存器适当的边线1即可b.io口模式设置:gpio_set(gpiof,pin9|pin10,gpio_mode_out,gpio_otype_pp,gpio_speed_100m,gpio_pup d_pu);参数分别就是:gpiox,pin9|pin10(具体对应的口,可以使用与的关系)因为每种占一位#definepin0#definepin1#definepin2#definepin3#definepin4#definepin5#definepin6#definepin7#definepin8#definepin9#definepin10#definepin11#definepin12#definepin 13#definepin14#definepin151<<01<<11<<21<<31<<41<<51<<61<<71<<81<<91<<101<<111<<121<<131<<141<<15mode:四种,各个模式只能设置一种#definegpio_mode_in0#definegpio_mode_out//普通输出模式1//普通输出模式#definegpio_mode_af#definegpio_mode_ain输入推挽或者开漏挑选:#definegpio_otype_pp#definegpio_otype_od23//af功能模式//演示输出模式01//推挽输入//开漏输入推挽输出可输出强的高、低电平,用于连接数字器件开漏输入相等于三极管的集电极,电流型驱动,只可以输入弱的低电平,高电平需外扎。
奋斗版STM32开发板V2.0的硬件说明1. 供电电路:AMS1117-3.3输入+5V,提供3.3V的固定电压输出,为了降低电磁干扰,C1-C5为CPU 提供BANK电源(VCC:P50、P75、P100、P28、P11 GND:P49、P74、P99、P27、P10)滤波。
CPU的模拟输入电源供电脚VDDA(P22)通过L1 22uH的电感与+3.3V VDD电压连接,CPU的模拟地VSSA(P19)及VREF-(P20)通过R1 0欧电阻与GND连接。
VREF+(P21)采用VDDA(P22)电源基准。
AMS1117-2.5输入+5V,提供2.5V的固定电压输出,为MP3电路VS1003提供所需的电压。
为RTC的备份电源采用V1 3.3V锂离子片状电池。
2. 启动方式设置:Boot1—Boot0(P37,P94): x0: 内部程序存储区启动01:系统存储区启动(为异步通信ISP编程方式)在此将BOOT1始终设置为0, BOOT0为可变的状态,在正常模式下将其置为0,在ISP 编程时将其置为1。
用JP1跳线块设置,开路为ISP模式,短路为正常运行模式。
3. 时钟源电路:外部晶体/陶瓷谐振器(HSE)(P12、P13):B1:8MHz晶体谐振器,C8,C9谐振电容选择10P。
系统的时钟经过PLL模块将时钟提高到72MHz。
低速外部时钟源(LSE)(P8、P9):B2: 32.768KHz晶体谐振器。
C10,C11谐振电容选择10P。
注意:根据ST公司的推荐, B2要采用电容负载为6P的晶振,否则有可能会出现停振的现象。
4. SPI存储电路:D2 AT45DB161(2M Bytes)CPU采用SPI1端口PA7-SPI1-MOSI(P32)、PA6-SPI1-MISO (P31)、PA5-SPI1-SCK(P30)、PC4-SPI1-CS2(P33)控制读写访问, SPI1地址:0x4000 3800 - 0x4000 3BFF5. 显示及触摸接口模块:显示器采用2.4” TFT320X240LCD(控制器ILI9325), 采用CPU的FSMC功能,LCD片选CS采用FSMC_NE1(P88),FSMC_A16(P58)作为LCD的RS选择,FSMC_nWE(P86)作为LCD的/WR, FSMC_nOE(P85)作为LCD的/RD, LCD的RESET脚用CPU的PE1(P98)(LCD-RST),FSMC_D0---FSMC_D15和LCD的D1-D8 D10-D17相互连接,触摸屏接口采用SPI1接口,片选为PB7-SPI1-CS3,由于LCD背光采用恒流源芯片PT4101控制,采用了PWM控制信号控制背光的明暗, PWM信号由PD13-LIGHT-PWM来控制。
单片机读写SD卡教程引言:SD卡(Secure Digital Card)是广泛应用于各类数字设备上的一种存储介质。
它小巧轻便,可靠性高,容量大,因此在各种嵌入式系统中都广泛使用。
本教程将介绍如何使用单片机读写SD卡,包括初始化SD卡、读写数据等基本操作。
一、硬件准备在开始之前,我们需要准备以下硬件设备:1.一个支持SPI协议的单片机开发板(例如STC89C51、STM32等);2.一个SD卡插槽,或者是一个带有SD卡插槽的扩展板;3.杜邦线、面包板等连接器。
二、软件准备除了硬件设备,我们还需要准备以下软件工具:1. Keil C51、IAR、Keil MDK等单片机编译工具;2. SD卡相关的库文件,例如FatFs;3.一个用于测试的程序(可以是一个简单的读写数据的程序)。
三、连接SD卡插槽将SD卡插入到对应的插槽中,并将插槽与单片机的硬件SPI接口连接。
根据不同的开发板,连接方式可能有所不同,一般SPI接口包括SCK(时钟线)、MOSI(主机输出从机输入线)、MISO(主机输入从机输出线)和CS(片选线)等。
四、编写读写SD卡的程序在开始编写程序之前,我们需要先了解SD卡的工作原理。
SD卡通过SPI总线与单片机进行通信,通过发送特定的命令和参数实现读写操作。
以下是一个简单的读写SD卡的流程:1.初始化SD卡a.发送CMD0命令,将SD卡设置为SPI模式;b.发送CMD8命令,验证SD卡是否支持高速SPI模式;c.发送ACMD41命令,等待SD卡初始化完成。
2.读写数据a.发送CMD17命令,指定要读取的扇区地址;b.等待SD卡回应,确认读取命令执行成功;c.读取数据;d.发送CMD18命令,继续读取下一个扇区;e.重复步骤c和d,直到读取完所有数据;f.发送CMD12命令,停止读取。
g.发送CMD24命令,指定要写入的扇区地址;h.等待SD卡回应,确认写入命令执行成功;i.写入数据;j.发送CMD25命令,继续写入下一个扇区;k.重复步骤i和j,直到写入完所有数据;l.发送CMD12命令,停止写入。
stm32 flash 读取数据初始化函数STM32是一款32位ARM Cortex-M系列的微控制器,具有强大的性能和丰富的外设。
在STM32中,Flash存储器是一种用于存储程序代码或配置数据的非易失性存储器。
在本文中,我们将讨论如何读取Flash存储器中的数据,并分享一些与初始化函数相关的内容。
一、Flash存储器读取数据为了读取Flash存储器中的数据,首先需要了解存储器的基本结构。
在STM32中,Flash存储器被分为多个扇区(Sector)。
每个扇区的大小通常为2KB或4KB,并通过一个Flash地址来访问。
读取Flash存储器的一种常见方法是使用指针操作。
首先,您需要定义一个指向Flash存储器地址的指针变量。
然后,您可以使用该指针访问存储器中的数据。
以下是一个简单的示例代码:c#include "stm32f4xx.h"#define FLASH_ADDRESS 0x08008000 Flash存储器的起始地址uint32_t *flash_data = (uint32_t *)FLASH_ADDRESS; 定义一个指向Flash 存储器的指针变量int main(void){uint32_t data = *flash_data; 读取存储器中的数据在这里可以进行后续操作...while (1){主循环}}在上述示例中,我们首先定义了一个Flash存储器的起始地址`FLASH_ADDRESS`,然后将其转换为指向32位数据类型的指针变量`flash_data`。
接下来,我们通过间接引用指针`flash_data`来读取存储器中的数据,并将其存储在`data`变量中。
您可以在后续的代码中使用`data`变量进行进一步的操作。
需要注意的是,读取Flash存储器中的数据时,需要确保访问的地址处于有效范围内,并且使用正确的数据类型进行读取。
此外,读取Flash存储器中的数据与写入数据不同,不需要先擦除相应的扇区。
1.1 SD卡模式选择SD卡上电后进入SD模式,如果SD卡在接收CMD0命令时CS为0则SD卡进入SPI模式并且应答为R1应答,SD卡处于idle状态,回到SD模式的唯一方法就是重新上电。
1.2 SD卡SPI模式下初始化1、Clock:上电后主机应发送至少74个时钟,在这期间应保持CS为高电平,然后SD卡进入idle模式。
2、进入SPI模式:如果在接受CMD0命令时CS为低电平,则SD卡进入SPI模式,CMD0命令没有参数。
CMD0的应答R1格式,R1应答的内容定义为:3、CMD8:初始化发送CMD0后,SD卡并不知道当前的电压是否合适,为了验证电压Physical LayerSpecification Version 2.00定义了CMD8命令;初始化发送完CMD0后,在发送ACMD41之前需发送CMD8,以便初始化High Capacity SD卡,如果SD卡不能在该电压下工作,则SD卡不作应答,并处于idle状态,否则SD卡将作出应答并echo出命令中设置的电压范围和check pattern。
CMD8命令格式:VHS: 0000b、Others Not Defined0001b 2.7-3.6V0010b Reserved for Low Voltage Range0100b、1000b ReservedCheck Pattern:可为任意8位的数,推荐使用0xaa。
CMD8应答:4、发送ACMD41:ACMD命令是在发送需要的命令之前发送一个CMD55命令组成的,ACMD41命令由CMD55和CMD41组成,CMD55命令没有参数,应答为R1应答,HCS=1表明主机支持High Capacity SD卡,HCS=0表明不支持。
发送CMD41命令,判断应答是否表明表明SD卡仍然处于初始化阶段;R1应答的bit0为1表明处于idle状态,SD卡还在初始化阶段。
5、初始化完成:当发送ACMD41命令的应答为0x00时表明SD卡已完成ACMD41发起的初始化过程。
STM32与SD卡通信各层分析最近做了一些STM32和SD卡通信的一些思考,一直以来SD的驱动和应用困扰了我很久,寒假的时候看到SD简化版物理层协议的时候就傻掉了,看到SD的驱动快3000行的代码也动摇了。
这几天几种地看了一下SD卡的相关内容,总结了一些体会,感觉也没有那么恐怖了。
我决定从分层上来讨论SD的驱动和应用,因为这样可以构建一个清晰的逻辑,且不知哪位计算机大师曾说过:一切计算机问题都可以用分层的方法来解决。
我自己把SD卡从驱动到应用共分为4层,从下至上依次为:驱动层、物理层、文件系统层、应用层。
下面一一来介绍各层的一些重要的操作。
1)驱动层驱动层,对应到ST的库,就是stm32f10x_sdio.c/.h这个两文件。
其实使用任何一个STM32的外设,只要用库函数都离不开这一对互相对应的.c/.h文件。
对于SDIO外设来说,它就是用来操作寄存器的,由于涉及ST库函数的编写,没能力参透,在此不赘述它的实现过程。
2)物理层这一层可以说是承上启下的一层,下接驱动层,用于操作寄存器,上接文件系统层,用于统一管理文件,可谓整个SD驱动的核心代码。
其实,如果对于SD的要求不高,可以直接在这一层上面进行文件操作,只是没有文件系统操作起来实在不便。
之所以叫物理层是因为这一部分的代码主要参考了SD卡物理层简化协议这样一个东西。
这个协议规定了控制器对SD卡操作的各种指令的格式和操作时序。
这一层对应了源代码中的sdio_sdcard.c/.h这两个文件,那么它主要实现了什么功能呢?这一层最重要的一个函数就是SD_Init()SD卡的初始化函数。
这函数包括了SD卡的上电、识别、卡初始这三个重要步骤,分别对应两个子函数SD_PowerOn、SD_IniTIalizeCards(),而SD_IniTIalizeCards()的返回值包含了卡的类型信息。
这两个子函数的实现则是通过STM32内置的SDIO控制器发送CMD命令完成,这个命令的发送要严格遵守SD协议的流程图,而且要及时进行标志位判断,否则很容易程序跑飞了。
STM32学习笔记:IIC通信协议详解(附带软件模拟源码)介绍IIC 即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦半导体公司设计出来的⼀种简单、双向、⼆线制、同步串⾏总线。
它是⼀种多向控制总线,也就是说多个芯⽚可以连接到同⼀总线结构下,同时每个芯⽚都可以作为实时数据传输的控制源。
这种⽅式简化了信号传输总线接⼝。
那么也就是说,只要收发双⽅同时接⼊SDA(双向数据线)、SCL(同步时钟线)便可以进⾏通信。
I2C总线的⼯作速度分为 3 种模式(实际上,IIC的通信速率由SCL决定):S(标准模式),测量与控制场合,100kbit/s;F(快速模式),速率为 400kb/s;(默认,⽬前普遍⽀持的最⼤速率)Hs(⾼速模式),速率为 3.4Mb/s(⽀持这种标准的器件很少)。
IIC接线框图⼀般情况下,SCL与SDA默认由上拉电阻拉⾼。
这也是为了⽅便通信协议。
多机连接时,为了区分不同的从机,我们会使⽤⾃定义的地址码进⾏区分。
IIC的通信状态IIC的通信要注意以下6个知识点:1.空闲状态2.开始信号3.停⽌信号4.应答信号5.数据的有效性6.数据传输空闲状态在IIC中规定,当SDA、SCL同时为⾼电平时,视为空闲状态。
注意,这个规定是通信设备通信前的判断条件。
开始信号 & 停⽌信号在IIC中规定,当SCL为⾼电平,且SDA从⾼到低的跳变时,视为数据开始传输;在IIC中规定,当SCL为⾼电平,且SDA从低到⾼的跳变时,视为数据停⽌传输;数据有效性 & 数据传送 & 应答信号(ACK)数据有效性:在传输数据时,应保证数据在SCL的上升沿到来之前准备好,并在下降沿到来之前必须稳定。
(由于在电路中,电平的跳变往往伴随着⽑刺。
)数据传送:在I2C总线上传送的每⼀位数据都有⼀个时钟脉冲相对应(或同步控制),即在SCL串⾏时钟的配合下,在SDA上逐位地串⾏传送每⼀位数据。
Erased v. 抹去(erase的过去分词);消除Programmed adj. 程序化的,程控的Verified adj. 已查清的,已证实的,,已验证的stm32f10x.h 类似于51单片机中的头文件reg51.h 一样,定义了如P0、P1等特殊寄存器的名称与实际物理地址相对应stm32f10x_conf.h 是用户需要配置的头文件,当我们需要用到某部分外设驱动时,我们只需要将该部分外设的头文件包含进来即可。
configured adj. 配置;配置的故,添加外设驱动文件stm32f10x_xxx.c 的时候,可以把全部驱动文件全部添加进来,然后通过stm32f10x_conf.h 文件选择性的添加;也即,只有在stm32f10x_conf.h 文件中配置的文件才会被编译。
Stm32f10x_it.c 和Stm32f10x_it.h 这两个文件里面是中断函数,里面内容为空,并没有写任何中断服务程序,需用户添加;it —interrupt vi. 打断;打扰Core_cm3.c 和Core_cm3.h 是位于Libraries/CMSIS/CM3文件夹下的Coresupport的文件,它们是CMSIS标准的核内设备函数层的M3核通用的源文件和头文件,其作用是为那些采用Cortex-M3核设计SOC的芯片的外设提供一个进入M3内核的接口,这两个文件在其他公司的M3系列芯片也是相同的。
什么是JTAG接口JTAG(Joint Test Action Group联合测试行动小组) 是一种国际标准测试协议,主要用于芯片内部测试及对系统进行仿真、调试。
JTAG 技术是一种嵌入式调试技术,它在芯片内部封装了专门的测试电路TAP (Test Access Port 测试访问口),通过专用的JTAG测试工具对内部节点进行测试。
TAP控制器的状态机通过TCK和TMS进行状态的改变,实现数据和指令的输入。
目前大多数比较复杂的器件都支持JTAG 协议,如ARM 、DSP 、FPGA 器件等。
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》.