最近学习一了下SD卡的驱动,网上程序的版本很多,使用的MCU和SD卡的型号千奇百怪,学起来反而没有方向,感觉上乱七八糟的,直到现在才知到我们平常说的SD卡实际上有很多中类别。0到2G的SD卡,最普通的卡;2G到32G的SDHC卡,也就是现在最常用的大容量SD卡;还有我没有见过的SDXC卡,容量好像在32G以上。同时还有手机上的TF卡,实际上也是SD卡 只不过做工不同而已,MMC卡。学习的时候走了很多弯路,SD卡的官方data sheet感觉上写的相当坑爹,网上的学习资料还是给了很大的帮助,但是由于网上的版本很多,程序流程还是要参考官方相对应的SD卡初始化流程。这两天闲下来,抓紧时间整理一下笔记。

首先说一下我自己使用的卡,它是SanDisk 4G SDHC Card,速度等级为4,算比较快的一种大容量SD卡。MCU选取了STC12C5A60S2,反馈信息的显示采用最常用的1602液晶屏,当然大部分网上的代码使用的是串口。SD卡有两种传输模式,SD模式和SPI模式,SD模式需要4跟数据线,而我们一般都采用SPI模式,也就是常说的串行通信模式,这种方式需要的通信线比较少,一根数据输入D_IN,一根数据输出D_OUT,CS片选线,CLK时钟,此外还有电源3.6V和GND地线,其他的引脚按照说明悬空或者接地即可。

其次,SD卡的初始化过程根据卡的不同有不同的方式,我们按照官方给出的流程来说。关于命令的具体参数和返回值的类型说明放在下一篇笔记中,这里只记录流程。

第一步,首先上电,将CS片选信号拉低,在这个基础上对CLK操作,给SD卡发送至少74个时钟周期,让SD卡完成自身检查和初始化,进入空闲状态(IDLE)。之后,对SD卡发送CMD0使其进入SPI模式。不论你是什么卡,第一步的工作都是相同的,这个时候可以观察一下SD卡从D_OUT线上的返回值,如果是0x01,说明CMD0操作是成功的,此时SD卡还处在IDLE状态。

第二步,发送CMD8这一步新的SD卡和老版本的SD卡是有区别的,CMD8是检测SD卡版本的命令,如果SD卡对此命令不识别,那么说明你的SD卡为老版本的,如果SD卡对CMD8做出了正确的返回值(前提你命令格式要对),则说明你的SD卡的硬件层版本是2.0的,支持大容量储存,也就是SDHC卡。我所使用的卡就是SDHC卡,所以有6个字节的返回值,这个在后面说明。另外要说的一点,我曾经直接跳过了CMD8的发送,直接进行了下一步命令,SD卡返回了错误的信息,没有进入正确的读写准备状态。所以这个命令还是按照官方的建议,发送检测。

第三步,CMD8有了返回值以后,则需要进一步让卡从IDLE状态进入读写就绪的状态,也就是发送ACMD41命令。这里要注意的是,SD卡有两种命令CMD和ACMD,如果直接发送命令,SD卡会将命令默认为CMD,如果你想发送ACMD,则要特殊的说明一下,CMD55就是这个功能,它可以提醒SD卡进行接着CMD55后的下一条命令为ACMD。第三步的操作即首先发送CMD55命令,接收到正常的返回值0X01后接着发送ACMD41,完成卡从IDLE状态到读写状态的初始化进程。如果操作正常,SD卡退出IDLE状态,最后的返回值为0X00,此外任何其他的返回值都是不正常的。

