初始化

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卡读写相关推荐

  1. STM32F103+RFID-RC522模块 实现简单读卡写卡demo

    目录 前言 特别声明: 代码下载: 功能介绍: 接线 STM32 STM32F1开发指南(精英版)-库函数版本_V1.2 STM32中文参考手册 RFID-RC522 RFID射频模块电路原理图 使用 ...

  2. Arduino UNO驱动micro SD卡读写模块

    目录 一.简介 二.使用前准备 三.测试方法 四.实验现象 一.简介 Micro SD卡模块TF卡读写卡器板载电平转换电路,即接口电平可为5V或3.3V,支持支持Micro SD卡(≤2G).Micr ...

  3. 【雕爷学编程】Arduino动手做(52)---MicroSD卡读写模块

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备 ...

  4. 【Arduino 连接 SD 卡模块实现数据读写】

    Arduino 连接 SD 卡模块实现数据读写 前言 Micro SD 卡模块引脚分配 Micro SD卡模块电路图 Arduino Micro SD卡模块电路连接图 Arduino 代码说明 模块的 ...

  5. SD/MMC 卡读写模块---SD/MMC 卡的外部物理接口

    转载地址:http://www.8951.com/book/jiao1n21.htm SD/MMC    卡是一种大容量(最大可达 4GB).性价比高.体积小.访问接口简单的存储卡.SD/MMC 卡大 ...

  6. sdhc 读写 扇区 linux,SD卡读写扇区注意事项(转)

    在调试SD卡时,大家都喜欢使用扇区进行验证.也就是说,一般都是通过读写扇区数据进行比较,或者读取第0扇区的数据,在通过WinHex软件打开启动扇区进行比较.这种方法对于1G的SD卡或部分2G的SD卡可 ...

  7. 基于FM1712的通用射频卡读写模块设计

    射频卡(非接触IC卡)是最近几年发展起来的一项新技术,与传统的接触式IC卡磁卡相比较,利用射频识别技术(radio frequency identifica-tion)开发的非接触式IC卡成功解决了无 ...

  8. 用STM32F103完成对SD卡的数据读取

    目录 SD卡协议原理 STM32+SD卡 的系统原理图设计 具体原理 代码 所用软件及硬件: 成果 参考文献 SD卡协议原理 功能 SD卡是存储卡,它的功能就是存储. 分类 SD卡按容量分类,可以分为 ...

  9. 基于STM32F103完成对SD卡的数据读取(fat文件模式)

    文章目录 实验内容 一.SD卡协议 (一).SD卡简介 (二).SD 卡物理结构 (三).SD卡总线 二.基于STM32F103完成对SD卡的数据读取 (一).创建工程 (二).修改代码 (三).串口 ...

  10. Keil MDK STM32系列(九) 基于HAL和FatFs的FAT格式SD卡TF卡读写

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

最新文章

  1. excel排名_WPS-Excel表格实用技巧——排位排名函数(RANK函数)的使用
  2. 新时代,大数据战略和DevOps更配
  3. SAP实战中Submit的常见用法-调用标准程序
  4. MySQL- 用Navicat通过隧道连接到远程数据库
  5. 2019-03-18-算法-进化(有效的字母异位词)
  6. Android自定义View构造函数详解
  7. SRP6针对于网游登录服的应用
  8. smbinning包:R语言下的分箱处理工具
  9. 《离散数学及其应用》章节总结与github地址
  10. java加载so文件_java加载so文件
  11. 使用 Arduino Uno 与MQTT,echarts,java自己手动撸一个IOT平台
  12. Ubuntu速配指南之软件参考
  13. 数位板的主要参数解析
  14. 【2020 ACM Fellow 华人学者】 Cathy H. Wu 特拉华大学
  15. 小米笔记本U盘win10换win7系统操作教程
  16. 能够正常加入域但无法实施域策略
  17. 渗透测试之安全手册(干货)
  18. mysqllinux操作,万字解析!
  19. jquery canvas网页画布画图
  20. 两步实现安卓手机秒变网络摄像头

热门文章

  1. CVPR2019/图像翻译:TransGaGa: Geometry-Aware Unsupervised Image-to-Image Translation几何感知的无监督图像到图像的翻译
  2. Cocos2d-x制作跨平台太空射击游戏
  3. 物联网平台搭建的全过程介绍(一)——物联网简介
  4. OpenCV—Python 导向滤波
  5. welearn考试切屏会有显示吗_welearn班级测试答案
  6. 在imitate中遇到的问题
  7. sql server操作1:数据库及基本表的建立
  8. UFS系列三:UFS数据包UPIU
  9. iOS 苹果开发者账号技术支持电话
  10. java emun ordinal_关于Java:JPA枚举ORDINAL与STRING