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

📄 mmc.c

📁 mmc单片机读写程序 mmc单片机读写程序
💻 C
📖 第 1 页 / 共 2 页
字号:
SPIPORT |= CS;
//SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0);    /* enable SPI as master, set clk divider */
SPCR = (1<<SPE) | (1<<MSTR) | (0<<SPR1) | (0<<SPR0);    /* enable SPI as master, set clk divider */
Delay_1ms(250);

/* start off with 80 bits of high data with card deselected */
for(i=0;i<10;i++)
SpiByte(0xff);
SPIPORT &= ~CS;        /* select card */
/* now send CMD0 - go to idle state */
MMCCommand(0,0,0);
if (MMCGet() != 1)
   {
   SPIPORT |= CS;
   return -1;  // MMC Not detected
   }

/* send CMD1 until we get a 0 back, indicating card is done initializing */
i = 0xffff;
while ((SpiByte(0xff) != 0) && (--i))
     {
     MMCCommand(1,0,0);
   //  WDR();
     }
if (i == 0)
   {
   SPIPORT |= CS;
   return -2;  // Init Fail
   }

SPIPORT |= CS;
return 0;
}

/************************************************************
 * void MMCInfo(void)
 *
 * - gets and prints formatted CID and CSD info from card
 ************************************************************/
void MMCInfo(void)
{
int i;

MMCCommand(10,0,0);
if (MMCDataToken() != 0xfe) puts("MMC: error");
else puts("MMC: CID read\n\r\0");

// Skip 3 byte Manufacturer ID
//SpiByte(0xff);
//SpiByte(0xff);
//SpiByte(0xff);
putchar(SpiByte(0xff));
putchar(SpiByte(0xff));
putchar(SpiByte(0xff));

puts("MMC: Product Name : ");
for (i=0;i<7;i++) putchar(SpiByte(0xff));
puts("\n\r\0");

for (i=0;i<9;i++) SpiByte(0xff); // Read 9 left byte

SPIPORT |= CS;
}


/************************************************************
 * int MMCReadSector(unsigned long lba, unsigned char * s)
 *
 * - reads a sector from the card (512 bytes)
 * - takes sector # as param
 ************************************************************/
int MMCReadSector(unsigned long lba, char *s)
{
unsigned int i;

MMCCommand(17,(lba>>7) & 0xffff, (lba<<9) & 0xffff);
if (MMCDataToken() != 0xfe)
   {
   SEI();
   return -1;
   }

for (i=0;i<512;i++)     /* read the sector */
   {
    *s++ = SpiByte(0xff);
   }
SpiByte(0xff);       /* checksum -> don't care about it for now */
SpiByte(0xff);       /* checksum -> don't care about it for now */
SPIPORT |= CS;
return 0;
}

/************************************************************
 * int MMCWriteSector(unsigned long lba, unsigned char * s)
 *
 * - reads a sector from the card (512 bytes)
 * - takes sector # as param
 ************************************************************/
int MMCWriteSector(unsigned long lba, char *s)
{
unsigned int i;

MMCCommand(24, (lba>>7)& 0xffff, (lba<<9)& 0xffff);
if (MMCGet() == 0xff) return -1;

SpiByte(0xfe);  // Send Start Byte

for (i=0;i<512;i++)       /* read the sector */
   {
    SpiByte(*s++);
   }
SpiByte(0xff);       /* checksum -> don't care about it for now */
SpiByte(0xff);       /* checksum -> don't care about it for now */
SpiByte(0xff);       /* Read "data response byte"                 */

i = 0xffff;
while ((SpiByte(0xff) == 0x00) && (--i)); /* wait for write finish */
if (i == 0) return -1; // Error

SPIPORT |= CS;
return 0;
}

/************************************************************
 * unsigned char MMCGet(void)
 *
 * - pings the card until it gets a non-0xff value
 * - returns one byte of read info
 ************************************************************/
unsigned char MMCGet(void)
{
unsigned int i = 0xffff;
unsigned char Byte = 0xff;

while((Byte == 0xff) && (--i)) Byte = SpiByte(0xff);
return Byte;
}

/************************************************************
 * int MMCDataToken(void)
 *
 * - pings the card until it gets data token
 * - returns one byte of read info (data token)
 ************************************************************/
