⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd.c

📁 SD卡驱动程序,用于ARM7单片机,完全能用
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************Copyright (c)**************************************************
**                                   
**                                    
**                                        
**
**                                 
**
**--------------文件信息--------------------------------------------------------------------------------
**文   件   名: SD.c
**创   建   人: 李功周
**最后修改日期: 2008年10月23日
**描        述: SD卡驱动 API 函数 
**              
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 李功周
** 版  本: v1.0
** 日 期: 2008年10月23日
** 描 述: 原始版本
**
**------------------------------------------------------------------------------------------------------
*/

#include <LPC2103.H>
//#include "../Uart1/Uart1.h"



/* SCK引脚 */
#define  SPI_SCK				((unsigned int)0x01 << 4)						
#define  SPI_SCK_GPIO()			PINSEL0 &= ~((unsigned int)0x03 << 8)			/* 设置 SCK 口为GPIO口 */
#define  SPI_SCK_OUT()			IODIR |= SPI_SCK				/* 设置 SCK 口为输出口 */
#define	 SPI_SCK_CLR()			IOCLR = SPI_SCK				/* 置 SCK 为低电平 */	

/* MISO 引脚 */	
#define  SPI_MISO				((unsigned int)0x01 << 5)						
#define  SPI_MISO_GPIO()		PINSEL0 &= ~((unsigned int)0x03 << 10)		/* 设置 MISO 口为GPIO口 */
#define  SPI_MISO_OUT()			IODIR |= SPI_MISO				/* 设置 MISO 口为输出口 */
#define	 SPI_MISO_CLR()			IOCLR = SPI_MISO				/* 置 MISO 为低电平 */

/* MOSI 引脚 */	
#define  SPI_MOSI				((unsigned int)0x01 << 6)
#define  SPI_MOSI_GPIO()		PINSEL0 &= ~((unsigned int)0x03 << 12)		/* 设置 MOSI 口为GPIO口 */
#define  SPI_MOSI_OUT()			IODIR |= SPI_MOSI				/* 设置 MOSI 口为输出口 */
#define	 SPI_MOSI_CLR()			IOCLR = SPI_MOSI				/* 置 MISO 为低电平 */

/* CS 引脚 */		
#define  SPI_CS      			((unsigned int)0x01 << 30)              	 	
#define  SPI_CS_GPIO()			PINSEL1 &= ~((unsigned int)0x03 << 28)		 /* 设置 CS 口为GPIO口 */
#define  SPI_CS_OUT()			IODIR |= SPI_CS;			 				/* 设置 CS 口为输出口 */
#define	 SPI_CS_SET()			IOSET |= SPI_CS;							/* 置 CS 为高电平 */
#define	 SPI_CS_CLR()			IOCLR |= SPI_CS;							/* 置 CS 为低电平 */

/* 卡完全插入卡座检测引脚 */
#define  SD_INSERT				((unsigned int)0x01 << 31)	
#define  SD_INSERT_GPIO()		PINSEL1 &= ~((unsigned int)0x03 << 30)		/* 设置 INSERT 口为GPIO口 */	
#define  SD_INSERT_IN()			IODIR &= ~SD_INSERT							/* 设置 INSERT 口为输入口 */	
#define  SD_INSERT_STATUS()  	(IOPIN & SD_INSERT)							/* 读取 INSERT 口的状态 */

/* 卡写保护检测引脚 */
#define  SD_WP					((unsigned int)0x01 << 10)		
#define  SD_WP_GPIO()			PINSEL0 &= ~((unsigned int)0x03 << 20)		/* 设置 WP 口为GPIO口 */	
#define  SD_WP_IN()				IODIR &= ~SD_WP								/* 设置 WP 口为输入口 */	
#define  SD_WP_STATUS()  		(IOPIN & SD_WP)								/* 读取 WP 口的状态 */



