Forum: Mikrocontroller und Digitale Elektronik SPI Problem (endlosschleife)


von Frank (Gast)


Lesenswert?

Hi,

ich habe ein Problem mit einer eigentlich funktionierenden SPI 
routine...
1
void master_transmit (unsigned char data) {
2
  PORTB &= ~_BV(PB0);                //SS am Slave Low --> Beginn der Übertragung
3
  _delay_us(1);
4
  SPDR = data;                //Schreiben der Daten
5
  while (!(SPSR & (1<<SPIF)));
6
  //_delay_ms(1);
7
  counter++;
8
  if(counter==2){ _delay_us(1); PORTB |= (1<<PB0); counter=0;}  //SS High --> Ende der Übertragung


Eigentlich läuft die Routine fehlerfrei, zu anfang meines Programms 
schicke ich mit ihr einige Daten raus die auch richtig ankommen...

Rufe ich die Routine aber etwas später nochmal auf, hängt sie sich bei 
der while schleife auf...

Hardwareseitig nutze ich nur die halbe Spi schnittstelle, soll heißen 
ich benutze nur den mosi der slave schickt also nichts zurück.

Ich könnte das komplette Programm posten allerdings ist das recht 
lang.....

deshalb erstmal so


gruß

von Stefan E. (sternst)


Lesenswert?

Frank schrieb:
> Rufe ich die Routine aber etwas später nochmal auf, hängt sie sich bei
> der while schleife auf...

Dann würde ich mal vermuten, dass du in der Zwischenzeit (vielleicht 
versehentlich) das SPI-Interface deaktiviert hast.

von irf (Gast)


Lesenswert?

lese ich falsch oder wird counter nur einmal hochgezählt? Dann wäre es 
Zufall, wenn er die "2" trifft..? Oder bis wohin geht die 
While-Schleife? (Bin nicht so fit in C)

von Frank (Gast)


Lesenswert?

>Dann würde ich mal vermuten, dass du in der Zwischenzeit (vielleicht 
>versehentlich) das SPI-Interface deaktiviert hast.

die vermutung hatte ich natürlich auch...aber fehlanzeige :(
das verückte ist ja das es manchmal geht...und dann wieder nicht :?

die while schleife wartet nur bis das Spif bit 1 ist.

dann kommt die if abfrage mit dem counter. das passt so.

das ganze dient dazu, weil immer 16bit übertragen werden müssen ich aber 
nur 8 auf einen satz rauschieben kann.
ich ziehe also den pin immer für zwei durchgänge auf null

von holger (Gast)


Lesenswert?

>Rufe ich die Routine aber etwas später nochmal auf, hängt sie sich bei
>der while schleife auf...

>das verückte ist ja das es manchmal geht...und dann wieder nicht :?

Meine Vermutung: Du setzt irgendwo das DDRB Bit für den SS
Pin wieder auf Eingang. Such al nach Stellen mit DDRB = xxx;

von Falk B. (falk)


Lesenswert?


von Klaus Falser (Gast)


Lesenswert?

holger schrieb:
>>Rufe ich die Routine aber etwas später nochmal auf, hängt sie sich bei
>>der while schleife auf...
>
>>das verückte ist ja das es manchmal geht...und dann wieder nicht :?
>
> Meine Vermutung: Du setzt irgendwo das DDRB Bit für den SS
> Pin wieder auf Eingang. Such al nach Stellen mit DDRB = xxx;
>

Zur Erklärung :
Der SS-Pin muss als Ausgang verwendet werden.
Falls man den SS-Pin als Eingang verwendet, dann stört dies das SPI 
Interface.

Auf so etwas habe ich auch einmal nicht achtgegeben, und habe den nicht 
verwendeten Pin als Eingang gesetzt, sogar ohne Pullups.
Das Ganze hat perfekt funktioniert, bis irgend eine elektrische Störung 
auf den Pin eingekoppelt wurde. Dann ist das Programm hängengeblieben

von Frank (Gast)


Lesenswert?

@falk

ich dachte zwar..o nein jetzt kommen wieder wiki links :P
aber ich vermute daran

>Wenn das SPI-Modul aktiviert wird, wird NICHT automatisch SPIF gesetzt, es 
>bleibt auf Null. Damit würde die erste Abfrage in Schiebe_alles in einer 
>Endlosschleife hängen bleiben. Deshalb muss nach der Initialisierung des 
>SPI-Moduls ein Dummy Byte gesendet werden, damit am Ende der Übertragung >SPIF 
gesetzt wird

könnte es durchaus liegen...

zur Zeit funktioniert es übrigens wieder einwandfrei .... :roll:

von Falk B. (falk)


Lesenswert?

@  Frank (Gast)

>zur Zeit funktioniert es übrigens wieder einwandfrei .... :roll:

Dann prüfe mal lieber das SS Pin!

MFG
Falk

von Frank (Gast)


Lesenswert?

1
  while (!(SPSR & (1<<SPIF)));
2
  //_delay_ms(1);

das lustige ist ja, wenn ich statt der while schleife einfach das delay 
nehme funktioniert alles einwandfrei...

von holger (Gast)


Lesenswert?

>das lustige ist ja, wenn ich statt der while schleife einfach das delay
>nehme funktioniert alles einwandfrei...

Erzähl nicht solche Geistergeschichten;)

Wenn er in der while Schleife hängen bleibt ist der
Master zum Slave geworden. Grund: SS Pin wieder auf
Eingang gesetzt und von irgendwas auf Low gezogen.
Z.B. von PORTB &= ~_BV(PB0);
Pullup abgeschaltet. SPI Modul abgeschaltet könnte auch noch sein.

Das mit dem _delay_ms(); nehm ich dir nicht ab.
Klar, das Programm bleibt so nicht stehen, aber
die SPI Übertragung dürfte tot sein.

von Frank (Gast)


Lesenswert?

keine geistergeschichte sind wohl tatsächlich geister :P

das ganze ist ein frequenz generator..

zur zeit: atmega8 -> ad5930 (DDS baustein)

die initialisierung geht einwandfrei, heißt es werden alle register des 
ad5930 sauber beschrieben... hier geht es auch noch mit der while 
schleife

will ich jetzt aber nachträglich die frequenz ändern bzw. zwischen 
dreieck und sinus wechseln (über tasten) schmiert mir das ganze ab...

über delay läuft es bis jetzt wie gesagt ohne probleme... :/ nur will 
ich das natürlich nicht so lassen

von Robert D. (robert0602)


Angehängte Dateien:

Lesenswert?

Also ich hab mich auch grad erst mit der Thematik beschäftig und ein
Programm geschrieben, dass ohne delay läuft.
Du brauchst eigentlich nur die routine rf23_trans() [Ich sende 2 Bytes] 
und spitest() [Datenrichtung und SPI-Hardware Register]zu beachten.
Die Pinbelegung ist im headerfile zu sehen.

von Frank (Gast)


Lesenswert?

kann es rein zufällig am internen oszillator liegen?

von Falk B. (falk)


Lesenswert?

Nein.

von Robert D. (robert0602)


Lesenswert?

Ich glaub das ist unabhängig von der Frequenz.
Wenn der interne Oszi mit 8 MHz eingestellt ist,
stimmt es zwar, dass dieser eine Verhältnissmäßige größere Abweichung
als ein Quarz hat, aber da das Spi-Interface auf einer niederen Frequenz 
liegt und der uC als Master agiert dürfte dieser Fehler keinen Einfluss
auf die Übertragung haben.

von Frank (Gast)


Lesenswert?

ist auch irgendwie logisch wenn man drüber nachdenkt... der slave synct 
sicher ja über den clock des masters...wie der aussieht ist ja solange 
egal bis er gegen irgendwelche min und max werte verstößt...aber so 
ungenau sollte der oszillator dann auch wieder nicht sein :P

woran es schlussendlich lag...ich hab keine ahnung /V-.-V\
jetzt läuft aber alles wie es soll

gruß & danke für eure hilfe

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.