Forum: Mikrocontroller und Digitale Elektronik SPI funktiniert nicht


von Fred (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe gerade versucht eine Verbindung über SPI zwischen zwei 
Mikrocontrollern herzustellen. Dazu hab ich ein Programm aus der 
Codesammlung des Forums genommen. Der dort verwendete Controller war der 
Atmega8, ich benutze den Atmega48. Die Pinbelegungen der beiden 
Controller sind identisch, daran dürfte es also nicht liegen. Beide 
Controller besitzen einen Takt von 8MHz.

Hab den Code mal angehängt. Woran kann es liegen?


von Fred (Gast)


Angehängte Dateien:

Lesenswert?

Und hier der Code für den Slave

von Fred (Gast)


Lesenswert?

Anscheinend bleibt das Programm beim Master in dieser Zeile hängen:

while (!(SPSR & (1<<SPIF)));

von Fred (Gast)


Lesenswert?

Keiner ne Idee? Komm einfach nicht weiter.....

von Dirk H. (arm-dran)


Lesenswert?

Hallo Fred,

das ist ja nur der Sourcecode eines Controllers.
Ist der andere identisch.
Mußt ja erst mal rausfinden, an welchem der beiden es liegt?

von Fred (Gast)


Lesenswert?

Hi Dirk,

der Sourcecode für den Master befindet sich im ersten Post ganz oben, 
der Code des Slave in dem darunter.....

von Dirk H. (arm-dran)


Lesenswert?

Sorry,

hatte Tomaten auf den Augen.

Gruß
Dirk

von Jörg X. (Gast)


Lesenswert?

du hast den SPI-Interrupt aktiviert UND ein ISR, d.h. wenn das SPI 
fertig ist wird die ISR aufgerufen und damit automatisch das SPIF 
gelöscht!,
 klar, dass sich der µC aufhängt.
(am besten den interrupt nicht aktivieren, wenn du den sowieso nicht 
brauchst, das Flag wird doch trotzdem gesetzt)
wird der slave wirklich mit high-pegel am SlaveSelect pin angesprochen?
1
    PORTB &= ~_BV(PB0);  <- das sollte so funktionieren
ach ja um dich vor überraschungen zu schützen den slaveselect pin des 
Master auf output oder pullup aktivieren

von Fred (Gast)


Lesenswert?

Kein Problem, passiert....;-)

Hast du ne Ahnung woran das liegen kann? Hab alle versucht, nur 
irgendwie haut das nicht hin.

von Fred (Gast)


Lesenswert?

Hi Jörg,


>am besten den interrupt nicht aktivieren, wenn du den sowieso nicht
>brauchst, das Flag wird doch trotzdem gesetzt

Welchen? Den SPI? Aber der wird doch gar nicht aktiviert. Die Routine 
ist zwar drin, aber der Interrupt wird nirgens aktiviert. Sehe ich 
zumindest nicht ;-)

Brauchen tu ich doch eigentlich nur den Timer-Interupt.....

von Jörg X. (Gast)


Lesenswert?

Ok, hast recht, aber im Simulator läuft das Programm!
- bis der Timer1 überläuft dauert es eben ziemlich lang
- die SPI übertragung dauert auch min. 8*16Takte
- laufen die µCs wirklich mit 8MHz? (Fuses bzw. CLKPR-Register korrekt?)
(standard sind 1MHz, da dauert alles 8x so lang)
- btw. die SIGNAL-Geschichten sind veraltet!
und sorry nochmals

von holger (Gast)


Lesenswert?

>>Brauchen tu ich doch eigentlich nur den Timer-Interupt.....

Genau und da steht ein "return" drin. Sollte das nicht ein "reti" sein ?

Oder Abfrage umstellen um das "return/reti" ganz zu vermeiden.

  if (count == 1) {
    master_transmit ('1');
    count--;
  }
  else if (count == 0) {
    master_transmit ('0');
    count++;
  }


Holger

von Jörg X. (Gast)


Lesenswert?

@Holger:
>> Sollte das nicht ein "reti" sein ?
gibts nicht in C, wenn der Compiler die ISR als solche erkennt, wird da 
schon korrekt "reti" benutzt, also: "return" ist schon richtig, man darf 
natürlich keine Werte zurückgeben (irgendwie logisch, wohin auch?)

von Fred (Gast)


Lesenswert?

Also langsam verzweifel ich wirklich.

Hab jetzt alles noch mal überprüft, aber keinen Fehler gefunden. Takt 
von 8MHz ist auf beiden Controllern eingestellt. Es scheint so, als 
bleibt der Controller beim Master an der Stelle

while (!(SPSR & (1<<SPIF))); //Wait for Transmission Complete

hängen. Ich weiß nur nicht warum. Keiner ne Idee?

von holger (Gast)


Lesenswert?

Wenn du das Programm für einen ATMega 8 übersetzt hast und in den 48
brennst, dann könnte das dein Problem sein. Die Registeradressen sind
beim 48 anders. Da müsste dann aber weit mehr schief laufen. Mehr fällt 
mir dazu nicht mehr ein.

Ich probier das Master Proggi heute Abend mal auf einem 88 oder 168
aus.

von Fred (Gast)


Lesenswert?

Die einzige Registeradresse die anders war, war die des TIMSK-Registers. 
Das habe ich von TIMSK(Atmega8) in TIMSK1(Atmega48) umbenannt. Ansonsten 
waren die Registeradressen soweit gleich.....

Oder ich hab was übersehen....

von Jörg X. (Gast)


Lesenswert?

Woher weißt du, dass der Proz. da hängen bleibt?
 im Simulator funktioniert das Programm bei mir! (siehe posting oben v. 
13:11h).

von holger (Gast)


Lesenswert?

Ich hab's ;)

Das Programm lief tatsächlich nicht.
PB0 ist ja auch nicht SS beim ATMega48. Das ist PB2 !
Ich krieg jetzt schöne regelmäßige Clock Impulse auf SCK.

Holger

von Fred (Gast)


Lesenswert?

Supi Holger,

jetzt klappt es bei mir auch. Obwohl ich nicht ganz verstehe warum.

SS ist beim Atmega8 auch nicht PB0 sondern auch PB2. dOb ich jetzt nen 
High- und Lowpegel mit PB0 oder PB2 erzeuge müsste doch eigentlich 
keinen Unterschied machen. Oder?

von holger (Gast)


Lesenswert?

Du kannst PB0 für deine Zwecke nehmen. Der Trick ist allerdings
das PB2 unbedingt ein Ausgang sein muss beim SPI Master.
Ob du ihn benutzt oder nicht. Alte Macke beim ATMega SPI Modul.

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von holger (Gast)


Lesenswert?

>>wieso Macke? Auf Seite 126 ist beschrieben das der SS Pin im Mastermode
>>auf High gehalten werden muß damit der SPI im Master läuft (Seite 126
>>atmega8.pdf)

muss er nicht ;)

Er muss nur als Eingang beim Mastermode auf High gehalten werden. Als
Ausgang ist der Pegel egal. Ich nehm SS immer gleich als CS Pin für
irgendein SPI Gerät. Als Eingang ist der ja schon fast nicht mehr
zu gebrauchen. Jeder Low Pegel resettet den Mastermode und
macht ihn zum Slave.

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.