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

📄 sdcard.c

📁 arm7 lpc2132+vs1003+sdcard制作MP3 此程序在 KEIL3下编译
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************Copyright (c)***********************************************
**                              		qsw
**                                      
**                                
**--------------File Info----------------------------------------------------------------------------
** File name:			sdhal.c
** Last modified Date:	2007.11.20
** Last Version:		V1.0
** Descriptions:		sd 卡驱动软件包: 硬件抽象层 ---- SPI1操作函数
**						Soft Packet of SD Card Driver: hard abstrast layer ---- function of SPI1 operation
**
**------------------------------------------------------------------------------------------------
** Created by:			qsw
** Created date:		2007.11.20
** Version:				V1.0
** Descriptions:		The original version
**
**------------------------------------------------------------------------------------------------
** Modified by:			
** Modified date:		
** Version:				
** Descriptions:		
**
**------------------------------------------------------------------------------------------------
** Modified by: 
** Modified date:
** Version:	
** Descriptions: 
**
**************************************************************************************************/
#include "..\..\main\main.h"


uint32  NextCluster;   		 	//指向当前正在读取文件的簇号
uint32  SectorIndex=0;   		//正在读扇区

uint8   reading;

////////////////////////////////////////////////////////////////////////////////
//磁盘分区信息
////////////////////////////////////////////////////////////////////////////////
INT8U	Partition_Active;				// 0x80代表该分区为缺省分区
INT8U	Partition_StartHead;			// 该分区入口的磁头地址
INT16U	Partition_StartCylSect;			// 该分区入口的扇区地址和柱面地址
INT8U	Partition_PartType;				// 该分区类型
INT8U	Partition_EndHead;				// 该分区结束的扇区地址
INT16U	Partition_EndCylSect;			// 该分区结束的柱面地址
INT32U	Partition_StartLBA;				// 该分区内第一个扇区地址
INT32U	Partition_Size;					// 该分区所包含的扇区总数



////////////////////////////////////////////////////////////////////////////////
//fat32 BPB结构,包括扩展BPB
////////////////////////////////////////////////////////////////////////////////
INT8U	BS_jmpBoot[3];					//jmp code
INT8U	BS_OEMName[8];					//oem and os like dos5.0

INT16U	BPB_BytesPerSec; 				//扇区字节数
INT8U	BPB_SecPerClus;					//每簇扇区数
INT16U	BPB_RsvdSecCnt; 				//保留扇区数
INT8U	BPB_NumFATs;					//FAT数目
INT16U	BPB_RootEntCnt; 				//根目录项数 0
INT16U	BPB_TotSec16; 					//小扇区总数 0
INT8U	BPB_Media;						//媒体描述符
INT16U	BPB_FATSz16; 					//每FAT扇区数fat32不用为0
INT16U	BPB_SecPerTrk; 					//每道扇区数
INT16U	BPB_NumHeads; 					//磁头数
INT32U	BPB_HiddSec; 					//隐藏扇区数
INT32U	BPB_TotSec32; 					//总扇区数   
INT32U	BPB_FATSz32;					//每FAT扇区数fat32
INT16U	BPB_ExtFlags;					//fat32扩展标志
INT16U  BPB_FSVer;						//fat32特有,高位为fat32的主版本号,底位为次版本号
INT32U	BPB_RootClus;					//根目录簇号
INT16U	BPB_FSInfo;						//文件系统信息扇区号
INT16U	BPB_BKBootSec;					//引导扇区备份号
INT8U	BPB_Reserved[12];				//保留空间

INT8U	BS_drvNum;					    //物理驱动器号
INT8U	BS_Reservd1;					//保留
INT8U	BS_BootSig;						//扩展引导标签
INT32U	BS_VolID;						//分区序号
INT8U	BS_VolLab[11];					//卷标
INT8U	BS_FilSysType[8];				//系统ID



////////////////////////////////////////////////////////////////////////////////
//目录信息
////////////////////////////////////////////////////////////////////////////////
INT8U  	deName[8];
INT8U  	deExtension[3];
INT32U  Clust; 							//当前目录的簇号
INT16U 	Nums;   						//仅FAT12—FAT16中的根目录区有效
INT32U 	Index;  						//当前的BLOCK中目录项索引
INT32U 	FileSize; 						//文件长度


