Hallo liebe HCS12 Nutzer,
ich möchte größere Datenmengen lesen / schreiben und möchte aus diesem
Grund eine SD Karte an meinen HCS12DP512 anbinden. Hat jemand von euch
schon mal versucht SD Karten an ein HCS12 System zu adaptieren? Ich bin
für jeden Tip dankbar.
P.S.: Dachte an das Eval board von Glyn. Leider ist dies ohne SW!
Grüße
Micky
Hallo Jürgen,
JA, habe vor ca. zwei Wochen den Durchbruch geschafft. Hatte noch ein
kleines Problem bezüglich der Kommunikation via SPI mit der SD Karte.
Nun sind aber alle Probleme beseitigt. Mein System ist ein FAT16/FAT32
System, welches Schreiben/Lesen kann. Verzeichnisse werden natürlich
auch voll unterstützt, mehrere Dateien können auch gleichzeitig zum
schreiben und/oder Lesen geöffnet werden.
Bedingt durch den geringen RAM Verbrauch ist das System nicht so
schnell, aber nach meiner Spezifikation ist es mehr als ausreichend.
Grüße
Micky
Das ist ja super und freut mich für dich. Wäre es möglich dass du mir
helfen kannst einen Einstieg in die Geschichte zu finden?
Ich bräuchte für meine Studienarbeit an der Hochschule eine Möglichkeit
Daten zu loggen. Ich entwickle gerade ein Display, dass Sensordaten von
einem KFZ anzeigen kann. Die ganzen Sensoren sind entweder direkt an die
s12compact Platine angeschlossen, oder die Daten kommen vom Steuergerät.
Ziel wäre es jetzt ausgewählte Daten in der SD- Karte zu speichern. Dazu
wäre es schön, wenn sich nach jedem Reset eine Datei öffnnen ließe und
dann die Daten in einem File getrennt duch Kommas abgespeicht würden.
Was ich nicht überblicken kann ist, ob die Geschwindigkeit der
Speicherung ausreichend wäre. Ich will Daten wie Temperatur loggen, da
käme es nicht auf hohe Geschwindigkeit an. Ich will aber auch die
Drehzahl haben. Da wären schon mehrere Punkte pro Sekunde wünschenswert.
Also bitte, wenn du mir irgendwie auf die Sprünge helfen könntest wäre
ich überglücklich.
Grüße
Jürgen
Hallo Jürgen,
na klar kann ich dir bei dieser Sache unter die Arme greifen!!
Also, ich würde vorschlagen, dass du die Daten sammelst und zyklisch auf
die SD Karte schreibst. Welche Größe hier Sinn macht, hängt in erster
Linie von deiner Anwendung ab. Auch ob du die Daten im RAM sammelst,
oder sie ins interne EEPROM schreibst. Jedes Byte gleich auf die SD
Karte schreiben zu wollen verbraucht zu viel Resource Zeit.
Ich habe momentan ein Glyn Eval Board (EVBMMCSD01) über SPI am
HCS12DP512 angekoppelt. Das Board unterstützt 3V und 5V Applikationen,
da es über einen Spannungsregler und einen Pegelanpasser verfügt. Die
gesammte Software (HAL, SD-Manager, FAT-System) stammt aus meiner Feder.
Ich an deiner Stelle würde die ganze Sach buttom up angehen und würde
zuerst die Konfiguration der SPI Schnittstelle auf deinem Prozessor
angehen. Danach täte ich mich mit dem SD Karten Manager beschäftigen,
welche Befehle von/zur SD Karte handelt (im wesentlichen InitCard,
ReadSektor, WriteSector). Kannst du bis hierher Blöcke auf der SD Karte
lesen und schreiben, würde ich die letzte Hürde angehen: das FAT System.
Für die beiden zuletzt genannten Dinge wirst du hier im Forum in Sachen
C-Code sicher fündig werden.
Grüße
Micky
Super! Danke für die schnelle Antwort. Das Board kannte ich nicht.
Müsste für meinen Zweck genau richtig sein und der Preis ist ja auch in
Ordnung.
Dann versuche ich es so wie du gesagt hast. Die SPI müsste ich in den
Griff bekommen.
Sind bei dem Board Beispiele für den SD Karten Manager dabei. Das stelle
ich mir schwierig vor wenn man alles aus den Datenblättern der SD
Kartenherstellern heraussuchen müsste. Wie ist den die mitgelieferte
Software allgemein? Kann man damit etwas anfangen?
Das FAT System macht mir am meisten Sorgen. Wielange hast du dafür
gebraucht bis das lief?
Danke
Jürgen
Hallo Jürgen,
ich muss gestehen, an die SW des Glyn boards kann ich mich gar nicht
mehr so recht erinnern. Aber viel ist es nicht, glaub ich.
Um mich einzuarbeiten habe ich mir neben der SD Karten Spezifikation und
dem Prozessorhandbuch auch C-Code, welchen man hier im Forum downloaden
kann angesehen. Da waren ein paar gute Dinge dabei, die mit Sicherheit
verwendbar wären und auch gut funktionieren.
Grüße
Micky
Hallo Micky,
ich habe mich nun mit dem Implementieren des Codes beschäftigt. Ich habe
jetzt doch nicht die Hardware von Glyn verwendet, sondern den Aufbau von
Ulrich Radig in der "optimalen Version". Seinen Code habe ich auch als
Basis verwendet. Das anpassen an HCS12 und ICC Compiler geht ganz gut,
aber ich habe es trotzdem nicht geschafft die Karte zu initialisieren.
Ich denke es liegt an meiner SPI Konfiguration. Die Hardware sollte
eigentlich passen. Leider habe ich im Moment kein Oszi zur Hand und kann
somit nicht optimal arbeiten.
Trotzdem meine SPI Konfiguration vielleicht fällt jemanden etwas auf.
Speziall bei den SPI Einstellung bin ich mir nicht sicher ob das so
richtig ist.
//######################################################################
###
//Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE)
UINT8 mmc_init ()
//######################################################################
###
{
UINT8 Timeout = 0;
UINT8 a;
UINT8 b;
UINT8 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
initLED();
//Konfiguration des Ports an der die MMC/SD-
Karte angeschlossen wurde
MMC_Direction_REG &=~(1<<SPI_DI);//Setzen von Pin
MMC_DI auf Input
MMC_Direction_REG |= (1<<SPI_Clock); //Setzen von Pin
MMC_Clock auf Output
MMC_Direction_REG |= (1<<SPI_DO);//Setzen von Pin MMC_DO auf
Output
MMC_Direction_REG |= 0x70; //Setzen von Pin MMC_Chip_Select auf
Output
MMC_Direction_REG |= (1<<SPI_SS);
MMC_Write |= 0x70; //Setzt den Pin MMC_Chip_Select auf High Pegel
for(a = 0; a < 100; a++){
a++;
a--;
}; //Wartet eine kurze Zeit
#if SPI_Mode
SPI1BR = 0x06; //set SPI Rate (25MHz/64=195kHz)
SPI1CR1 = BM_SPE | BM_MSTR ;// enable SPI, Master Mode
SPI1CR2 = 0; // as default
#endif
//Initialisiere MMC/SD-Karte in den SPI-Mode
for (b = 0; b < 0x0F ; b++) //Sendet min 74+ Clocks an die
MMC/SD-Karte
{
mmc_write_byte(0xff);
}
//Sendet Commando CMD0 an MMC/SD-Karte
while(mmc_write_command (CMD) !=1)
{
if (Timeout++ > 200)
{
MMC_Disable();//onLED();
return(1); //Abbruch bei Commando1 (Return
Code1)
}
}
//Sendet Commando CMD1 an MMC/SD-Karte
Timeout = 0; //onLED();
CMD[0] = 0x41;//Commando 1
CMD[5] = 0xFF;
while( mmc_write_command (CMD) !=0)
{
if (Timeout++ > 400)
{
MMC_Disable();
return(2); //Abbruch bei Commando2 (Return
Code2)
}
}
#if SPI_Mode
//SPI Bus auf max Geschwindigkeit
//SPCR &= ~((1<<SPR0) | (1<<SPR1)); faber
//SPSR = SPSR|(1<<SPI2X);
#endif
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable();
return(0);
}
//######################################################################
###
//Sendet ein Commando an die MMC/SD-Karte
UINT8 mmc_write_command (UINT8 *cmd)
//######################################################################
###
{
UINT8 tmp = 0xff;
UINT16 Timeout = 0;
UINT8 a;
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable();
//sendet 8 Clock Impulse
mmc_write_byte(0xFF);
//set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
MMC_Enable();
for (a = 0; a < 100; a++); //kurz warten faber
//sendet 6 Byte Commando
for (a = 0; a < 0x06; a++) //sendet 6 Byte Commando zur MMC/SD-
Karte
{
mmc_write_byte(*cmd++);
}
//Wartet auf ein gültige Antwort von der MMC/SD-Karte
while (tmp == 0xff)
{
tmp = mmc_read_byte();
if (Timeout++ > 500)
{
break; //Abbruch da die MMC/SD-Karte nicht
Antwortet
}
}
return(tmp);
}
//######################################################################
###
//Routine zum Empfangen eines Bytes von der MMC-Karte
/*inline*/ UINT8 mmc_read_byte (void)
//######################################################################
###
{
UINT8 Byte = 0;
#if SPI_Mode //Routine für Hardware SPI
while (!BM_SPTEF); /* Wait for Tx buffer empty */
SPI1DR = 0xFF;
while (!BM_SPIF); /* Wait for Rx buffer full */
Byte = SPI1DR;
#endif
return (Byte);
}
//######################################################################
###
//Routine zum Senden eines Bytes zur MMC-Karte
/*inline*/ void mmc_write_byte (UINT8 Byte)
//######################################################################
###
{
UINT8 a;
#if SPI_Mode //Routine für Hardware SPI
while ((SPI1SR & BM_SPTEF) == 0);
SPI1DR = Byte; //Sendet ein Byte
#endif
}