/* SD卡命令超时时间(单位 8clock)*/
/* timeout of command */
#define   SD_CMD_TIMEOUT   	 		100

/* 定义在初始化阶段,等待SD卡退出空闲状态的重试次数 */
#define   SPI_CLOCK				5529600		/* 正常通信时,SPI时钟频率 frequency (Hz) */
#define   SD_READREG_TIMEOUT		8				// 读寄存器的超时时间
#define   SD_IDLE_WAIT_MAX     		1000
#define   READ_TIMEOUT_100MS      	100 * SPI_CLOCK / 1000 / 8

/* 250ms 相当的SPI时钟数(单位 unit: 8 clocks) */
/* 250ms correspond to SPI clock(unit: 8 clocks)*/
#define   WRITE_TIMEOUT_250MS		250 * SPI_CLOCK / 1000 / 8 




/* 错误码 error code */
#define   SD_NO_ERR			     	0x00			// 函数执行成功
#define   SD_ERR_NO_CARD		 	0x01			// 卡没有完全插入到卡座中
#define   SD_ERR_USER_PARAM      	0x02			// 用户使用API函数时,入口参数有错误
#define   SD_ERR_CARD_PARAM		 	0x03			// 卡中参数有错误(与本模块不兼容)
#define	  SD_ERR_VOL_NOTSUSP        0x04			// 卡不支持3.3V供电
#define   SD_ERR_OVER_CARDRANGE		0x05			// 操作超出卡容量范围
#define   SD_ERR_UNKNOWN_CARD       0x06			// 无法识别卡型

/* 等待错误码 */
#define   SD_ERR_TIMEOUT_WAIT    	0x30			// 写或擦操作时,发生超时错误
#define   SD_ERR_TIMEOUT_READ    	0x31			// 读操作超时错误
#define	  SD_ERR_TIMEOUT_WRITE	 	0x32			// 写操作超时错误
#define   SD_ERR_TIMEOUT_ERASE   	0x33			// 擦除操作超时错误
#define	  SD_ERR_TIMEOUT_WAITIDLE 	0x34			// 初始化卡时,等待卡退出空闲状态超时错误

/* 数据流错误码 */
#define   SD_ERR_DATA_CRC16      	0x20			// 数据流CRC16校验不通过
#define   SD_ERR_DATA_START_TOK		0x21			// 读单块或多块时,数据开始令牌不正确
#define	  SD_ERR_DATA_RESP		 	0x22			// 写单块或多块时,卡数据响应令牌不正确

/* Number of tries to wait for the card to go idle during initialization */
#define SD_IDLE_WAIT_MAX     	1000

/* Number of tries to wait for the card to go idle during initialization */
#define SD_IDLE_WAIT_MAX     	1000



/* R1和R2高字节错误码 R1 and upper byte of R2 error code */
#define MSK_IDLE          		  0x01
#define MSK_ERASE_RST     		  0x02
#define MSK_ILL_CMD       		  0x04
#define MSK_CRC_ERR       		  0x08
#define MSK_ERASE_SEQ_ERR 		  0x10
#define MSK_ADDR_ERR      		  0x20
#define MSK_PARAM_ERR     		  0x40



/* SD命令可能返回的错误码 */
#define   SD_ERR_CMD_RESPTYPE	 	0x10			// 命令类型错误
#define   SD_ERR_CMD_TIMEOUT     	0x11			// 卡命令响应超时
#define   SD_ERR_CMD_RESP		 	0x12			// 卡命令响应错误


/* 写操作可能返回的错误码 */
#define	  SD_ERR_WRITE_BLK			0x40			// 写块数据错误
#define	  SD_ERR_WRITE_BLKNUMS      0x41			// 写多块时,想要写入的块与正确写入的块数不一致
#define   SD_ERR_WRITE_PROTECT		0x42			// 卡外壳的写保护开关打在写保护位置

