📄 mmc_c.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 + -