Atmega8 + sd Karte

Hier mal mein Code, den ich selbst für die diskio.c geschrieben habe.



CodeBox C

void init_spi (void){
//SPI-Konfiguration SD
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<Soft_SS);
DDR_SPI &= ~(1<<DD_MISO);
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0); //MSB zuerst, SPI Modus 0
}

void select(void){
PORTB &= ~(1<<1);

}

void deselect(void){
PORTB |= (1<<1); 

}

 
Ich bin mir mit deinem ChipSelect-Signal nicht sicher.

Soll das auf dem Pin Soft_SS des PortB sein?
Dein ChipSelect funktioniert nur, wenn der auf PB1 ist. Also muss Soft_SS = 1 sein. Das kann ich hier nicht sehen.

Es fehlen dann noch deine Sende- und Empfangsroutine.

DDR_SPI ist DDRB

SCK -> PB5
MISO -> PB4
MOSI -> PB3

CS (SS) -> PB1?
 
/SS des Mega8 ist B2, B1 hat als Alternativfunktion nur OC1A.
Wie ihr wißt, kann ich kein Klammercodinesisch, aber:
  • DDR_SPI ist im vorliegenden Schnipsel 'ne Konstante, die auf DDRB verweist? Das setzt vorraus, daß die Pins alle am gleichen Port hängen (was hier(!) der Fall ist)
  • Zeile drei ist 'ne "harte" Zuweisung, oder? Es werden also alle anderen B-Beine auf Eingang geschaltet. Wenn vor Aufruf dieser Init schon Irgendwo Ausgänge gesetzt wurden, sind die jetzt Eingänge. Analog zu Zeile vier müßte hier eine "Oder Gleich"-Zuweisung stehen, oder? Insbesondere wird also auch der (Soft-) Select-Pin B1 auf Eingang geschaltet.
Trotzdem sollte dieser Code die Clk (und ggf MOSI) zappeln lassen, sobald man was ins SPDR prügelt, auch wenn das Target nicht korrekt (de-)selektiert wird.

Noch'n Hinweis zu CS-Signalen: während des Reset bis zum Init sind die Beine Tristate - bei SPI-ISP-AVR also auch während des Programmierens (abgesehen von Programmierpins, Reset und ggf dem dWire etc). Sollen Slaves am SPI-Bus währenddessen sicher deselektiert bleiben, empfiehlt sich ein externer Pullup an dessen CS-Leitung.
Thomas hatte deswegen schon mal lustige Effekte auf 'nem LCD, gelt @TommyB ...
 
  • Zeile drei ist 'ne "harte" Zuweisung, oder? Es werden also alle anderen B-Beine auf Eingang geschaltet. Wenn vor Aufruf dieser Init schon Irgendwo Ausgänge gesetzt wurden, sind die jetzt Eingänge. Analog zu Zeile vier müßte hier eine "Oder Gleich"-Zuweisung stehen, oder? Insbesondere wird also auch der (Soft-) Select-Pin B1 auf Eingang geschaltet.
In Zeile 3 weiß ich nicht, wie ich diese Zuweisung anders gestalten soll. Habe dies aus dem Datenblatt des Mikrocontroller übernommen.
Wird auch etwas über das SPDR geschickt, wenn ich die Funktion open oder write aufrufe?
 
Ja genau, mein /CS Signal liegt an PB1 an.
Wenn Du meinst, PB1 ist als Ausgang geschaltet und mit dem /CS-Eingang der SD-Karte verbunden, dann stimmts.
(Wenn ein /CS-Signal an PB1 anliegen würde, müßte PB1 Eingang sein und das SPI-Modul würde dann beim selektieren in den Slave-Modus gehen.)
In Zeile 3 weiß ich nicht, wie ich diese Zuweisung anders gestalten soll.


CodeBox C
DDR_SPI |= (1<<DD_MOSI)|(1<<DD_SCK)|(1<<Soft_SS);
 
Dein Code in #21 scheint mir soweit in Ordnung zu sein.

