STM32F103 SDID模块SDHC卡读写
初始化
SDIO
时钟、端口初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_SDIO|RCC_AHBPeriph_DMA2,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
SDIO配置
注意在cmd41响应完成之前,卡位上电完成,SDIO上的时钟线的频率应低于400k
SDIO_DeInit();
SDIO_InitStructure.SDIO_ClockDiv = 0xB2;
SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;
SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;
SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;
SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
SDIO_Init(&SDIO_InitStructure);
SDIO上电
SDIO_SetPowerState(SDIO_PowerState_ON);
SDIO时钟线使能
至此SDIO模块已经开始工作
SDIO_ClockCmd(ENABLE);
SD卡初始化
进入空闲模式
SDIO_CmdInitStructure.SDIO_Argument = 0x0;
SDIO_CmdInitStructure.SDIO_CmdIndex = 0;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_No;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
while(SDIO_GetFlagStatus(SDIO_FLAG_CMDSENT) == RESET);
SDIO_ClearFlag(0x000005FF);
上电
SDIO_CmdInitStructure.SDIO_Argument = (u32)0x000001AA;
SDIO_CmdInitStructure.SDIO_CmdIndex = 8; //cmd8
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; //r7
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
while((SDIO->STA&(1<<6))==0);
SDIO_ClearFlag(0x000005FF);
do
{
SDIO_CmdInitStructure.SDIO_Argument = 0x00;
SDIO_CmdInitStructure.SDIO_CmdIndex = 55;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
while((SDIO->STA&(1<<6))==0);
SDIO_ClearFlag(0x000005FF);
SDIO_CmdInitStructure.SDIO_Argument = 0x80100000;
SDIO_CmdInitStructure.SDIO_CmdIndex = 41;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; //r3
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
while((SDIO->STA&(1<<6))==0);
SDIO_ClearFlag(0x000005FF);
res=SDIO->RESP1;
}while(res>>31!=1);
获取信息
此时卡已经上电完成可以把时钟调高频率
SDIO_InitStructure.SDIO_ClockDiv = 0x04;//12Mhz
SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;
SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;
SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;
SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
SDIO_Init(&SDIO_InitStructure);
SDIO_CmdInitStructure.SDIO_Argument = 0x0;
SDIO_CmdInitStructure.SDIO_CmdIndex = 2;//cmd2
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
while((SDIO->STA&(1<<6))==0);
SDIO_ClearFlag(0x000005FF);
CID_Tab[0]=SDIO->RESP1;
CID_Tab[1]=SDIO->RESP2;
CID_Tab[2]=SDIO->RESP3;
CID_Tab[3]=SDIO->RESP4;
SDIO_CmdInitStructure.SDIO_Argument = 0x00;
SDIO_CmdInitStructure.SDIO_CmdIndex = 3; //cmd3
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; //r6
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
while((SDIO->STA&(1<<6))==0);
SDIO_ClearFlag(0x000005FF);
rca=SDIO->RESP1;
SDIO_CmdInitStructure.SDIO_Argument = 0x0;
SDIO_CmdInitStructure.SDIO_CmdIndex = 9;//cmd9
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
while((SDIO->STA&(1<<6))==0);
SDIO_ClearFlag(0x000005FF);
CSD_Tab[0]=SDIO->RESP1;
CSD_Tab[1]=SDIO->RESP2;
CSD_Tab[2]=SDIO->RESP3;
CSD_Tab[3]=SDIO->RESP4;
选中卡
选中卡后就初始化完成了
SDIO_CmdInitStructure.SDIO_Argument = rca;//·¢ËÍCMD7,Ñ¡Ôñ¿¨,¶ÌÏìÓ¦
SDIO_CmdInitStructure.SDIO_CmdIndex = 7;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);//·¢ËÍCMD7,Ñ¡Ôñ¿¨,¶ÌÏìÓ¦
while((SDIO->STA&(1<<6))==0);
SDIO_ClearFlag(0x000005FF);
读取一个块数据
这里使用DMA读取,默认读取过程中没有错误
SDIO_CmdInitTypeDef SDIO_CmdInitStructure;
SDIO_DataInitTypeDef SDIO_DataInitStructure;
DMA_InitTypeDef DMA_InitStructure;
SDIO_CmdInitStructure.SDIO_Argument = 512;
SDIO_CmdInitStructure.SDIO_CmdIndex = 16;//cmd16
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
while((SDIO->STA&(1<<6))==0);
SDIO_ClearFlag(0x000005FF);
SDIO_DataInitStructure.SDIO_DataBlockSize= SDIO_DataBlockSize_512b;
SDIO_DataInitStructure.SDIO_DataLength= 512 ;
SDIO_DataInitStructure.SDIO_DataTimeOut=(u32)0xFFFFFFFF ;
SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToSDIO;
SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
SDIO_DataConfig(&SDIO_DataInitStructure);
SDIO_CmdInitStructure.SDIO_Argument = sector;
SDIO_CmdInitStructure.SDIO_CmdIndex = 17;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
while((SDIO->STA&(1<<6))==0);
SDIO_ClearFlag(0x000005FF);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
DMA_DeInit(DMA2_Channel4);
DMA_Cmd(DMA2_Channel4, DISABLE );
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SDIO->FIFO;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 512/4;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel4, &DMA_InitStructure);
DMA_Cmd(DMA2_Channel4, DISABLE );
SDIO_DMACmd(ENABLE);
while(((DMA2->ISR&0X2000)==RESET)&&((SDIO->STA&(1<<10))==0));
SDIO_ClearFlag(0x000005FF);
写一个块数据
这里使用DMA,默认过程中没有错误
SDIO_CmdInitTypeDef SDIO_CmdInitStructure;
SDIO_DataInitTypeDef SDIO_DataInitStructure;
DMA_InitTypeDef DMA_InitStructure;
SDIO_DataInitStructure.SDIO_DataBlockSize= SDIO_DataBlockSize_512b;
SDIO_DataInitStructure.SDIO_DataLength= 512 ;
SDIO_DataInitStructure.SDIO_DataTimeOut=(u32)0xFFFFFFFF ;
SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
SDIO_DataConfig(&SDIO_DataInitStructure);
do
{
SDIO_CmdInitStructure.SDIO_Argument = rca;//
SDIO_CmdInitStructure.SDIO_CmdIndex = 13;//cmd13
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
while((SDIO->STA&(1<<6))==0);
SDIO_ClearFlag(0x000005FF);
}while(((SDIO->RESP1&0x00000100)==0));
SDIO_CmdInitStructure.SDIO_Argument = sector;//·¢ËÍCMD24,дµ¥¿éÖ¸Áî,¶ÌÏìÓ¦
SDIO_CmdInitStructure.SDIO_CmdIndex = 24;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
while((SDIO->STA&(1<<6))==0);
SDIO_ClearFlag(0x000005FF);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
DMA_DeInit(DMA2_Channel4);
DMA_Cmd(DMA2_Channel4, DISABLE );
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SDIO->FIFO;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 512/4;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel4, &DMA_InitStructure);
DMA_Cmd(DMA2_Channel4, DISABLE );
SDIO_DMACmd(ENABLE);
while(((DMA2->ISR&0X2000)==RESET)&&((SDIO->STA&(1<<10))==0));
SDIO_ClearFlag(0x000005FF);
STM32F103 SDID模块SDHC卡读写相关推荐
- STM32F103+RFID-RC522模块 实现简单读卡写卡demo
目录 前言 特别声明: 代码下载: 功能介绍: 接线 STM32 STM32F1开发指南(精英版)-库函数版本_V1.2 STM32中文参考手册 RFID-RC522 RFID射频模块电路原理图 使用 ...
- Arduino UNO驱动micro SD卡读写模块
目录 一.简介 二.使用前准备 三.测试方法 四.实验现象 一.简介 Micro SD卡模块TF卡读写卡器板载电平转换电路,即接口电平可为5V或3.3V,支持支持Micro SD卡(≤2G).Micr ...
- 【雕爷学编程】Arduino动手做(52)---MicroSD卡读写模块
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备 ...
- 【Arduino 连接 SD 卡模块实现数据读写】
Arduino 连接 SD 卡模块实现数据读写 前言 Micro SD 卡模块引脚分配 Micro SD卡模块电路图 Arduino Micro SD卡模块电路连接图 Arduino 代码说明 模块的 ...
- SD/MMC 卡读写模块---SD/MMC 卡的外部物理接口
转载地址:http://www.8951.com/book/jiao1n21.htm SD/MMC 卡是一种大容量(最大可达 4GB).性价比高.体积小.访问接口简单的存储卡.SD/MMC 卡大 ...
- sdhc 读写 扇区 linux,SD卡读写扇区注意事项(转)
在调试SD卡时,大家都喜欢使用扇区进行验证.也就是说,一般都是通过读写扇区数据进行比较,或者读取第0扇区的数据,在通过WinHex软件打开启动扇区进行比较.这种方法对于1G的SD卡或部分2G的SD卡可 ...
- 基于FM1712的通用射频卡读写模块设计
射频卡(非接触IC卡)是最近几年发展起来的一项新技术,与传统的接触式IC卡磁卡相比较,利用射频识别技术(radio frequency identifica-tion)开发的非接触式IC卡成功解决了无 ...
- 用STM32F103完成对SD卡的数据读取
目录 SD卡协议原理 STM32+SD卡 的系统原理图设计 具体原理 代码 所用软件及硬件: 成果 参考文献 SD卡协议原理 功能 SD卡是存储卡,它的功能就是存储. 分类 SD卡按容量分类,可以分为 ...
- 基于STM32F103完成对SD卡的数据读取(fat文件模式)
文章目录 实验内容 一.SD卡协议 (一).SD卡简介 (二).SD 卡物理结构 (三).SD卡总线 二.基于STM32F103完成对SD卡的数据读取 (一).创建工程 (二).修改代码 (三).串口 ...
- Keil MDK STM32系列(九) 基于HAL和FatFs的FAT格式SD卡TF卡读写
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
最新文章
- excel排名_WPS-Excel表格实用技巧——排位排名函数(RANK函数)的使用
- 新时代,大数据战略和DevOps更配
- SAP实战中Submit的常见用法-调用标准程序
- MySQL- 用Navicat通过隧道连接到远程数据库
- 2019-03-18-算法-进化(有效的字母异位词)
- Android自定义View构造函数详解
- SRP6针对于网游登录服的应用
- smbinning包:R语言下的分箱处理工具
- 《离散数学及其应用》章节总结与github地址
- java加载so文件_java加载so文件
- 使用 Arduino Uno 与MQTT,echarts,java自己手动撸一个IOT平台
- Ubuntu速配指南之软件参考
- 数位板的主要参数解析
- 【2020 ACM Fellow 华人学者】 Cathy H. Wu 特拉华大学
- 小米笔记本U盘win10换win7系统操作教程
- 能够正常加入域但无法实施域策略
- 渗透测试之安全手册(干货)
- mysqllinux操作,万字解析!
- jquery canvas网页画布画图
- 两步实现安卓手机秒变网络摄像头
热门文章
- CVPR2019/图像翻译:TransGaGa: Geometry-Aware Unsupervised Image-to-Image Translation几何感知的无监督图像到图像的翻译
- Cocos2d-x制作跨平台太空射击游戏
- 物联网平台搭建的全过程介绍(一)——物联网简介
- OpenCV—Python 导向滤波
- welearn考试切屏会有显示吗_welearn班级测试答案
- 在imitate中遇到的问题
- sql server操作1:数据库及基本表的建立
- UFS系列三:UFS数据包UPIU
- iOS 苹果开发者账号技术支持电话
- java emun ordinal_关于Java:JPA枚举ORDINAL与STRING