Forum: Mikrocontroller und Digitale Elektronik SPI hängt im while (!(SPSR & (1<<SPIF)))


von Schorsch (Gast)


Lesenswert?

Hi,

wiedermal ein SPI Problem:

muß über SPI 16bit übertragen. Klappt auch alles, hab der Logic Analyser 
nachgesehen. Wenn ich den Befehl eine Sekunde später nochmal 
rausschicke, bleibt er im while (!(SPSR & (1<<SPIF))) {} hängen. Ich 
sehe, dass nicht geclockt wird. Was mache ich falsch?

Hier meine Init-Routine:
1
SPI_init(void) {
2
  DDRB = _BV(PB1) | _BV(PB2) | _BV(PB4) | _BV(PB5) | _BV(PB6) | _BV(PB7);
3
  DDRB &= ~_BV(PB3);
4
  PORTB = _BV(PB4) | _BV(PB5) | _BV(PB6) | _BV(PB7);
5
  SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0) | _BV(SPR1);
6
  spi_status = SPSR;  
7
}

hier der Teil meine Senderoutine, der SPI anspricht
1
    PORTB &= ~_BV(PB4);
2
    SPI_send(highByte);
3
    SPI_send(lowByte);
4
    PORTB |= _BV(PB4);
was highByte und lowByte ist, ist erstmal egal, wie gesagt es wird gar 
nicht geclocked...



und hier der SPI_send command
1
void SPI_send (unsigned char data) {
2
  uart_puts("sending SPI\n\r");
3
  SPDR = data;              
4
  uart_puts("before while...\n\r");
5
  while (!(SPSR & (1<<SPIF))) {}
6
  uart_puts("ready!\n\r"); ///< Wird nicht mehr angezeigt
7
}

Ah ja, ich benutze eine atmega64

Gruß und Danke für alle tips

Schorsch

von Stefan E. (sternst)


Lesenswert?

Schorsch schrieb:
> Was mache ich falsch?

SS ist nicht auf Ausgang geschaltet.

von Schorsch (Gast)


Lesenswert?

Stefan Ernst schrieb:
> SS ist nicht auf Ausgang geschaltet.

Hallo,

wie gesagt, einmals gehts, das zweite mal nicht....

und er würde auch SCK senden, wenn CS nicht Ausgang wäre.

Dennoch Danke

Schorsch

von Karl H. (kbuchegg)


Lesenswert?

Schorsch schrieb:
> Stefan Ernst schrieb:
>> SS ist nicht auf Ausgang geschaltet.
>
> Hallo,
>
> wie gesagt, einmals gehts, das zweite mal nicht....


Schalte den SS-Pin (PB0) einfach mal auf Ausgang. OK?

> und er würde auch SCK senden, wenn CS nicht Ausgang wäre.
>

Und wo soll das passieren (auf Ausgang schalten)?
Hier
SPI_init(void) {
  DDRB = _BV(PB1) | _BV(PB2) | _BV(PB4) | _BV(PB5) | _BV(PB6) | 
_BV(PB7);
jedenfalls nicht.
Du fummelst zwar an jeder Menge Pins rum, die nichts mit SPI zu tun 
haben, aber am entscheidenden SS Pin (PB0) tust du nichts.

von Stefan E. (sternst)


Lesenswert?

Schorsch schrieb:
> und er würde auch SCK senden, wenn CS nicht Ausgang wäre.

Ich meine nicht den Pin, den du als CS benutzt, sondern den SS-Pin des 
SPI-Moduls des Controllers (PB0).

von Schorsch (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Schalte den SS-Pin (PB0) einfach mal auf Ausgang. OK?

Hallo,


erstaunlich.....

...in der Tat ich hatte im Datenblatt nur diesen Satz gelesen

> When the SPI is configured as a Master (MSTR in SPCR is set), the user
> can determine the direction of the SS pin

damit war die Sache für mich gegessen und SS spielte keine Rolle mehr, 
wenn ich aber drei Zeilen weiter gelsen hätte

> If SS is configured as an input, it must be held high to ensure Master
> SPI operation.

wäre das nicht passiert

schäme mich :(



Ihr seid super,
Vielen Dank


Schorsch

von Purzel H. (hacky)


Lesenswert?

So ganz nebenbei, pollen in dieser Form, blockierend, ist beliebig 
schlechter Stil

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Wenn das SPI sehr schnell ist, geht das gar nicht anders, da die 
Interruptbearbeitungszeit u.U. länger als eine Bytelaufzeit ist. Es 
kommt auf den Verwendungszweck an ;-)

von Schorsch (Gast)


Lesenswert?

Siebzehn und Fuenfzehn schrieb:
> So ganz nebenbei, pollen in dieser Form, blockierend, ist beliebig
> schlechter Stil

Hallo,

für konstruktive Kritik bin ich jederzeit offen.

Wie würdest Du es vorschlagen?

Schorsch

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.