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

📄 mmc_c.h

📁 在基于avr内核的单片机上实现MP3播放器的功能
💻 H
字号:
#include "mmc.h"

#define uartDebugByte  0
//低速模式  //spi low speed
/*
SPI2X SPR1 SPR0 SCK 频率
000 f /4
osc
001 f /16
osc
010 f /64
osc
011 f /128
osc
100 f /2
osc
101 f /8
osc
110 f /32
osc
111 f /64
osc*/
void SPI_Low(void)
{
	SPCR =   _BV(SPE)|_BV(MSTR)|_BV(SPR1)|_BV(SPR0); 
	CLRBIT(SPSR,SPI2X);    ///Fosc/128
}

//高速模式	//spi full speed
void SPI_High(void)
{

	/*SPCR =  _BV(SPE)|_BV(MSTR)|_BV(SPR0);//;低点稳定Fosc/8
	SETBIT(SPSR,SPI2X);//CLRBIT(SPSR,SPI2X);//*/

	SPCR =  _BV(SPE)|_BV(MSTR);//|_BV(SPR0)
	CLRBIT(SPSR,SPI2X);//CLRBIT(SPSR,SPI2X);//低点稳定Fosc/4
}//Fosc/2   SETBIT(SPSR,SPI2X);


void SD_port_init(void)
{
out(SD_CS);
out(SD_DI);
in(SD_DO);
out(SD_Clk);
}


//写读一个字节			//read and write one byte
uint8 SPI_Write_Byte(uint8 val)
{
	SPDR = val;
	while(!(SPSR & _BV(SPIF)));
	return SPDR;
}

/*uint8 SPI_Read_Byte(void)
{
	SPDR = 0xff;
	while(!(SPSR & _BV(SPIF)));
	return SPDR;
}
*/

//sd卡写命令		//sd send command
uint8 SD_Send_Command(uint8 cmd, uint32 arg)
{
	uint8 tmp;
	uint8 retry=0;
	
	//for(i=0;i<7;i++)
	//SPI_Write_Byte(0xff);

 
	SPI_CS_Assert();
	
	
	SPI_Write_Byte(0xff);
	
	SPI_Write_Byte(cmd | 0x40);//分别写入命令	//send command
	SPI_Write_Byte(arg>>24);
	SPI_Write_Byte(arg>>16);
	SPI_Write_Byte(arg>>8);
	SPI_Write_Byte(arg);
	SPI_Write_Byte(0x95);
	
	SPI_Write_Byte(0xff);
	
	while((tmp = SPI_Write_Byte(0xff)) == 0xff)//等待响应,	//wait response
		if(retry++ > 20) break;//超时退出					//time out error
    
    SPI_CS_Deassert();

	return tmp;//返回状态值					//return state
}

//sd卡复位		//reset sd card (software)
uint8 SD_Reset(void)
{
	uint8 i;
	uint8 retry=0;
	uint8 tmp=0;
	
	SD_port_init();
	SPI_Low();
	SPI_CS_Deassert();
	for(i=0;i<20;i++)
	SPI_Write_Byte(0xff);
	
		do
	{
		for(i=0;i<20;i++) SPI_Write_Byte(0xff);
		tmp = SD_Send_Command(0, 0);//发idle命令	//send idle command
		retry++;
		if(retry>10) return 1;//超时退出		//time out
	} while(tmp!= 0x01);	


	retry = 0;
	do
	{
		tmp = SD_Send_Command(1, 0);//发active命令	//send active command
		retry++;
		if(retry>10) return 2;//超时退出		//time out
	} while(tmp);
	
	
	
	tmp = SD_Send_Command(59, 0);//关crc		//disable CRC

	tmp = SD_Send_Command(16, 512);//设扇区大小512	//set sector size to 512
	
	SPI_High();
	return 0;//正常返回		//normal return
}

//读一个扇区		//read one sector
uint8 SD_Read_Single_Block(uint32 sector, uint8* buffer)
{
	uint8 tmp;
	uint16 i;
	uint16 retry=0;


SPI_High();

	do
	{
		tmp = SD_Send_Command(17, sector<<9);//读命令	//read command
		retry++;
		if(retry>10) return 1;//超时退出		//time out
	} while(tmp != 0x00);	


	SPI_CS_Assert();
	retry=0;

	//等数据的开始	//wait to start recieve data
	while(SPI_Write_Byte(0xff) != 0xfe )
	   {
	if(retry++ > 8000){SPI_CS_Deassert();return 2;}
       }
	for(i=0; i<512; i++)//读512个数据	//read 512 bytes
	{
#if  uartDebugByte
		tmp= SPI_Write_Byte(0xff);
			*buffer++=tmp ;	
UDR=tmp;
while(!(UCSRA & 0x40));
UCSRA |= 0x40;
_delay_ms(10);

#else 
*buffer++= SPI_Write_Byte(0xff);
#endif
	}

	SPI_Write_Byte(0xff);//伪crc
	SPI_Write_Byte(0xff);
	
	SPI_CS_Deassert();

	return ok;
}


//写一个扇区		//wirite one sector //not used in this application
uint8 SD_Write_Single_Block(uint32 sector, uint8* buffer)
{
	uint8 tmp;
	uint16 i;
	uint16 retry=0;
  
SPI_High();
	
	do
	{   
		tmp=SD_Send_Command(24, sector<<9);//写命令	//send command
		retry++;
		if(retry>10) return 1;//超时退出		//time out
	} while(tmp != 0x00);	



	SPI_CS_Assert();
	
	SPI_Write_Byte(0xff);
	SPI_Write_Byte(0xff);

	SPI_Write_Byte(0xfe);//发开始符			//send start byte
	
	for(i=0; i<512; i++)//送512字节数据		//send 512 bytes data
	{
		SPI_Write_Byte(*buffer++);

	}
	
	SPI_Write_Byte(0xff);
	SPI_Write_Byte(0xff);
	
	tmp = SPI_Write_Byte(0xff);
	
	if( (tmp&0x1f) != 0x05)//等待是否成功	//judge if it successful
	{
		SPI_CS_Deassert();
		return tmp;
	}
	//等待操作完		//wait no busy
	
	retry=0;
	while(SPI_Write_Byte(0xff)!= 0xFF)
	  {if(retry++ > 8000){SPI_CS_Deassert();return 2;}}

	SPI_CS_Deassert();

	return ok;
}


⌨️ 快捷键说明

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