第四步,发送CMD58,读取OCR寄存器,OCR寄存器记录了SD卡可识别的电压范围;SD卡是否支持大容量存储,即SDHC;和SD卡上点状态。发送了CMD58命令后,SD卡的下一组返回值为R1返回值+OCR寄存器的内容。根据datasheet我们可以得到很多信息,上面已经提到,具体的位置手册上很明白。手册上推荐发送这个命令,主要功能是你可以知道你的V2.0SD卡是标准版本的,还是大容量的SD卡,大容量的SD卡读写操作时按照块(512BYTE)进行的,所以读写地址的方法有所不同。判断正常的方法,CMD58的返回值类型为R3 ,即R1类型+OCR寄存器内容,如果一切就绪,那么OCR的最高四位为1100。从这个命令以后,初始化的工作就全部进入了,SD卡进入读写准备状态,接下来就可以任意读取目标地址,对其进行读写操作了。

读写数据的过程:
无论读写数据还是接收发送CMD,我们都会用到两个最基本的函数,一个是read_byte(),即从SD卡的DATA_OUT引脚上读取8bit(1byte)的数据;另一个是write_byte(),向SD卡的DATA_IN引脚写一个字节的数据。命令,数据和返回值都是由多字节组合成的,所以在一个操作中会多次调用这两个基本的函数。如SD_Read_Sector()这个函数的主要功能就是从指定的地址中读取512字节的数据,那我们在发送了读的命令后相应的要调用512次read_byte()函数。

读写函数的时序图:向SD卡写数据时,时钟上升沿时数据有效;从SD卡读数据时,时钟在高电平时,MCU读到的数据有效,根据这个写两个基本函数就没有问题。