/* 数据响应令牌 Data Response Tokens */
#define SD_RESP_DATA_MSK		  0x0F				//数据响应掩码
#define SD_RESP_DATA_ACCETPTED	  0x05				//数据被接受
#define SD_RESP_DATA_REJECT_CRC	  0x0B      		//由于CRC错误而被拒绝
#define SD_RESP_DATA_REJECT_WRITE 0x0D				//由于写错误而被拒绝

/* 等待类型 Wait Type */
#define SD_WAIT_READ			  0x00				//读等待
#define SD_WAIT_WRITE			  0x01				//写等待
#define SD_WAIT_ERASE		 	  0x02				//擦除等待


/* 应用操作错误 */
#define	SD_WRITE_ERR				0xf0			//写SD错误
#define	SD_READ_ERR					0xf1			//读SD卡错误
#define	SD_Efficacy_ERR				0xf2			//效验错误
#define SD_BLOCKADDR_ERR			0xf3			//块地址不合法



#define SD_CRC_EN		   			0			/* 设置数据传输时是否使用CRC */
/*
*********************************************

     SD卡SPI模式下命令集

*********************************************
*/



/* 命令响应定义 define command's response */
#define R1 1
#define R1B 2
#define R2 3
#define R3 4



/******************************** 基本命令集 Basic command set **************************/
/* 复位SD 卡 Reset cards to idle state */
#define CMD0 0
#define CMD0_R R1

/* 读OCR寄存器 Read the OCR (MMC mode, do not use for SD cards) */
#define CMD1 1
#define CMD1_R R1
/* 读CSD寄存器 Card sends the CSD */
#define CMD9 9
#define CMD9_R R1

/* 读CID寄存器 Card sends CID */
#define CMD10 10
#define CMD10_R R1

/* 停止读多块时的数据传输 Stop a multiple block (stream) read/write operation */
#define CMD12 12
#define CMD12_R R1B

/* 读 Card_Status 寄存器 Get the addressed card's status register */
#define CMD13 13
#define CMD13_R R2

/***************************** 块读命令集 Block read commands **************************/

/* 设置块的长度 Set the block length */
#define CMD16 16
#define CMD16_R R1

/* 读单块 Read a single block */
#define CMD17 17
#define CMD17_R R1

/* 读多块,直至主机发送CMD12为止 Read multiple blocks until a CMD12 */
#define CMD18 18
#define CMD18_R R1

/***************************** 块写命令集 Block write commands *************************/
/* 写单块 Write a block of the size selected with CMD16 */
#define CMD24 24
#define CMD24_R R1

/* 写多块 Multiple block write until a CMD12 */
#define CMD25 25
#define CMD25_R R1

/* 写CSD寄存器 Program the programmable bits of the CSD */
#define CMD27 27
#define CMD27_R R1

/***************************** 写保护 Write protection *****************************/
/* Set the write protection bit of the addressed group */
#define CMD28 28
#define CMD28_R R1B

/* Clear the write protection bit of the addressed group */
#define CMD29 29
#define CMD29_R R1B

/* Ask the card for the status of the write protection bits */
#define CMD30 30
#define CMD30_R R1

/***************************** 擦除命令 Erase commands *******************************/
/* 设置擦除块的起始地址(只用于SD卡) Set the address of the first write block to be erased(only for SD) */
#define CMD32 32
#define CMD32_R R1

/* 设置擦除块的终止地址(只用于SD卡) Set the address of the last write block to be erased(only for SD) */
#define CMD33 33
#define CMD33_R R1

/* 设置擦除块的起始地址(只用于MMC卡) Set the address of the first write block to be erased(only for MMC) */
#define CMD35 35
#define CMD35_R R1

/* 设置擦除块的终止地址(只用于MMC卡) Set the address of the last write block to be erased(only for MMC) */
#define CMD36 36
#define CMD36_R R1

/* 擦除所选择的块 Erase the selected write blocks */
#define CMD38 38
#define CMD38_R R1B

