STM32使用SDIO进行SD卡读写关于库函数获取SD卡信息
以下是相关流程
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卡信息相关推荐
- linux sd卡读写出错,linux系统SD卡读写问题
请教有过linux系统SD卡读写经验的前辈. 我的项目是对FPGA上的SD卡部分做测试,在测试过程中发现在对SD卡所有领域进行读写操作时 1.bus width 选择1-bit的速度4-bit是差不多 ...
- termux获取sd卡读写权限_重回SD市场 三星128GB/256GB PRO Plus存储卡评测
当前数码相机的性能越来越强,视频/照片双修的拍摄能力也逐步得到提高,对于大多数人来说,大容量的存储卡需求也在逐渐增大,一款好的SD卡不但能够进行快速的视频.照片捕捉,而且在抗磁.耐高温等一些特定环境的 ...
- android获取sd的大小,Android实现获取SD卡总容量,可用大小,机身内存总容量及可用大小的方法...
本文实例讲述了Android实现获取SD卡总容量,可用大小,机身内存总容量及可用大小的方法.分享给大家供大家参考,具体如下: 可能有的同学不知道系统已经提供了获取获取SD卡总容量,可用大小,机身内存总 ...
- Android 7.0 高通平台-telephony-机器无Sim卡情况下,获取SIM卡状态方法getSimState偶现为6,而不是1
TelephonyManager.java -------->getSimState接口 /** * Returns a constant indicating the state of the ...
- android 获取sd卡目录失败_获取sd卡存储路径失败
android新手,最近在学习 搜索sd卡上的所有txt文件并将其放入listview中显示,加载的过程中界面上会显示一个progress dialog.在之前的手机(Android5.0 andro ...
- [sg] Android 6.0 判断SD卡是否挂载,获取SD卡路径,和挂载的U盘进行区分
这三个问题其实可以归为一个问题,Android 6.0的SD卡和U盘都会挂载在 /mnt/media_rw/路径下,其实问题就是如何获取挂载信息 1. 存储服务StorageManagerServic ...
- 【STM32】STM32 SDIO SD卡读写测试(三)-- SD_Init之Init Card阶段
相关文章 <[SDIO]SDIO.SD卡.FatFs文件系统相关文章索引> 1. 前言 本篇文章主要是介绍stm324x9i_eval_sdio_sd.c里面SD_Init()函数完整的过 ...
- 【STM32】STM32 SDIO SD卡读写测试(二)-- SD_Init之Power On阶段
相关文章 <[SDIO]SDIO.SD卡.FatFs文件系统相关文章索引> 1. 前言 本篇文章主要是介绍stm324x9i_eval_sdio_sd.c里面SD_Init()函数完整的过 ...
- SDIO—SD 卡读写测试
1.SDIO 简介 SD 卡 (Secure Digital Memory Card) 在我们生活中已经非常普遍了,控制器对 SD 卡进行读写通信操作一般有两种通信接口可选,一种是 SPI 接口,另外 ...
最新文章
- 电子商务创造的第二次产业机会
- Glide @GlideModule 注解使用
- java压缩----使用ANT JDK压缩---只压缩选中目录的指定文件夹
- 重学java基础第五课:博客的重要性
- python多线程同步与互斥_python多线程编程(3): 使用互斥锁同步线程
- matlab外部调用lingo,讲讲官方的例子,MATLAB调用Lingo
- 命令行 蓝牙_蓝牙键盘接入UOS系统的方法
- python爬虫之帅哥图片爬取
- java 查询微信支付订单
- 找到了airdrop无法发现对方的原因了,原因你想不到!
- 用C语言编写简化版银行系统:ATM取款机(数组版)
- 查找代码文件中的非 ASCII 字符
- 如果写不出好的和弦就在洒满阳光的钢琴前一起吃布丁+与8有关的事儿
- 第1章 对象入门——Thinking-in-Java
- SEO中巧用个人博客优化关键字
- C++乘除运算防止中间值溢出
- 计算机网络与无线通信系统学习16:射频器件的基本参数
- 计算机网络课程设计(一)网络聊天程序的设计与实现
- 【求职】陌陌C++方向面经
- Android之分屏模式解析(上)
热门文章
- 读书笔记||函数探幽
- 全局钩子+正则表达式=后台自动获取扫描枪数据
- 自定义控件---继承ViewGroup类方式(循序渐进之第2步效果----图片左右拖动+自动回弹效果)
- 何恺明暗通道去雾(阅读笔记)
- 微信公众号可以改名称了,只限个人订阅号!
- Relational Reinforcement Learning: An Overview
- [源码]Meepo路由
- python高级--数据分析(Pandas库)
- Day 16 购物车
- 吴忌寒有算力,我有的是钱,我打算用钱摧毁比特大陆|专访澳洲中本聪