unsigned char MMCDataToken(void)
{
unsigned int i = 0xffff;
unsigned char Byte = 0xff;

while((Byte != 0xfe) && (--i)) Byte = SpiByte(0xff);
return Byte;
}

/************************************************************
 * void MMCCommand(unsigned char command, unsigned int px, unsigned int py)
 *
 * - send one byte of 0xff, then issue command + params + (fake) crc
 * - eat up the one command of nothing after the CRC
 ************************************************************/
void MMCCommand(unsigned char command, unsigned int px, unsigned int py)
{
SPIPORT &= ~CS;
SpiByte(0xff);
SpiByte(command | 0x40);
SpiByte((unsigned char)((px >> 8)&0x0ff)); /* high byte of param y */
SpiByte((unsigned char)(px & 0x00ff));     /* low byte of param y */
SpiByte((unsigned char)((py >> 8)&0x0ff)); /* high byte of param x */
SpiByte((unsigned char)(py & 0x00ff));     /* low byte of param x */
SpiByte(0x95);            /* correct CRC for first command in SPI          */
                          /* after that CRC is ignored, so no problem with */
                          /* always sending 0x95                           */
SpiByte(0xff);
}

/*****************************************************
 * Main SPI routine
 *  - transmits a byte and receives a byte simultaneously
 *  - received byte is returned
 *  - if you only want to read a byte, put a dummy 
 *    (say 0xff) in the transmit slot
 ****************************************************/
unsigned char SpiByte(unsigned char byte)
{
//WDR();
SPDR = byte;               /* put byte to send in SPDR, which initiates xmit  */
while(!(SPSR & (1<<SPIF)));/* wait for completion */
return SPDR;               /* return with byte shifted in from slave */
}


/*****************************************************/
unsigned char read_VFAT_info(void)
{
	unsigned long	sec;
	unsigned int	bpb;
	unsigned int	n;
//								printf("Type of FAT: FAT%c\n",FATtype);

	MMCReadSector(0,&DataBuff[0]);
	Delay_1ms(1);
	
	//read_32(446);										// MBR
	bpb = (unsigned int)DataBuff[8+446] + ((unsigned int)DataBuff[9+446]<<8);	// BPB
	//printf("bpb: %u\n",bpb);
	MMCReadSector(bpb,&DataBuff[0]);
	Delay_1ms(1);
	n = (unsigned int)DataBuff[11] + ((unsigned int)DataBuff[12] << 8);
	//printf("N: %u\n",n);
	if (n != 512){
		return 2;
	}
	SectorsPerCluster = DataBuff[13];
//	printf("SPCluster: %u\n",SectorsPerCluster);
	FATstart = bpb + (unsigned int)DataBuff[14] + ((unsigned int)DataBuff[15] << 8);
	Delay_1ms(1);
//	printf("FATstart: %u\n",FATstart);

	RootDirEntriesCount = (unsigned int)DataBuff[17] + ((unsigned int)DataBuff[18] << 8);
//	printf("RootDirEntriesCount: %u\n",RootDirEntriesCount);
	Delay_1ms(1);
	
	n = (unsigned int)DataBuff[22] + ((unsigned int)DataBuff[23] << 8);
	if (n == 0){
		return 1;	// FAT32
	}
	DIRstart =(unsigned int) FATstart + (unsigned int)DataBuff[16] * (unsigned int)n;	// FAT
	Delay_1ms(1);
//	printf("DIRstart: %u\n",DIRstart);
//	printf("FATstart: %u\n",FATstart);
//	printf("Buff: %x\n",DataBuff[16]);
//	printf("N: %u\n",n);
	
	n = RootDirEntriesCount / 16;
	if (RootDirEntriesCount % 16){
		n++;
	}
//	printf("N: %u\n",n);
	DataStart =(unsigned long)DIRstart + (unsigned long)n;
//	printf("DataStart: %u\n",DataStart);

	sec = (unsigned long)DataBuff[19] + ((unsigned long)DataBuff[20] << 8);
	if (sec == 0){
	//	read_32((unsigned long)bpb * 512 + 32);
	MMCReadSector((unsigned long)bpb,&DataBuff[0]);
		sec = (unsigned long)DataBuff[0+ 32] + ((unsigned long)DataBuff[1+ 32] << 8)
			+ ((unsigned long)DataBuff[2+ 32] << 16) + ((unsigned long)DataBuff[3+ 32] << 24);
	}
	sec -= FATstart;
	sec /= SectorsPerCluster;
	if (sec >= 0x1000){
		FATtype = 1;
//		printf("FAT16");	// FAT16
	} else {
		FATtype = 0;	// FAT12
	//			printf("FAT12");
	}

	return 0;
}