Deine Funktionen
spi_init()
spi_read()
spi_write()
select()
deselect()
musst du wie in dem Beispiel (avr sd/mmc) den Funktionen in diskio.c bekannt geben. Am besten nennst du deine Funktionen so, wie sie in diskio.c benannt sind.
Open und Write sollten dann automatisch deine Funktionen aufrufen und das SPI Modul deines Atmega8 verwenden.
 
Dein Code in #21 scheint mir soweit in Ordnung zu sein.
Sicher?
Zeile drei ist 'ne "harte" Zuweisung, oder? Es werden also alle anderen B-Beine auf Eingang geschaltet.
Insbesondere auch B2, der /SS-Pin des AVR.
Dieser ist default eh Eingang und tristate. Wenn also nach(!) dem Init nichts anderes zugewiesen wird, hängt der (ohne internem Pullup in der Luft.
Sollte der digitale Inputpuffer das einmal als low werten, schaltet er den AVR in den Slavemode (MSTR wird gelöscht), folglich wird beim späteren beschrieben von SPDR nur das zu sendende Byte im Transmit-Schieberegister abgelegt - da der AVR jetzt Slave ist, sendet er erst, wenn extern 'ne Clock anliegt.

Abgesehen davon gibts möglicherweise auch andere Hardware an anderen PortB-Beinen, die nicht erst nach dem SPI initialisiert werden ... müssen...soll....
 
... empfiehlt sich ein externer Pullup an dessen CS-Leitung.
Thomas hatte deswegen schon mal lustige Effekte auf 'nem LCD, gelt @TommyB ...
Jupp, erfolgreich getestet, wird benötigt ;)
Und selbst wenn nicht, stören tut der in keinem Fall.
https://www.makerconnect.de/index.php?threads/spaß-bei-der-arbeit.2852/page-2#post-33030

Vielleicht sollte man hier mal eine Kategorie "Hall of fail" einführen, oder Resoure oder so.
Kann doch nicht sein dass ich der Einzige bin dem sowas passiert ^^'
 
@LotadaC hat recht. Da SS hier ungenutzt ist (CS der SD Card liegt auf anderem Pin), muss man dafür sorgen, dass der inputPin auf high ist oder dass SS als Ausgang geschaltet ist.

(Während der Initialisierung der SD Card sollte der SPI Clock bei 100...400kHz liegen, danach kann man den erhöhen.)

So sollte es jetzt für ATmega8 passen ...
(es fehlen noch Sende- und Empangsfunktion)


CodeBox C
#define SPI_PORT PORTB
#define SPI_DDR DDRB
#define SPI_SCK 5
#define SPI_MISO 4
#define SPI_MOSI 3
#define SPI_SS 2 // nicht genutzt
#define SPI_CS 1 // CS SD Card

void init_spi (void)
{
  uint8_t data;

  SPI_DDR |= (1<<SPI_MOSI) | (1<<SPI_SCK) | (1<<SPI_SS) | (1<<SPI_CS);
  SPI_DDR &= ~(1<<SPI_MISO);

  SPI_PORT |= (1<<SPI_SS) | (1<<SPI_CS);
  SPI_PORT &= ~((1<<SPI_SCK) | (1<<SPI_MISO));

  SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0); // MSB zuerst, SPI Modus 0

  data = SPSR;
  data = SPDR; // clr IF
}
void select(void)
{
  SPI_PORT &= ~(1<<SPI_CS);
}
void deselect(void)
{
  PORTB |= (1<<SPI_CS); 
}
 
Anbei mal meine Lösung. Ist jetzt erstmal nur für den MEGA32. Andere (ATMEGA´S oder TINY´S) können aber problemlos ergänzt werden.
 

Anhänge

  • spi.c
    3 KB · Aufrufe: 9
  • spi.h
    1,5 KB · Aufrufe: 8
Super Danke!
Wenn ich nun etwas auf die SD-Karte schreiben möchte, muss ich den Befehl pf_write(); aufrufen. Was genau muss ich da in die Klammern schreiben?
Und genügt es, wenn ich davor disk_initialize(); pf_mount(); und pf_open(); aufrufe oder benötige ich noch mehr?
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)