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

📄 mmc.c

📁 用LPC2103(ARM7)操作SD卡代码。
💻 C
字号:
//-------------------------------------------------------------------------

#include	"mmc.h"
#include	"spi.h"
//-------------------------------------------------------------------------
#define   SPI_CS 1<<18	/*片选*/
#define	CSH			IOSET=SPI_CS
#define	CSL			IOCLR=SPI_CS

//-------------------------------------------------------------------------
void mmcInit(void){	
	Init_SPI();
}
//-------------------------------------------------------------------------
uint8 mmcReset_1(void){
	uint8 i,retry,r1;

	retry=0;
	do{
		for(i=0;i<10;i++) MasterSendData(0xFF);	// send dummy at CS high		
		r1=mmcSendCommand(MMC_GO_IDLE_STATE, 0);	// resetting card
		retry++;
		if(retry>10) return -1;
	} while(r1 != MMC_R1_IDLE_STATE);

	retry=0;
	do{			
		r1=mmcSendCommand(MMC_SEND_OP_COND, 0);	// initializing card
		retry++;
		if(retry>100) return -1;
	} while(r1!=0);

	mmcSendCommand(MMC_CRC_ON_OFF, 0);			// turn off CRC checking
	mmcSendCommand(MMC_SET_BLOCKLEN, 512);		// set block len 512 bytes

	return 0;
}
//-------------------------------------------------------------------------
uint8 mmcReset(void){
	uint8 i;
	for(i=0;i<50;i++)if(mmcReset_1()==0)return 0;
	return -1;
}
//-------------------------------------------------------------------------
uint8 mmcSendCommand(uint8 cmd, uint32 arg){
	uint8 r1;

	CSL;											// assert chip select	
	r1 = mmcCommand(cmd, arg);						// issue the command
	CSH;											// release chip select
	return r1;
}
//-------------------------------------------------------------------------
uint8 mmcRead(uint32 sector, uint8* buffer ){
	uint8 r1;
	uint16 i;

	CSL;											// assert chip select	
	r1 = mmcCommand(MMC_READ_SINGLE_BLOCK, sector<<9);	// issue command
	if(r1 != 0)return r1;	
	while(MasterSendData(0xFF)!=MMC_STARTBLOCK_READ);// wait for block start
	
	for(i=0; i<0x200; i++){
		*buffer++ = MasterSendData(0xFF);			// read in data
	}
	
	MasterSendData(0xFF);							// read 16-bit CRC
	MasterSendData(0xFF);
	CSH;											// release chip select
	return 0;
}
//-------------------------------------------------------------------------
uint8 mmcWrite(uint32 sector, uint8* buffer){
	uint8 r1;
	uint16 i;

	CSL;											// assert chip select	
	r1 = mmcCommand(MMC_WRITE_BLOCK,sector<<9);	// issue command
	if(r1 != 0)return r1;	
	MasterSendData(0xFF);							// send dummy	
	MasterSendData(MMC_STARTBLOCK_WRITE);			// send data start token
	
	for(i=0; i<512; i++){
		MasterSendData(*buffer++);				// write data
	}
	
	MasterSendData(0xFF);							// write 16-bit CRC (dummy values)
	MasterSendData(0xFF);
	
	r1 = MasterSendData(0xFF);						// read data response token
	if((r1&MMC_DR_MASK)!=MMC_DR_ACCEPT)return r1;	
	while(!MasterSendData(0xFF));					// wait until card not busy
	CSH;											// release chip select
	return 0;
}
//-------------------------------------------------------------------------
uint8 mmcCommand(uint8 cmd, uint32 arg){
	uint8 r1,retry=0;
	MasterSendData(cmd|0x40);						// send command
	MasterSendData(arg>>24);
	MasterSendData(arg>>16);
	MasterSendData(arg>>8);
	MasterSendData(arg);
	MasterSendData(0x95);	// crc valid only for MMC_GO_IDLE_STATE
	// end command
	// wait for response
	// if more than 8 retries, card has timed-out
	// return the received 0xFF
	while((r1=MasterSendData(0xFF))==0xFF)if(retry++>8)break;
	// return response
	return r1;
}
//-------------------------------------------------------------------------
//Routine for reading CID Registers from MMC/SD-Card (16Bytes) 
//Return 0 if no Error.
uint8 Read_CID_MMC(uint8 *buffer){
	uint8 r1,i;

	CSL;											// assert chip select
	r1 = mmcCommand(MMC_SEND_CID,0);				// reading CID Registers
	if(r1 != 0)return r1;
	while(MasterSendData(0xFF)!=MMC_STARTBLOCK_READ);// wait for block start
	for(i=0; i<16; i++){
		*buffer++=MasterSendData(0xFF);			// read in data
	}
	MasterSendData(0xFF);							// read 16-bit CRC
	MasterSendData(0xFF);
	CSH;											// release chip select
	
	return(0);
}
//-------------------------------------------------------------------------
//Routine for reading CSD Registers from MMC/SD-Card (16Bytes)
//Return 0 if no Error.
uint8 Read_CSD_MMC(uint8 *buffer){
	uint8 r1,i;
		
	CSL;											// assert chip select
	r1 = mmcCommand(MMC_SEND_CSD,0);				// reading CSD Registers
	if(r1 != 0)return r1;
	while(MasterSendData(0xFF)!=MMC_STARTBLOCK_READ);// wait for block start
	for(i=0; i<16; i++){
		*buffer++=MasterSendData(0xFF);			// read in data
	}
	MasterSendData(0xFF);							// read 16-bit CRC
	MasterSendData(0xFF);
	CSH;
	
	return(0);
}
//-------------------------------------------------------------------------
//returns the :
// 	size of the card in MB ( ret * 1024^2) == bytes
// 	sector count and multiplier MB are in u08 == C_SIZE / (2^(9-C_SIZE_MULT))
// 	name of the media 
void MMC_get_volume_info(void){
	uint8 i,buffer[16];
    struct MMC_VOLUME_INFO vinf;
    
	for(i=0;i<16;i++)buffer[i]=0;
	Read_CSD_MMC(buffer);
	
	vinf.sector_count=buffer[6]&0x03;
	vinf.sector_count<<=8;
	vinf.sector_count+=buffer[7];
	vinf.sector_count<<=2;
	vinf.sector_count+=(buffer[8]&0xc0)>>6;
		
	vinf.sector_multiply=buffer[9]&0x03;
	vinf.sector_multiply<<=1;
	vinf.sector_multiply+=(buffer[10]&0x80)>>7;
	//SD的容量
	vinf.size_MB=vinf.sector_count>>(9-vinf.sector_multiply);

	for(i=0;i<16;i++)buffer[i]=0;
	Read_CID_MMC(buffer);
	//SD的名称
	vinf.name[0]=buffer[3];
	vinf.name[1]=buffer[4];
	vinf.name[2]=buffer[5];
	vinf.name[3]=buffer[6];
	vinf.name[4]=buffer[7];
	vinf.name[5]=0x00; //end flag
}
//-------------------------------------------------------------------------

⌨️ 快捷键说明

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