////////////////////////////////////////////////////////////////////////////////
//文件信息
////////////////////////////////////////////////////////////////////////////////
INT8U	DIR_Name[11];					//文件名,没有.
INT8U	DIR_Attr;         				//文件属性,自低至高,只读、隐藏、系统、卷标、子目录、归档
INT8U	DIR_NTRes;        				//系统保留
INT8U	DIR_CrtTimeTenth;  				//创建时间的10毫秒位
INT16U	DIR_CrtTime;      				//创建时间
INT16U	DIR_CrtDate;      				//创建日期
INT16U	DIR_LastAccDate;  				//最后访问日期
INT16U	DIR_FstClusHI;    				//文件起始簇号高16位               
INT16U	DIR_WrtTime;      				//最近修改时间
INT16U	DIR_WrtDate;      				//最近修改日期
INT16U	DIR_FstClusLO;    				//文件起始簇号的低16位               
INT32U	DIR_FileSize;     				//文件长度



////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
INT32U  FAT1Sec;						//FAT1表的位置
INT32U  FAT2Sec;
INT32U  FirstDataSector;				//第一个根目录位置,区号为2
INT32U  FirstDirSector;
////////////////////////////////////////////////////////////////////////////////

INT8U   BUFFER[512]; 

INT8U MP3_BUFFER[512];

#define MP3_TYPE   0
#define WMA_TYPE   1
#define MID_TYPE   2
#define LRC_TYPE   3

INT8U filetype[][3] ={ {"MP3"},{"WMA"},{"MID"},{"LRC"}};

INT8U hzk12[][11] =
{
	{"HZK12      "},
 	{"UNITOGB BIN"},
	{".          "},
	{"..         "}
};

INT32U  FAT_MASK;
INT16U  RootDirEnts;         // 根目录总的项数(FAT12&FAT16)

