?? mmc.c
字號:
/*
Copyright: Radig Ulrich mailto: mail@ulrichradig.de
Author: Radig Ulrich
Remarks: this Copyright must be included
known Problems: none
Version: 28.05.2004
Description: Ansteuerung einer MMC/SD-Memory-Card
*/
#define MMC_Write PORTB //Port an der die MMC/SD-Karte angeschlossen ist
#define MMC_Read PINB
#define MMC_Direction_REG DDRB
#define MMC_DI 0 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist
#define MMC_DO 1 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist
#define MMC_Clock 2 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist
#define MMC_Chip_Select 3 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist
//Prototypes
char Read_Byte_MMC(void);
void Write_Byte_MMC(char);
char Init_MMC(void);
char Read_Block_MMC (unsigned long, char *Buffer);
char Write_Block_MMC (unsigned long, char *Buffer);
char Write_Command_MMC (char *CMD);
//Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE)
char Init_MMC ()
{
char tmp = 0;
char Timeout;
//Konfiguration des Ports an der die MMC/SD-Karte angeschlossen wurde
cbi(MMC_Direction_REG,MMC_DI); //Setzen von Pin MMC_DI auf Input
sbi(MMC_Direction_REG,MMC_Clock); //Setzen von Pin MMC_Clock auf Output
sbi(MMC_Direction_REG,MMC_DO); //Setzen von Pin MMC_DO auf Output
sbi(MMC_Direction_REG,MMC_Chip_Select); //Setzen von Pin MMC_Chip_Select auf Output
sbi(MMC_Write,MMC_Chip_Select); //Setzt den Pin MMC_Chip_Select auf High Pegel
sbi(MMC_Write,MMC_DO); //Setzt den Pin MMC_DO auf High Pegel
//Initialisiere MMC/SD-Karte in den SPI-Mode
for (int b = 0;b<0x0f;b++) //Sendet min 74+ Clocks an die MMC/SD-Karte
{
Write_Byte_MMC(0xff);
}
//Sendet Commando CMD0 an MMC/SD-Karte
Timeout = 0;
char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
while(tmp!=1)
{
tmp = Write_Command_MMC (CMD);
//printf ("Return Code from MMC/SD Init CMD0 %x\n",tmp);
Timeout++;
if (Timeout > 20)
{
return(1); //Abbruch bei Commando1 (Return Code1)
}
}
//Sendet Commando CMD1 an MMC/SD-Karte
Timeout = 0;
CMD[0] = 0x41;//Commando 1
CMD[5] = 0xFF;
while(tmp!=0)
{
tmp = Write_Command_MMC (CMD);
//printf ("Return Code from MMC/SD Init CMD1 %x\n",tmp);
Timeout++;
if (Timeout > 10)
{
return(2); //Abbruch bei Commando2 (Return Code2)
}
}
return(0);
}
//Sendet ein Commando an die MMC/SD-Karte
char Write_Command_MMC (char *CMD)
{
char tmp = 0xff;
unsigned int Timeout = 0;
//sendet 8 Clock Impulse
sbi(MMC_Write,MMC_Chip_Select);//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
Write_Byte_MMC(0x00);
//sendet 6 Byte Commando
cbi(MMC_Write,MMC_Chip_Select);//set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
for (int a = 0;a<0x06;a++) //sendet 6 Byte Commando zur MMC/SD-Karte
{
Write_Byte_MMC(*CMD++);
}
while (tmp == 0xff) //Wartet auf ein g黮tige Antwort von der MMC/SD-Karte
{
tmp = Read_Byte_MMC();
Timeout++;
if (Timeout > 1000)
{
break; //Abbruch da die MMC/SD-Karte nicht Antwortet
}
}
return(tmp);
}
//Routine zum Empfangen eines Bytes von der MMC-Karte (Soft_SPI)
char Read_Byte_MMC (void)
{
char Byte = 0;
for (int a=8; a>0; a--) //das Byte wird Bitweise nacheinander Empangen MSB First
{
cbi (MMC_Write,MMC_Clock); //erzeugt ein Clock Impuls (Low)
if (bit_is_set(MMC_Read,MMC_DI) > 0) //Lesen des Pegels von MMC_DI
{
sbi (Byte,(a-1));
}
else
{
cbi (Byte,(a-1));
}
sbi (MMC_Write,MMC_Clock); //setzt Clock Impuls wieder auf (High)
}
return(Byte);
}
//Routine zum Senden eines Bytes zur MMC-Karte (Soft_SPI)
void Write_Byte_MMC (char Byte)
{
for (int a=8; a>0; a--) //das Byte wird Bitweise nacheinander Gesendet MSB First
{
if (bit_is_set(Byte,(a-1))>0) //Ist Bit a in Byte gesetzt
{
sbi (MMC_Write,MMC_DO); //Set Output High
}
else
{
cbi (MMC_Write,MMC_DO); //Set Output Low
}
cbi (MMC_Write,MMC_Clock); //erzeugt ein Clock Impuls (LOW)
sbi (MMC_Write,MMC_Clock); //setzt Clock Impuls wieder auf (High)
}
sbi (MMC_Write,MMC_DO);
}
//Routine zum lesen eines Blocks(512Byte) von der MMC/SD-Karte
char Read_Block_MMC (unsigned long addr,char *Buffer)
{
char tmp;
int Timeout;
char CMD17[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; //Commando 16 zum lesen eines Blocks
/*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
addr wird von Blocks zu Bytes umgerechnet danach werden
diese in das Commando eingef黦t*/
addr = addr << 9; //addr = addr * 512
CMD17[1] = ((addr & 0xFF000000) >>24 );
CMD17[2] = ((addr & 0x00FF0000) >>16 );
CMD17[3] = ((addr & 0x0000FF00) >>8 );
//Sendet Commando CMD16 an MMC/SD-Karte (Read 1 Block/512 Bytes)
tmp = Write_Command_MMC (CMD17);
if (tmp != 0)
{
return(tmp);
}
//Wartet auf Start Byte von der MMC/SD-Karte (FEh/Start Byte)
Timeout = 0;
while (tmp != 0xfe)
{
tmp = Read_Byte_MMC();
Timeout++;
if (Timeout > 1000)
{
return(1);
}
}
//Lesen des Bolcks (512Bytes) von MMC/SD-Karte
for (int a=0;a<512;a++)
{
*Buffer++ = Read_Byte_MMC();
}
//CRC-Byte auslesen
tmp = Read_Byte_MMC();//CRC - Byte wird nicht ausgewertet
tmp = Read_Byte_MMC();
return(0);
}
//Routine zum schreiben eines Blocks(512Byte) auf die MMC/SD-Karte
char Write_Block_MMC (unsigned long addr, char *Buffer)
{
char tmp;
char CMD24[] = {0x58,0x00,0x00,0x00,0x00,0xFF}; //Commando 24 zum schreiben eines Blocks
/*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
addr wird von Blocks zu Bytes umgerechnet danach werden
diese in das Commando eingef黦t*/
addr = addr << 9; //addr = addr * 512
CMD24[1] = ((addr & 0xFF000000) >>24 );
CMD24[2] = ((addr & 0x00FF0000) >>16 );
CMD24[3] = ((addr & 0x0000FF00) >>8 );
//Sendet Commando CMD24 an MMC/SD-Karte (Write 1 Block/512 Bytes)
tmp = Write_Command_MMC (CMD24);
if (tmp != 0)
{
return(tmp);
}
//Wartet einen Moment und sendet einen Clock an die MMC/SD-Karte
for (int a=0;a<100;a++)
{
tmp = Read_Byte_MMC();
}
//Sendet Start Byte an MMC/SD-Karte
Write_Byte_MMC(0xFE);
//Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte
for (int a=0;a<512;a++)
{
Write_Byte_MMC(*Buffer++);
}
//CRC-Byte schreiben
Write_Byte_MMC(0xFF); //Schreibt Dummy CRC
Write_Byte_MMC(0xFF); //CRC Code wird nicht benutzt
//Wartet auf MMC/SD-Karte Bussy
tmp = 0;
while (tmp != 0xff)
{
tmp = Read_Byte_MMC();
}
return(0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -