Forum: Mikrocontroller und Digitale Elektronik ATmega32 ueber Software SPI programmieren scheitert


von Erz (Gast)


Angehängte Dateien:

Lesenswert?

Guten Abend,

bei dem Versuch, mit einem ATmega32 einen ATmega32 über die Hardware SPI 
auszulesen / programmieren hatte ich Erfolg.

In der Software Ausführung kein Erfolg. Bekomme als Return 255. Anbei 
mein Code in C als Test.
Habe es mit / ohne Delay´s Probiert und auch andere Ausführungen der 
Software SPI die ich im Internet gefunden habe. Im Datenblatt des 
ATmega´s steht dass die Übertragung Synchron sein muss, ist sie ja 
trotzdem oder nicht?

Ich möchte euch gerne um hilfe bitten (:

mfg
erz

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Erz schrieb:

> In der Software Ausführung kein Erfolg. Bekomme als Return 255. Anbei
> mein Code in C als Test.

ich sehe zwei Fehler in Deinem Code:

1. Das Einlesen der Daten (MISO) sollte nicht bei dem selben Taktpegel 
erfolgen, wie die Ausgabe (MOSI). Korrekt wäre:
- Datenbit ausgeben
- Takt hi
- Datenbit einlesen
- Takt low
(Wenn das zum SPI-Mode des SPI-Slaves passt).

2. Die Reihenfolge der Bits von ausgegebenem und eingelesenen Datenbyte 
stimmt nicht überein. Wenn Du die Daten mit dem MSB zuerst über MOSI 
ausgibst, solltest Du die Daten auch mit MSB voran von MISO einlesen.

Ob der SPI-Mode passt, kann ich nicht sagen.

Grüßle
Volker

Nachtrag: Hier ein Software-SPI, den ich vor Jahren auf einem ATtiny 
implementiert habe:
1
uint8_t SpiIO(uint8_t Dout) {
2
  uint8_t Mask, Din = 0;
3
  for(Mask = BMSK(7); Mask; Mask >>= 1) {
4
    DATA_PORT &= ~SCK;                            /* SCk -> L */
5
    if(Dout & Mask) DATA_PORT |=  DOUT_LED_JTAG;  /* Dout -> H */
6
    else            DATA_PORT &= ~DOUT_LED_JTAG;  /* Dout -> L */
7
    DATA_PORT |= SCK;                             /* SCk -> H */
8
    if(IN_PORT & DIN) Din |= Mask;                /* Din == H */
9
  } /* for(Mask = BMSK(7); Mask; Mask >>= 1) */
10
  return(Din);
11
}

: Bearbeitet durch User
von Erz (Gast)


Lesenswert?

Hallo Volker,

vielen dank für deine Antwort.

Zu 1, habe ich bereits getestet auch mit delay dazwischen (:

Zu 2, da ich nur Werte mit 255 zurück bekomme konnte ich das noch gar 
nicht testen ^^

gruß
erz

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Erz schrieb:

> Zu 1, habe ich bereits getestet auch mit delay dazwischen (:

Mir ist zwar nicht bekannt, ob es auch eine untere Grenze für den 
SPI-Takt gibt, aber die 5Hz, die Du mit Deinen Delays hast, erscheint 
mir grenzwertig.

> Zu 2, da ich nur Werte mit 255 zurück bekomme konnte ich das noch gar
> nicht testen ^^

Leider ist mir Dein Code zu kompliziert (ich habe noch nie eine dermaßen 
komplizierte Wandung von binär nach dezimal gesehen).

Aber an Deiner Stelle würde ich MISO und MOSI direkt verbinden und 
prüfen, ob dann das gelesene Byte mit dem gesendeten übereinstimmt.

Grüßle
Volker

P.S.: Man kann sich Byte-Werte auch hexadezimal ausgeben, dann ist die 
Codierung nicht ganz so kompliziert...

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

> ob es auch eine untere Grenze für den SPI-Takt gibt

Es gibt keine; ich hatte vor Jahren mal ein paar Bytes von Hand 
programmiert (das ist zwar mühsam, aber es geht).

von Erz (Gast)


Lesenswert?

Hallo Volker,

habe nun mal Probiert, den MISO und MOSI direkt zu verbinden. Hatte 
anfangs das Problem das ebenfalls nur 255 rauskam. Daraufhin habe ich 
etwas mit meinem if(PINB & (1<<PB6)) rumgespielt, als ich es negierte, 
bekam ich die veränderten Zustände zurück also nicht 0 sondern der 
Zustand des PIN´s..

Habe dann wieder den obigen Befehl eingefügt und seitdem funktioniert es 
bzw. ich erhalte richtige Werte. Verstehe aber nicht warum, der Compiler 
macht ja normal keine Fehler und an der Hardware lag es nicht 
(Leiterschluss,..) da meine Versuche auf den Gleichen PIN´s liegen 
zwischen Hardware SPI und Software SPI und ersteres funktioniert..

Trotzdem möchte ich mich für deine Hilfe bedanken (:
Und auf die Frage über die Taktgrenze kann ich die Aussage von S. 
Landolt nur bestätigen. Habe es ohne Delay und mit 200ms pause versucht 
und beides funktioniert Problemlos (:

gruß
erz

von Rächdschraipunk (Gast)


Lesenswert?

Erz schrieb:
> Zustand des PIN´s

Erz schrieb:
> auf den Gleichen PIN´s

Bitte keine Deppenapostrophen. Siehe
http://www.deppenapostroph.info

Die Mehrzahl von Pin schreibt man Pins.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Erz schrieb:

> Habe dann wieder den obigen Befehl eingefügt und seitdem funktioniert es
> bzw. ich erhalte richtige Werte.

Erstaunlich! Sind gesendetes Byte (data) und empfangenes (ret) wirklich 
gleich? Ich würde anhand Deines Codes vermuten, dass das empfangene Byte
gespiegelt ist, also LSB first.
1
if(data & (1 << (7 - x)))
...
1
if(PINB & (1<<PB6)) ret |= (1 << x);

> Und auf die Frage über die Taktgrenze kann ich die Aussage von S.
> Landolt nur bestätigen. Habe es ohne Delay und mit 200ms pause versucht
> und beides funktioniert Problemlos (:

Auf diese Idee bin ich auch noch nie gekommen... :-)

Grüßle
Volker

von Erz (Gast)


Lesenswert?

Rächdschraipunk schrieb:
> Bitte keine Deppenapostrophen. Siehe
> http://www.deppenapostroph.info
>
> Die Mehrzahl von Pin schreibt man Pins.

Schön wenn´s keine anderen Probleme gibt (:


Volker B. schrieb:
> ind gesendetes Byte (data) und empfangenes (ret) wirklich
> gleich? Ich würde anhand Deines Codes vermuten, dass das empfangene Byte
> gespiegelt ist, also LSB first.

Entschuldige bitte, ich hab das nicht korrigiert, die Bytes waren 
natürlich getauscht. Richtig ist hier
1
ret |= (1 << (7 - x));

gruß
erz

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.