以下是相关流程
1.STM32通电
2.对几个SDIO相关的引脚初始化(查芯片手册,哪几个引脚对应SDIO,还有时钟也要设置)

SD卡只支持4位数据传输,所以只占SDIO_D0 ~ SDIO_D3,再加上SDIO_CK、SDIO_CMD。对PC8、PC9、PC10、PC11、PC12,还有PD2做一些配置和使能时钟。

void mySD_init(void)
{
GPIO_InitTypeDef  GPIO_InitStructure; /* GPIOC and GPIOD Periph clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD , ENABLE); // 使能两个时钟,因为SDIO在两个端口上,上面图片有说明了,一个在PC,另一个在PD
GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_SDIO); // PC8使用SDIO功能
GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_SDIO); // PC9使用SDIO功能
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SDIO); // PC10使用SDIO功能  GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_SDIO); // PC11使用SDIO功能  GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SDIO); // PC12使用SDIO功能 GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_SDIO); // PD2使用SDIO功能  /* Configure PC.08, PC.09, PC.10, PC.11 pins: D0, D1, D2, D3 pins */ // 配置PC8、PC9、PC10、PC11引脚  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);   /* Configure PD.02 CMD line */ // 配置PD2引脚  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOD, &GPIO_InitStructure);   /* Configure PC.12 pin: CLK pin */ // 配置PC12引脚  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);  / * Enable the SDIO APB2 Clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE); // 使能SDIO时钟,SDIO是挂在APB2总线上的  /* Enable the DMA2 Clock */
RCC_AHB1PeriphClockCmd(SD_SDIO_DMA_CLK, ENABLE); // 如果要使用DMA的话,使能DMA时钟}

3.设置中断(SDIO中断,还有优先级之类的)

{  NVIC_InitTypeDef NVIC_InitStructure;   /* Configure the NVIC Preemption Priority Bits */ // 嵌套向量中断控制器组选择
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn; // 配置SDIO中断  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢断优先级为0  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级为0  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断
NVIC_Init(&NVIC_InitStructure); // 初始化配置NVIC
NVIC_InitStructure.NVIC_IRQChannel = SD_SDIO_DMA_IRQn; // 使能SDIO DMA中断  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢断优先级为1  NVIC_Init(&NVIC_InitStructure); // 初始化配置NVIC
}4.复位SDIO外设寄存器(将SDIO外设寄存器,初始化为它们的默认复位值)```c
void mySDIO_DeInit(void)
{ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, DISABLE);}

5.调用库函数,SDIO初始化(库函数名:SDIO_Init,一些初始化的东西,例如频率,卡识别时要先设400K,后续数据传输时可以调高些,另外还有设置几根数据线之类的)

void mySDIO_init(void)
{__IO SD_Error errorstatus = SD_OK;
uint32_t response = 0, count = 0, validvoltage = 0;
uint32_t SDType = SD_STD_CAPACITY;
SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV;
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);
}

6.调用库函数,设置SDIO上电(库函数名:SDIO_SetPowerState,要使用SD卡,就要把电源打开)

void mySDIO_PowerOn(void){ /*!< Set Power State to ON */  SDIO_SetPowerState(SDIO_PowerState_ON);}

7 . 调用库函数,使能SDIO时钟(库函数名:SDIO_ClockCmd,和SD卡交互数据需要时钟)

void mySDIO_EnableClock(void)
{/*!< Enable SDIO Clock */ SDIO_ClockCmd(ENABLE);}

8 .调用发送命令的库函数,开始发送命令(CMD) 所以第8步骤的命令发送顺序是:CMD0 -> CMD8 -> CMD55 -> CMD41 -> CMD2 -> CMD3(由于CMD41是特定应用命令,在CMD41之前,必须发送CMD55)后续进行卡识别时,要发送CMD0、CMD8、CMD41等等(CMD41是特定应用命令,在它之前必须先发CMD55)
在卡识别结束后,对SD读、写、擦除等相关的操作,一律都是用SDIO_SendCommand这个库函数来操作的

9.第8步骤最后发送了CMD3,进入数据传输模式,首先来获取SD的容量,卡的块大小之类的信息(发送CMD9命令)

SD_Error SD_InitializeCards2(void)
{
if (SDIO_SECURE_DIGITAL_IO_CARD != CardType)
{   RCA = rca;     /*!< Send CMD9 SEND_CSD with argument as card's RCA */    SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)(rca << 16);
SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_CSD;
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);
errorstatus = CmdResp2Error();
if (SD_OK != errorstatus)
{     return(errorstatus);    }    CSD_Tab[0] = SDIO_GetResponse(SDIO_RESP1);   CSD_Tab[1] = SDIO_GetResponse(SDIO_RESP2);   CSD_Tab[2] = SDIO_GetResponse(SDIO_RESP3);   CSD_Tab[3] = SDIO_GetResponse(SDIO_RESP4);  }   errorstatus = SD_OK; /*!< All cards get intialized */   return(errorstatus);}

10.前9个步骤算是初始化流程,然后就可进行其他操作,例如读取SD卡,写入数据。

STM32使用SDIO进行SD卡读写关于库函数获取SD卡信息相关推荐

  1. linux sd卡读写出错,linux系统SD卡读写问题

    请教有过linux系统SD卡读写经验的前辈. 我的项目是对FPGA上的SD卡部分做测试,在测试过程中发现在对SD卡所有领域进行读写操作时 1.bus width 选择1-bit的速度4-bit是差不多 ...

  2. termux获取sd卡读写权限_重回SD市场 三星128GB/256GB PRO Plus存储卡评测

    当前数码相机的性能越来越强,视频/照片双修的拍摄能力也逐步得到提高,对于大多数人来说,大容量的存储卡需求也在逐渐增大,一款好的SD卡不但能够进行快速的视频.照片捕捉,而且在抗磁.耐高温等一些特定环境的 ...

  3. android获取sd的大小,Android实现获取SD卡总容量,可用大小,机身内存总容量及可用大小的方法...

    本文实例讲述了Android实现获取SD卡总容量,可用大小,机身内存总容量及可用大小的方法.分享给大家供大家参考,具体如下: 可能有的同学不知道系统已经提供了获取获取SD卡总容量,可用大小,机身内存总 ...

  4. Android 7.0 高通平台-telephony-机器无Sim卡情况下,获取SIM卡状态方法getSimState偶现为6,而不是1

    TelephonyManager.java -------->getSimState接口 /** * Returns a constant indicating the state of the ...

  5. android 获取sd卡目录失败_获取sd卡存储路径失败

    android新手,最近在学习 搜索sd卡上的所有txt文件并将其放入listview中显示,加载的过程中界面上会显示一个progress dialog.在之前的手机(Android5.0 andro ...

  6. [sg] Android 6.0 判断SD卡是否挂载,获取SD卡路径,和挂载的U盘进行区分

    这三个问题其实可以归为一个问题,Android 6.0的SD卡和U盘都会挂载在 /mnt/media_rw/路径下,其实问题就是如何获取挂载信息 1. 存储服务StorageManagerServic ...

  7. 【STM32】STM32 SDIO SD卡读写测试(三)-- SD_Init之Init Card阶段

    相关文章 <[SDIO]SDIO.SD卡.FatFs文件系统相关文章索引> 1. 前言 本篇文章主要是介绍stm324x9i_eval_sdio_sd.c里面SD_Init()函数完整的过 ...

  8. 【STM32】STM32 SDIO SD卡读写测试(二)-- SD_Init之Power On阶段

    相关文章 <[SDIO]SDIO.SD卡.FatFs文件系统相关文章索引> 1. 前言 本篇文章主要是介绍stm324x9i_eval_sdio_sd.c里面SD_Init()函数完整的过 ...

  9. SDIO—SD 卡读写测试

    1.SDIO 简介 SD 卡 (Secure Digital Memory Card) 在我们生活中已经非常普遍了,控制器对 SD 卡进行读写通信操作一般有两种通信接口可选,一种是 SPI 接口,另外 ...

最新文章

  1. 电子商务创造的第二次产业机会
  2. Glide @GlideModule 注解使用
  3. java压缩----使用ANT JDK压缩---只压缩选中目录的指定文件夹
  4. 重学java基础第五课:博客的重要性
  5. python多线程同步与互斥_python多线程编程(3): 使用互斥锁同步线程
  6. matlab外部调用lingo,讲讲官方的例子,MATLAB调用Lingo
  7. 命令行 蓝牙_蓝牙键盘接入UOS系统的方法
  8. python爬虫之帅哥图片爬取
  9. java 查询微信支付订单
  10. 找到了airdrop无法发现对方的原因了,原因你想不到!
  11. 用C语言编写简化版银行系统:ATM取款机(数组版)
  12. 查找代码文件中的非 ASCII 字符
  13. 如果写不出好的和弦就在洒满阳光的钢琴前一起吃布丁+与8有关的事儿
  14. 第1章 对象入门——Thinking-in-Java
  15. SEO中巧用个人博客优化关键字
  16. C++乘除运算防止中间值溢出
  17. 计算机网络与无线通信系统学习16:射频器件的基本参数
  18. 计算机网络课程设计(一)网络聊天程序的设计与实现
  19. 【求职】陌陌C++方向面经
  20. Android之分屏模式解析(上)

热门文章

  1. 读书笔记||函数探幽
  2. 全局钩子+正则表达式=后台自动获取扫描枪数据
  3. 自定义控件---继承ViewGroup类方式(循序渐进之第2步效果----图片左右拖动+自动回弹效果)
  4. 何恺明暗通道去雾(阅读笔记)
  5. 微信公众号可以改名称了,只限个人订阅号!
  6. Relational Reinforcement Learning: An Overview
  7. [源码]Meepo路由
  8. python高级--数据分析(Pandas库)
  9. Day 16 购物车
  10. 吴忌寒有算力,我有的是钱,我打算用钱摧毁比特大陆|专访澳洲中本聪