stc12c5a60s2功能说明(STC12C5A60S2默认触发)

最近学习一下SD卡的驱动,网上程序的版本很多,使用的MCU和SD卡的型号千奇百怪,学起来反而没有方向,感觉上乱七八糟的,直到现在,才直到我们平常说的SD卡实际上有很多中类别。0到2G的SD卡,最普通的卡;2G到32G的SDHC卡,也就是现在最常用的大容量SD卡;还有我没有见过的SDXC卡,容量好像在32G以上。同时还有手机上的TF卡,实际上也是SD卡只不过做工不同而已,MMC卡。学习的时候走了很

大家好,又见面了,我是你们的朋友全栈君。

最近学习一了下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卡的初始化过程根据卡的不同有不同的方式,我们按照官方给出的流程来说。关于命令的具体参数和返回值的类型说明放在下一篇笔记中,这里只记录流程。

stc12c5a60s2功能说明(STC12C5A60S2默认触发)

第一步,首先上电,将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()函数。

stc12c5a60s2功能说明(STC12C5A60S2默认触发)

读写函数的时序图:向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=1
			DelayMs(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;	
}


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/128715.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • hdu1106 java字符串分割

    hdu1106 java字符串分割排序TimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/32768K(Java/Others)TotalSubmission(s):30220    AcceptedSubmission(s):8391ProblemDescription输入一行数字,如果我们把这行数字中的‘5’都

    2022年9月1日
    4
  • 少儿编程mta证书_少儿编程项目计划书

    少儿编程项目计划书未来30年是人工智能的伟大时代,学编程会让孩子的未来充满更多可能性。此项目是针对小学生,主要是以培养学习兴趣,接受最基本的编程概念,并能够通过学到的知识完成一些小的课题,激发和培养学生的编程思维。在学习的过程中,主要通过实体的编程玩具,学会构建自己的作品,比如学习编程语言,机器人等课程。本项目提供多维度的少儿编程培训服务,包括编辑机器人研发、在线编程教育培训、线下培训等。一、线下…

    2022年4月8日
    40
  • memorycleaner汉化版(v4l2 userptr)

    本文链接:https://blog.csdn.net/coroutines/article/details/70141086可参考:http://www.it610.com/article/4522348.htm//v4l2官方翻译基于V4L2的应用,通常面临着大块数据的读取与拷贝等问题。尤其在嵌入式系统中,对于实时性能要求较高的应用,拷贝会花上几十个ms…

    2022年4月16日
    131
  • 手眼标定的两种方式

    手眼标定的两种方式最近在学习手眼标定,做下笔记,和大家分享下学习经历:一手眼标定的两种情形首先讲一下在工业应用中,手和眼(摄像机)的两种位置关系,第一种是将摄像机(眼)固定在机械手(手)上面,眼随手移动;第二种是摄像机(眼)和机械手(手)分离,眼的位置相对于手是固定的,下面用网上的两张图来说明下:第一种情况:相机移动第二种情况:相机固定从上面两副示意图可以看出,第一种情况中我们

    2022年4月30日
    47
  • 移动文件到文件夹 linux_centos移动文件

    移动文件到文件夹 linux_centos移动文件Linux移动或复制文件(文件夹)命令格式:cp-rf/home/backup/default/Public/Public/复制/home/backup/default/Public文件夹到当前文件夹下补充cp该命令的各选项含义如下-a该选项通常在拷贝目录时使用。它保留链接、文件属性,并递归地拷贝目录,其作用等于dpR选项的组合。  -d拷贝时保留链接。…

    2022年8月23日
    4
  • 怎么查看自己电脑的IP地址

    怎么查看自己电脑的IP地址

    2021年10月17日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号