Forum: Mikrocontroller und Digitale Elektronik AtMega16, SPI geht nach auslagern nicht mehr


von Basti H. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe seit zwei Tagen ein Problem mit der SPI am AtMega 16.
Herr Google wurde befragt, ebenso diverse Bücher und Foren. Leider wußte 
keiner Rat.

Wenn der Controller in die
1
while(!(SPSR&(1<<SPIF)));
 springt hängt er sich auf.
Dieses Problem besteht aber erst seit dem der Code auf mehrere Files 
aufgeteilt wurde. Stehen die Funktionen in der main.c funktioniert die 
SPI Übertragung einwandfrei.
Andere Funktionen die auf die selbe Art und Weise ausgelagert wurden 
funktionieren bestens.
Das Kompilieren und Übertragen werden ohne Fehler erledigt.
Die angehängten Dateien sind eigentlich wesentlich länger und wurden nur 
zur Fehlersuche immer weiter verkürzt.

Ich schau da seit zwei Tagen rein wie die Katze in den Kalender und 
finde meinen Fehler nicht.
Vielleicht kann von euch jemand helfen, ich bin für jeden Tipp dankbar.

Gruß Basti

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Basti H. schrieb:
> Wenn der Controller in die while(!(SPSR&(1<<SPIF))); springt hängt er sich auf.

Ist ein typisches Anzeichen für nicht initialisierten Takt,
bspw. weil SPE|MSTR nicht gesetzt sind, oder aber weil das /SS-Pin
kein Ausgang ist und der Eingang floatet.

von Basti H. (Gast)


Lesenswert?

Danke für die schnelle Antwort.
Das SPE und MSTR sollte eigentlich in der
1
Init_SPI_Master()
 gesetzt werden.
1
void Init_SPI_Master(void)
2
{
3
  DDRB = (1<<SPI_MOSI);    //MOSI als Ausgang
4
  DDRB = (1<<SPI_CLK);    //CLK als Ausgang
5
  
6
        DDRB = (1<<PB4);
7
  PORTB = (1<<PB4);
8
  
9
  SPCR = (1<<MSTR)|      //Master Mode
10
      (1<<SPE)|    //SPI Enable
11
      (!(1<<SPR1))|    //1MHz Takt
12
      (1<<SPR0)|    //1MHz Takt
13
      (!(1<<DORD))|    //MSB first
14
      (1<<CPHA)|
15
      (1<<CPOL);    
16
}

Den /SS hatte ich versehentlich mit rausgelöscht und ist jetzt wieder 
drin.
Leider geht das ganze immer noch nicht, er bleibt in der While hängen.

Gruß Basti

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Wenn du ein Bit löschen willst macht man das übrigens nicht so: 
(!(1<<SPR1))
Da das Register beim starten des AVR eh 0 ist, kannste das auch 
weglassen.

Halt doch maln Oszi an SCK und gucke ob was rauskommt.

Schreib die Warteschleife mal so:
1
while(!(SPSR & (1<<SPIF)))
2
  ;

von Stefan E. (sternst)


Lesenswert?

Weder MOSI noch CLK sind zur Zeit auf Ausgang geschaltet. Mach dich mal 
mit |= vertraut.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Das hatte ich grad vergessen zu tippen.
1
  DDRB = (1<<SPI_MOSI);    //MOSI als Ausgang
2
  DDRB = (1<<SPI_CLK);    //CLK als Ausgang
3
  DDRB = (1<<PB4);
Hier werden die ersten 2 Richtungen wieder überschrieben, am Ende ist 
nur PB4 ein Ausgang.
Das muss verodert werden!

von Basti H. (Gast)


Lesenswert?

Oh Mann, eigentlich logisch. Ich habs verballert. Jetzt gehts.
Peinlich, peinlich...

Gruß

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.