/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
void SD_Power(void)
{
	SPI1_SCK_GPIO();	
	SPI1_SCK_OUT();
	SPI1_SCK_CLR();		
	
	SPI1_MOSI_GPIO();		
	SPI1_MOSI_OUT();
	SPI1_MOSI_CLR();		
	
    SPI1_CS_GPIO();	 		
	SPI1_CS_OUT();
	SPI1_CS_CLR();
}
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
void SPI1_Init(INT8U speed)
{  
	SPI1_CS_GPIO();		
	SPI1_CS_OUT();
					
	PINSEL1 &= ~((0x03 << 2) + (0x03 << 4) + (0x03 << 6)); 
	PINSEL1 |=  (0x02 << 2) + (0x02 << 4) + (0x02 << 6);
	
	SSPCR0 = (0x00 << 8) |              			// SCR=0  
            (0x00 << 7) |             				// CPHA =0时钟输出相位,仅SPI模式有效 
            (0x00 << 6) |              				// CPOL =0时钟输出极性,仅SPI模式有效
            (0x00 << 4) |              				// FRF =00 帧格式 00=SPI,01=SSI,10=Microwire,11=保留
            (0x07 << 0);               				// DSS  数据长度,0000-0010=保留,0011=4位,0111=8位,1111=16位

    SSPCR1 = (0x00 << 3) |              			// SOD  从机输出禁能,1=禁止,0=允许
            (0x00 << 2) |              				// MS   主从选择,0=主机,1=从机
            (0x01 << 1) |              				// SSE  SSP使能,1=允许SSP与其它设备通信
            (0x00 << 0);               				// LBM  回写模式
             
    SSPCPSR	= speed; 								//2-254 偶数	
  	SSPIMSC	= 0x00;								    // 取消所有中断使能		
    SSPICR	= 0x00;                     			// 中断清除寄存器
}								
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SPI1_SrByte(INT8U byte)
{
	OS_ENTER_CRITICAL();
	SSPDR = byte;

	while( (SSPSR & 0x01) == 0 );	    			// 等待TFE置位,即发送FIFO空  										

	OS_EXIT_CRITICAL();
	return(SSPDR);
}
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SD_ChkCard(void)
{
	//if (SD_INSERT_STATUS() != 0)
	//	return 0;									/* 未完全插入 not insert entirely */
	//else
		return 1;									/* 完全插入 insert entirely */
}
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SD_WriteCom(uint8 cmd,uint32 arg)
{
	uint8 tmp;
   	uint8 retry=0;
	
  	SPI1_CS_CLR();      							//SD卡使能

   	SPI1_SrByte((INT8U)(cmd|0x40));   				//送头命令
   	SPI1_SrByte((INT8U)(arg>>24));
   	SPI1_SrByte((INT8U)(arg>>16));     				//send 6 Byte Command to MMC/SD-Card
   	SPI1_SrByte((INT8U)(arg>>8));
   	SPI1_SrByte((INT8U)(arg));
	SPI1_SrByte((INT8U)(0x95));       				//仅仅对RESET有效的CRC效验码

	do
   	{ 
    	tmp = SPI1_SrByte(0XFF); 					//Only last 8 bit is used here.Read it out.
      	retry++;
   	}
   	while((tmp==0xff)&&(retry<100));    			//当没有收到有效的命令的时候

	if(retry>=100)
	{
		return 0;
	}
	
	if(reading == 0)
    {
      	SPI1_CS_SET();          	  				//MMC_CS_PIN=1;
    }
    else 
    {
    	SPI1_CS_CLR();                 		    	// MMC_CS_PIN = 0;   
    }
	return(tmp);
}
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SD_ReadBlock(INT32U address,INT8U *SD_BUFFER)
{
	INT32U	addr;
	INT16U  i=0;
	INT8U   temp=0;
   	
	addr=address<<9;
	
	reading=1;
	
   	SPI1_CS_CLR();    			  				//MMC_CS_PIN=0;
   	
	temp=SD_WriteCom(CMD17,addr);     			//读出RESPONSE

	while( (SPI1_SrByte(0XFF)!= 0xFE)&&(i<400))
	{
		i++;
	}; 											//直到读取到了数据的开始头0XFE,才拿继续

   	for(i=0; i<512; i++)
	{
		*SD_BUFFER++=SPI1_SrByte(0XFF);
	}
	
   	SPI1_SrByte(0XFF);							//CRC - Byte
   	SPI1_SrByte(0XFF);							//CRC - Byte

	reading=0;

	SPI1_CS_SET(); 

	return(temp);
}
/*******************************************************************************************************************
** 函数名称: INT8U SD_WriteBlockData()				Name:	  INT8U SD_WriteBlockData()
** 功能描述: 向sd卡写数据块							Function: write block data to sd card
** 输   入: INT8U bmulti  : 是否为多块操作1:是0:否 Input:	  INT8U bmulti   : multi blocks operate 1:Y 0:N 
			 INT32U len    : 长度						  	  INT32U len     : length
			 INT8U *sendbuf: 发送缓冲区					 	  INT8U *sendbuf : the buffer of send
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
********************************************************************************************************************/
INT8U SD_WriteBlock(INT32U len, INT8U *sendbuf)
{
	INT16U i;
	INT8U tmp;

	SPI1_CS_CLR();
		
    SPI1_SrByte(0xFF);								/* 开始发送数据之前发送8个clock clock out 8 clk before start */
    
	SPI1_SrByte(SD_TOK_WRITE_STARTBLOCK);			/* 写单块开始令牌 start token of write single block */

	for (i = 0; i < len; i++)
        SPI1_SrByte(sendbuf[i]);					/* 发送数据 send data */

	SPI1_SrByte((i >> 8) & 0xFF);
	SPI1_SrByte(i & 0xFF); 							/* 发送CRC16校验码 send CRC16 check code */
			    
	tmp = SPI1_SrByte(0xff);
  	if ((tmp & SD_RESP_DATA_MSK) != SD_RESP_DATA_ACCETPTED)	
  	{		
   		SPI1_SrByte(0xFF);							/* 返回之前发送8个clock  clock out 8 clk before return */
   		//SPI_CS_Deassert();
   		//return SD_ERR_DATA_RESP;					/* 数据响应错误 data response error */
    }
        
   SPI1_CS_SET();	
     		
    //if (SD_WaitBusy(SD_WAIT_WRITE) != SD_NO_ERR)			
    	return 0;				/* 写入超时 write time out */
    //else
   // 	return 1; 							/* 写入正确 write right */
 }
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SD_Init(void)
{
	uint8 retry;
   	uint8 temp;
   	uint8 i;
	
	SPI1_Init(100);
	
	OSTimeDlyHMSM(0, 0, 1, 0);	

	SPI1_CS_CLR();      					//SD卡使能
   	
   	for (i=0;i<16;i++)

⌨️ 快捷键说明

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