Hallo,
ich habe eine einfache FAT16 Format Funktion geschrieben, mit dem man die SD-Karte mit dem Microcontroller formatieren kann.
Der Umweg über Windows kann manchmal zu umständlich sein, vor allem
wenn man viele Karten formatieren muss.
Ich habe nichts anderes getan, als 2 Sektoren ( 0 und 99) die Windows beim Formatieren anlegt 1:1 zu kopieren und in die Karte zu schreiben.
Achtung : Ich habe eine schon einmal formatierte SD Karte benutzt,
die ich mit der Format Funktion reformatiert habe (Sector 0 und 99 überschrieben) und wieder im PC getestet. Es läuft einwandfrei.
Eine unformatierte karte habe ich nicht und ich habe auch keine komplett gelöscht, sodass alles auf der Karte weg ist.
Soviel ich weiss, reicht aus, die 2 Sektoren zu schreiben, damit Windows die Karte als gültige formatierte Karte erkennt. Sollte das nicht der Fall sein, so müsste man das leicht festellen, wenn die Karte niemals
formatiert wurde und sie danach im PC einliest.
( Man kann auch alle Sektoren auf der Karte mit 0xFF schreiben, dann ist alles weg)
Ich benutze einen Motorola MCU (Achtung : Big Endian Reihenfolge von Bytes, wenn es Werte > 1 Byte geht!) und nicht einen AVR, aber das ist bei diesem Code egal.
void format_card_fat16(void)
{
u08 Buffer[512];
u08 MBR[512] =
{
0xEB,0x3C,0x90,0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30,0x00,0x02,0x04,0x08,0x00,
0x02,0x00,0x02,0x00,0x00,0xF8,0xF0,0x00,0x3F,0x00,0xFF,0x00,0x63,0x00,0x00,0x00,
0x9D,0xBE,0x03,0x00,0x00,0x00,0x29,0x77,0x81,0x0A,0x9A,0x4E,0x4F,0x20,0x4E,0x41,
0x4D,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x36,0x20,0x20,0x20,0x33,0xC9,
0x8E,0xD1,0xBC,0xF0,0x7B,0x8E,0xD9,0xB8,0x00,0x20,0x8E,0xC0,0xFC,0xBD,0x00,0x7C,
0x38,0x4E,0x24,0x7D,0x24,0x8B,0xC1,0x99,0xE8,0x3C,0x01,0x72,0x1C,0x83,0xEB,0x3A,
0x66,0xA1,0x1C,0x7C,0x26,0x66,0x3B,0x07,0x26,0x8A,0x57,0xFC,0x75,0x06,0x80,0xCA,
0x02,0x88,0x56,0x02,0x80,0xC3,0x10,0x73,0xEB,0x33,0xC9,0x8A,0x46,0x10,0x98,0xF7,
0x66,0x16,0x03,0x46,0x1C,0x13,0x56,0x1E,0x03,0x46,0x0E,0x13,0xD1,0x8B,0x76,0x11,
0x60,0x89,0x46,0xFC,0x89,0x56,0xFE,0xB8,0x20,0x00,0xF7,0xE6,0x8B,0x5E,0x0B,0x03,
0xC3,0x48,0xF7,0xF3,0x01,0x46,0xFC,0x11,0x4E,0xFE,0x61,0xBF,0x00,0x00,0xE8,0xE6,
0x00,0x72,0x39,0x26,0x38,0x2D,0x74,0x17,0x60,0xB1,0x0B,0xBE,0xA1,0x7D,0xF3,0xA6,
0x61,0x74,0x32,0x4E,0x74,0x09,0x83,0xC7,0x20,0x3B,0xFB,0x72,0xE6,0xEB,0xDC,0xA0,
0xFB,0x7D,0xB4,0x7D,0x8B,0xF0,0xAC,0x98,0x40,0x74,0x0C,0x48,0x74,0x13,0xB4,0x0E,
0xBB,0x07,0x00,0xCD,0x10,0xEB,0xEF,0xA0,0xFD,0x7D,0xEB,0xE6,0xA0,0xFC,0x7D,0xEB,
0xE1,0xCD,0x16,0xCD,0x19,0x26,0x8B,0x55,0x1A,0x52,0xB0,0x01,0xBB,0x00,0x00,0xE8,
0x3B,0x00,0x72,0xE8,0x5B,0x8A,0x56,0x24,0xBE,0x0B,0x7C,0x8B,0xFC,0xC7,0x46,0xF0,
0x3D,0x7D,0xC7,0x46,0xF4,0x29,0x7D,0x8C,0xD9,0x89,0x4E,0xF2,0x89,0x4E,0xF6,0xC6,
0x06,0x96,0x7D,0xCB,0xEA,0x03,0x00,0x00,0x20,0x0F,0xB6,0xC8,0x66,0x8B,0x46,0xF8,
0x66,0x03,0x46,0x1C,0x66,0x8B,0xD0,0x66,0xC1,0xEA,0x10,0xEB,0x5E,0x0F,0xB6,0xC8,
0x4A,0x4A,0x8A,0x46,0x0D,0x32,0xE4,0xF7,0xE2,0x03,0x46,0xFC,0x13,0x56,0xFE,0xEB,
0x4A,0x52,0x50,0x06,0x53,0x6A,0x01,0x6A,0x10,0x91,0x8B,0x46,0x18,0x96,0x92,0x33,
0xD2,0xF7,0xF6,0x91,0xF7,0xF6,0x42,0x87,0xCA,0xF7,0x76,0x1A,0x8A,0xF2,0x8A,0xE8,
0xC0,0xCC,0x02,0x0A,0xCC,0xB8,0x01,0x02,0x80,0x7E,0x02,0x0E,0x75,0x04,0xB4,0x42,
0x8B,0xF4,0x8A,0x56,0x24,0xCD,0x13,0x61,0x61,0x72,0x0B,0x40,0x75,0x01,0x42,0x03,
0x5E,0x0B,0x49,0x75,0x06,0xF8,0xC3,0x41,0xBB,0x00,0x00,0x60,0x66,0x6A,0x00,0xEB,
0xB0,0x4E,0x54,0x4C,0x44,0x52,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,0x44,0x61,
0x74,0x65,0x6E,0x74,0x72,0x84,0x67,0x65,0x72,0x20,0x65,0x6E,0x74,0x66,0x65,0x72,
0x6E,0x65,0x6E,0xFF,0x0D,0x0A,0x4D,0x65,0x64,0x69,0x65,0x6E,0x66,0x65,0x68,0x6C,
0x65,0x72,0xFF,0x0D,0x0A,0x4E,0x65,0x75,0x73,0x74,0x61,0x72,0x74,0x3A,0x20,0x54,
0x61,0x73,0x74,0x65,0x20,0x64,0x72,0x81,0x63,0x6B,0x65,0x6E,0x0D,0x0A,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xC4,0xD3,0x55,0xAA };
u16 i;
for(i=0;i<512;i++) // Buffer mit 0 ausfuellen.
Buffer=0;
for(i=0;i<120;i++) // loesche die ersten 120 sektoren. Das reicht aus
mmc_write_sector (i,Buffer);
Buffer[447] = 0x03; // die Werte fuer Sektor 0 jetzt
Buffer[448] = 0x04;
Buffer[450] = 0x06;
Buffer[451] = 0x07;
Buffer[452] = 0xE0;
Buffer[453] = 0xBE;
Buffer[454] = 0x63;
Buffer[458] = 0x9D;
Buffer[459] = 0xBE;
Buffer[460] = 0x03;
Buffer[510] = 0x55; // Signature
Buffer[511] = 0xAA;
mmc_write_sector (0,Buffer); // sector 0
mmc_write_sector (99,MBR); // sector 99
}
Big Endian Prozesoren wie Motorola. etc
Wer den Code von AVRs auf Motorola Prozessoren portiert, sollte
nicht vergessen, dass die Integer und 32 Bit Werte die ausgelesen werden , von Prozessor umgekehrt gelesen werden - ein 32 bit Wort WXYZ für AVR ist ZYXW für Motorola und ein 16 Bit XY Wort ist für Motorola YX. Und da sind einige Stellen im AVR Code, die für den Motorola zu falschen Werte führen, wenn man den Code nicht anpasst !
Ich habe ein Paar Tage wegen dem Big Endian Problem verloren, da ich nie vorher nie für Motorolas codiert habe und daran gar nicht gedacht hatte.
Z.B. beim Lesen des Sectors 99, muss man nach dem Auslesen folgende Bytes tauschen, damit sie für den Motorola richtig sind:
bootp->BPB_BytesPerSec = (uint16) (Buffer[12]<<8) | Buffer[11];
bootp->BPB_BytesPerSec = (uint16) (Buffer[12]<<8) | Buffer[11];
bootp->BPB_RsvdSecCnt = (uint16) (Buffer[15]<<8) | Buffer[14];
bootp->BPB_RootEntCnt = (uint16) (Buffer[18]<<8) | Buffer[17];
bootp->BPB_TotSec16 = (uint16) (Buffer[20]<<8) | Buffer[19];
bootp->BPB_FATSz16 = (uint16) (Buffer[23]<<8) | Buffer[22];
bootp->BPB_SecPerTrk = (uint16) (Buffer[25]<<8) | Buffer[24];
bootp->BPB_HiddSec = (uint16) (Buffer[27]<<8) | Buffer[26];
Sonst stimmen die Werte gar nicht, obwohl der Lesevorgang an sich richtig ist. Beim Schreiben muss man das genauso achten.
Über Big Endian : http://www.libsdl.org/intro.de/usingendian.html
Danke Ulrich für deine Mühe !
Gruss, grabby
[/b]