unsigned int Search_File(unsigned int num)
{
	unsigned int	ent;
	unsigned long	sec;
	unsigned char	i, j;
	unsigned int	n;

	n = 0;
	MMCReadSector((unsigned long)DIRstart,&DataBuff[0]);
//	sec = (unsigned long)DIRstart * 512;
	for (ent = 0; ent < RootDirEntriesCount/16; )
	{
		for (i = 0; i < 16; i++)
		{
			if (DataBuff[0+i*32] == 0)	break;
			if (((DataBuff[26+i*32] != 0)||(DataBuff[27+i*32] != 0))&&
				(DataBuff[0+i*32] != 0xE5)&&	
				(!(DataBuff[11+i*32] & 0x18))&&
				(DataBuff[8+i*32]=='T')&&(DataBuff[9+i*32]=='X')&&(DataBuff[10+i*32]=='T'))
				{
				n++;
				if (--num == 0)	break;
				}
		}
		ent++;
		if (DataBuff[0] == 0)	break;
		if (num == 0)	break;
//		sec += 512;
		MMCReadSector((unsigned long)DIRstart+(unsigned long)ent,&DataBuff[0]);
	}
	return n;
}

unsigned int read_word(unsigned int addr)
{
	unsigned int	w;
	unsigned int	l;
	unsigned int	h;
	l = addr & 511;
	h &= addr>>8;
	MMCReadSector((unsigned long)h,&DataBuff[0]);
	w = (unsigned int)DataBuff[l++];
	w |= ((unsigned int)DataBuff[l] << 8);
	return w;
}
/////////////////////////////////////////////////////////////////////////////////////
//	NextCluster = next_cluster(Cluster, 0, 0);

unsigned int next_cluster(unsigned int c, unsigned long sec, unsigned int remain)
{
	unsigned long	addr;
	unsigned int	data;
	unsigned long	fatadr;
	unsigned int	i;
	unsigned int	l,h;

	if (FATtype == 0)
	   	{}		// FAT12		 
		else 
		{	 	   // FAT16
			MMCReadSector(FATstart,&DataBuff[0]);
		if ((sec != 0)&&(fatadr != FatCacheAddr))
		{
			for (i = remain; i < 512; i++)	SpiByte(0xff);
			c = (unsigned int)DataBuff[l++];
			c |= ((unsigned int)DataBuff[l] << 8);
			for (i = 0; i < remain; i++)	SpiByte(0xff);
		} 
		else 
		{
			c = (unsigned int)DataBuff[l++];
			c |= ((unsigned int)DataBuff[l] << 8);
		}
		if (c >= 0xFFF8)	c = 0xFFFF;
	}
	return c;
}

/////////r = play_music(PlayMusic);
/////////r = play_music(1);
char play_music(unsigned int fn)
{
	unsigned long	sec;
	unsigned int	remain;
	unsigned int	cn;
	unsigned int	i,j;
//	printf("DataStart: %u\n",DataStart);

	if (fn != Search_File(fn))
	{
		return -1;
	}
	FileSize = (unsigned long)DataBuff[28+64] + ((unsigned long)DataBuff[29+64]<<8)
			  + ((unsigned long)DataBuff[30+64]<<16) + ((unsigned long)DataBuff[31+64]<<24);
	Cluster = (unsigned int)DataBuff[26] + ((unsigned int)DataBuff[27] << 8);
	RemainSec = FileSize / 512;//文件占用的扇区数
	remain = FileSize % 512;
	sec = DataStart;
	for (j = 0; j<RemainSec; j++)
	{
		MMCReadSector(sec+j,&DataBuff[0]);
	//	DisPlay();
		for (i = 0; i < 512; i++)
		{
		 putchar(DataBuff[i]);
		}
	}
	if ((remain > 0)&&(remain < 512))
	{
		MMCReadSector(sec+RemainSec,&DataBuff[0]);
	//	DisPlay();
		for (i = 0; i < remain; i++)
		{
		 putchar(DataBuff[i]);
		}
	}
	return 0;
}

⌨️ 快捷键说明

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