/****************************************************************************************
** 函数名称: void write_byte()
** 功能描述: 对SD卡写一个字节的数据
** 输   入: 要写入的字节
** 输   出: 无
****************************************************************************************/
void write_byte( uchar _data)
{uchar i;for(i=0; i<8; i++){SD_CLK_CLR();SD_DAIN = (_data & 0x80);           //位操作必须有与运算以免不必要的错误if(is_init)                          //是否进入高速模式,初始化时低速,is_init=1DelayMs(4);                      //读写数据时高速,is_init=0;_data <<= 1;                        //有的人为了提高速度,会把for循环拆开一句一句写SD_CLK_SET();if(is_init)DelayMs(4);}SD_CLK_CLR();                          //8bit数据传输完后拉低时钟线SD_DAIN_SET();
}/****************************************************************************************
** 函数名称: uchar read_byte()
** 功能描述: 从DATA_OUT线上读取一字节的数据
** 输   入: 无
** 输   出: 读出的一字节数据
****************************************************************************************/
uchar read_byte()
{uchar _data,i;SD_DAOUT_SET();                          //读取前先要拉高数据线for(i=0; i<8; i++){SD_CLK_CLR();if(is_init)   DelayMs(4);SD_CLK_SET();if(is_init)DelayMs(4);_data <<= 1;if(SD_DAOUT == 1){_data = _data | 0x01;}        }SD_CLK_CLR();return _data;
}

基于STC12C5A60S2的SDHC卡的初始化和读写过程相关推荐

  1. 学习笔记——基于FPGA的SD卡学习(1)

    SD卡介绍 SD卡( Secure Digital Card),即安全数字卡 ,具有两个突出的优点 更高的安全性和更快的读写速度 . SD卡分类   SD卡从存储容量上分为3个级别,分别为SD卡.SD ...

  2. 基于FPGA的SD卡的数据读写实现(SD NAND FLASH)

    文章目录 1.存储芯片分类 2.NOR Flash 与 NAND Flash的区别 3.什么是SD卡? 4.什么是SD NAND? 5.SD NAND的控制时序 6.FPGA实现SD NAND读写 6 ...

  3. SD/MMC卡初始化及读写流程

    二.MMC/SD卡的模型和工作原理 PIN脚.SD卡总线.SD卡结构.SD卡寄存器.上电过程 SD卡寄存器: OCR:操作电压寄存器: 只读,32位 第31位:  表示卡上电的状态位  CID: 卡身 ...

  4. SD/TF卡驱动(二)--------SD卡程序初始化流程以及读写

    说明: ①测试的SD卡为高容量卡,支持SD卡2.0协议,容量为16G ②采用GPIO模拟SPI时序的方式对SD卡进行驱动,很方便移植到没有硬件SPI或者SDIO的MCU,对于这类MCU,只需要将对应的 ...

  5. 基于MATLAB的答题卡识别方法

    基于MATLAB的答题卡识别方法 摘 要 背景: 随着科技的发展,电子与计算机技术的进步,答题卡的出现大大减轻教学工作者们批改试卷的工作量.答题卡是光标阅读机输入信息的载体,是配套光标阅读机的各种信息 ...

  6. 实战精通OpenCV第一章--基于Android的图片卡通化及肤色改变(三)

    第一章 基于Android的图片卡通化及肤色改变 一.基于Visual Studio的图片卡通化 二.基于Visual Studio的肤色改变 三.Android代码移植 最近由于工作比较忙,很抱歉没 ...

  7. 基于FPGA的SD卡音乐播放器之WM8731篇

    基于FPGA的SD卡音乐播放器之WM8731篇 目录 前言 一.I2C驱动模块 二.WM8731寄存器配置模块 三.WM8731时钟生成模块 四.音频发送模块 总结 前言 这个题目是我之前7月初做的一 ...

  8. 基于FPGA的SD卡音乐播放器之完结篇

    基于FPGA的SD卡音乐播放器之完结篇 目录 前言 一.WAV格式 二.FIFO模块 三.音频-SD卡交互模块 四.锁相环模块 五.按键去抖模块 六.按键控制模块 总结 前言 前面已经介绍了WM873 ...

  9. html音频从10秒播放至30秒,基于Arduino制作SD卡音乐播放器

    一.项目介绍 前面用ATtiny85制作SD卡音乐播放器,本次主要利用Arduino UNO 和SD卡制作音乐播放器.这个播放器不需要添加多余的模块,只需要SD读卡器和Arduino UNO开发板就可 ...

  10. php充值代码,基于php的加油卡充值接口调用代码实例

    搜索热词 下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. 代码描述:基于PHP的加油卡充值接口调用代码实例 关联数据:加油卡充值 接口地址 ...

最新文章

  1. 传感器信号 如何发送到服务器,传感器如何将消息发送给云服务器
  2. 数据结构---邻接表的BFS
  3. 【转】人工智能教程-前言
  4. chrome浏览器无法加载百度网页启动组件怎么办
  5. 7.1.8860.142
  6. 和华为云一起做件“伟大的事”,24万奖金等你来!
  7. ArcGIS API for Silverlight 调用GP服务绘制等值面
  8. wooden sticks
  9. 【初赛】各种排序算法总结
  10. mariadb.zip压缩包解压后使用绿色db配置方法
  11. html搜索联系人,联系人列表.html
  12. Origin画图技巧之柱状图优化
  13. python二元一次方程组用鸡兔同笼的思路来写编程_二元一次方程组的应用一鸡兔同笼问题...
  14. 河北科技师范学院对口计算机分数线,河北科技师范学院对口分数线
  15. 重磅推出:2019中国开源年度报告
  16. 【系统集成项目管理工程师】项目范围管理
  17. mysql导出备份、导入恢复以及迁移(适用虚拟主机)
  18. Hibernate对象关系映射详解之一对多关系映射
  19. 经典面试题-搜狐和讯网Shell面试题
  20. 程序员职业发展的绊脚石-思想的枷锁

热门文章

  1. 冻库正常低压力是多少_零下40度低温低压压力多少算正常?
  2. 阿里妈妈展示广告引擎新探索:迈向全局最优算力分配
  3. Java根据出生年月日计算年龄
  4. 社会网络分析 社区划分—经典数据集
  5. ws office excel 基础公式
  6. Home Assistant启动失败,页面报404
  7. Java多线程系列--【JUC集合08】- LinkedBlockingQueue
  8. Windows 模块安装程序必须更新,才能安装此程序包。 请更新计算机上的 Windows 模块安装程序,然后重试安装。问题解决
  9. 速途在线沙龙11期:王通夫唯首次聚首共话SEO
  10. Fate Decision剧本