/***************************** 锁卡命令 Lock Card commands ***************************/
/* 设置/复位密码或上锁/解锁卡 Set/reset the password or lock/unlock the card */
#define CMD42 42
#define CMD42_R	R1B
/* Commands from 42 to 54, not defined here */


/***************************** 应用命令 Application-specific commands ****************/
/* 禁止下一个命令为应用命令  Flag that the next command is application-specific */
#define CMD55 55
#define CMD55_R R1

/* 应用命令的通用I/O  General purpose I/O for application-specific commands */
#define CMD56 56
#define CMD56_R R1

/* 读OCR寄存器  Read the OCR (SPI mode only) */
#define CMD58 58
#define CMD58_R R3

/* 使能或禁止 CRC Turn CRC on or off */
#define CMD59 59
#define CMD59_R R1


/***************************** 应用命令 Application-specific commands ***************/
/* 获取 SD Status寄存器 Get the SD card's status */
#define ACMD13 13
#define ACMD13_R R2

/* 得到已写入卡中的块的个数 Get the number of written write blocks (Minus errors ) */
#define ACMD22 22
#define ACMD22_R R1

/* 在写之前,设置预先擦除的块的个数 Set the number of write blocks to be pre-erased before writing */
#define ACMD23 23
#define ACMD23_R R1

/* 读取OCR寄存器 Get the card's OCR (SD mode) */
#define ACMD41 41
#define ACMD41_R R1

/* 连接/断开CD/DATA[3]引脚上的上拉电阻 Connect or disconnect the 50kOhm internal pull-up on CD/DAT[3] */
#define ACMD42 42
#define ACMD42_R R1

/* 读取SCR寄存器 Get the SD configuration register */
#define ACMD51 51
#define ACMD51_R R1



/* 数据令牌 Data Tokens */
#define SD_TOK_READ_STARTBLOCK    0xFE
#define SD_TOK_WRITE_STARTBLOCK   0xFE
#define SD_TOK_READ_STARTBLOCK_M  0xFE
#define SD_TOK_WRITE_STARTBLOCK_M 0xFC
#define SD_TOK_STOP_MULTI         0xFD

/**************************************************
	
			其它宏定义

***************************************************/
#define	  	CARDTYPE_SD				0xa0			// 卡型为SD  卡
#define   	CARDTYPE_MMC			0xa1			// 卡型为MMC 卡
//#define 	SD_BLOCKSIZE 			512				// SD卡块的长度 

/* CSD中一些域的字节位置(高字节在前) */
#define TAAC_POS 			1			//TACC
#define NSAC_POS			2			//NSAC

#define READ_BL_LEN_POS		5			//READ_BL_LEN

#define C_SIZE_POS1			6			//C_SIZE upper  2-bit
#define C_SIZE_POS2			7			//C_SIZE middle 8-bit
#define C_SIZE_POS3			8			//C_SIZE lower	2-bit

#define C_SIZE_MULT_POS1	9			//C_SIZE_MULT upper 2-bit
#define C_SIZE_MULT_POS2	10			//C_SIZE_MULT lower 1-bit	

#define SECTOR_SIZE_POS1	10			//SECTOR_SIZE upper 5-bit
#define SECTOR_SIZE_POS2	11			//SECTOR_SIZE lower 2-bit

#define R2WFACTOR_POS 		12			//R2WFACTOR_POS

//CSD中一些域的掩码
#define TAAC_MSK			0x07		//TACC 域掩码
#define NSAC_MSK			0x78		//NSAC 域掩码

#define READ_BL_LEN_MSK		0x0F		//READ_BL_LEN 的掩码

#define C_SIZE_MSK1			0x03		//C_SIZE 高2位掩码
#define C_SIZE_MSK3			0xC0		//C_SIZE 低2位掩码

