www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI Problem (endlosschleife)


Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe ein Problem mit einer eigentlich funktionierenden SPI 
routine...
void master_transmit (unsigned char data) {
  PORTB &= ~_BV(PB0);                //SS am Slave Low --> Beginn der Übertragung
  _delay_us(1);
  SPDR = data;                //Schreiben der Daten
  while (!(SPSR & (1<<SPIF)));
  //_delay_ms(1);
  counter++;
  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ß

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: irf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Klaus Falser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Frank (Gast)

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

Dann prüfe mal lieber das SS Pin!

MFG
Falk

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  while (!(SPSR & (1<<SPIF)));
  //_delay_ms(1);

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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Robert De meyer (robert0602)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann es rein zufällig am internen oszillator liegen?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein.

Autor: Robert De meyer (robert0602)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.