#define C_SIZE_MULT_MSK1 	0x03		//C_SIZE_MULT 的高2位掩码
#define C_SIZE_MULT_MSK2 	0x80		//C_SIZE_MULT 的低2位掩码

#define R2WFACTOR_MSK		0x1C		//R2WFACTOR 掩码

#define SECTOR_SIZE_MSK1	0x3F		//SECTOR_SIZE 的高5位
#define SECTOR_SIZE_MSK2	0x80		//SECTOR_SIZE 的低2位

#define ERASE_GRP_SIZE_MSK 		0x7C		//MMC卡 ERASE_GRP_SIZE 掩码
#define ERASE_GRP_MULTI_MSK1 	0x03		//MMC卡 ERASE_GRP_MULTI 高2位掩码
#define ERASE_GRP_MULTI_MSK2 	0xE0		//MMC卡 ERASE_GRP_NULTI 低3位掩码

#define ERASE_GRP_SIZE_POS   	10		//MMC卡 ERASE_GRP_SIZE 5-bit
#define ERASE_GRP_MULTI_POS1 	10		//MMC卡 ERASE_GRP_MULTI 2-bit
#define ERASE_GRP_MULTI_POS2 	11		//MMC卡 ERASE_GRP_MULTI 3-bit




/* 超时时间单位表(单位:0.000000001ns) timeout unit table */
const unsigned int time_unit[8] = {1000000000,100000000,10000000,
							 1000000,100000,10000,1000,100};

/* 超时时间表 timeout value table */							 
const unsigned char time_value[16] = {0,10,12,13,15,20,25,30,
                              35,40,45,50,55,60,70,80};
 
/* 超时时间因数表 timeout factor table */                              
const unsigned char r2w_fator[8] = {1,2,4,8,16,32,64,128}; 





 /* SD卡信息结构体定义 */ 
/* the information structure variable of SD Card*/
typedef struct 
{	
	unsigned char card_type;
	unsigned int  block_num;				/* 卡中块的数量 */
	unsigned int  block_len;				/* 卡的块长度(单位:字节) */
	unsigned int  erase_unit;				/* 一次可擦除的块个数 */
	
	unsigned int  timeout_read;				/* 读块超时时间(单位: 8 SPI clock) */
	unsigned int  timeout_write;			/* 写块超时时间(单位: 8 SPI clock) */
	unsigned int  timeout_erase;			/* 擦块超时时间(单位: 8 SPI clock) */
	
}sd_struct;

volatile sd_struct sds;						/* SD卡信息结构体变量 */ 
//volatile unsigned int SD_BLOCKSIZE;
//volatile unsigned int SD_BLOCKSIZE_NBITS;

#define SD_BLOCKSIZE		512
#define	SD_BLOCKSIZE_NBITS  9

volatile unsigned int  MAXBlock_num;	


 /*******************************************************************
** 函数名称: void SPI_SendByte()				
** 功能描述: 通过SPI接口发送一个字节			
** 输   入: INT8U byte: 发送的字节				
** 输   出: 无									
**********************************************************************/
void SPI_SendByte(unsigned char byte)
{

	S0SPDR = byte;							/* 发送数据放入SPI数据寄存器 */
   
	while(0 == (S0SPSR & 0x80));				/* 等待SPIF置位,即等待数据发送完毕 */
												/* wait for SPIF being set, that is, wait for finishing of data being send */
 	byte = S0SPDR;
	
}



/**********************************************************************
** 函数名称: INT8U SPI_RecByte()				
** 功能描述: 从SPI接口接收一个字节				
** 输   入: 无									
** 输   出: 收到的字节							
*************************************************************************/
unsigned char SPI_RecByte(void)
{
	S0SPDR = 0xFF;
   
 	while(0 == (S0SPSR & 0x80));				/* 等待SPIF置位,即等待收到数据 */
												/* wait for SPIF being set, that is, wait for being received data */
	return(S0SPDR); 							/* 读取收到的字节 read the byte received */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -