Forum: Compiler & IDEs AVR SPI hängt (SPIF Abfrage), ss IST Ausgang!


von Martin N. (martin02)


Lesenswert?

Hallo zusammen!

Ich verzweifle am SPI Bus. Ein ATmega16 steuert drei 74hc595 an.

Hier mal die wichtigsten Zeilen:

    DDRB = (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB4)|(1<<PB5)|(1<<PB7);
    // SPI Port Initialisieren
    SPCR  =  (1<<SPE) | (1<<SPR0) | (1<<SPR1) | (1<<MSTR);

    // Segmente an Schieberegister übertragen
    STROBE_L;
    SPDR = ~transmit_e;
    _delay_ms(1);
    SPDR = ~transmit_z;
    _delay_ms(1);
    SPDR = ~transmit_h;
    _delay_ms(1);
    STROBE_H;

So funktioniert es. Aber das ist ja nicht schön. Wenn ich die delays 
durch while(!(SPSR & (1<<SPIF))); ersetze, hängt der sich da fest. Ich 
habe nachgelesen. Der SS Pin ist bei mir als Ausgang konfiguriert. Was 
kann es noch sein? Ich nutze bis jetzt keine Interrupts in dem Programm.

Gruß
Martin

von Michael (Gast)


Lesenswert?

Klappt das senden von nur einem Byte oder hängt er da auch schon?

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


Lesenswert?

Martin N/a schrieb:
> Wenn ich die delays
> durch while(!(SPSR & (1<<SPIF))); ersetze, hängt der sich da fest.

Du hast das Bit aber vorher korrekt gelöscht, ja?

von Martin N. (martin02)


Lesenswert?

Hi,

ich wollte genau das gerade testen. Habe genau den Code von gestern, der 
NICHT lief, genommen. Und siehe da - es geht heute.

Keine Ahnung warum... aber immerhin geht's. Danke für den hilfreichen 
Tipp :o)

Gruß
Martin

von Mark B. (markbrandis)


Lesenswert?

Da hat wohl ein Bit zu kräftig gefeiert und ist über Nacht umgekippt.

von Hans-jürgen H. (hjherbert) Benutzerseite


Lesenswert?

>> Und siehe da - es geht heute.

Die Unzuverlässigkeit bei SPI-Komminukation hatte bei mir die Ursache, 
dass ich SS nicht vor jedem Byte kurz pulste.

Also so:

Der Master muss :
- Erst keinen der Slaves angewählt haben: Ausgang SS=inaktiv (high).
- Einen der Slaves anwählen SS=aktiv (low). (Durch dieses Umschalten 
wird der Eingang des Slaves synchronisiert, der Bit-Zähler auf 0 
gesetzt)
- Ein Byte an den Slave senden
- Warten bis gesendet ist (Durch Abfragen, oder durch Warten auf 
Interrupt)
- Die zurückgemeldete Antwort auswerten.
- Den Slave abwählen SS=inaktiv (high).

von Michael U. (amiga)


Lesenswert?

Hallo,

Hans-jürgen Herbert schrieb:
>>> Und siehe da - es geht heute.
>
> Die Unzuverlässigkeit bei SPI-Komminukation hatte bei mir die Ursache,
> dass ich SS nicht vor jedem Byte kurz pulste.
>
> Also so:
>
> Der Master muss :
> - Erst keinen der Slaves angewählt haben: Ausgang SS=inaktiv (high).
> - Einen der Slaves anwählen SS=aktiv (low). (Durch dieses Umschalten
> wird der Eingang des Slaves synchronisiert, der Bit-Zähler auf 0
> gesetzt)
> - Ein Byte an den Slave senden
> - Warten bis gesendet ist (Durch Abfragen, oder durch Warten auf
> Interrupt)
> - Die zurückgemeldete Antwort auswerten.
> - Den Slave abwählen SS=inaktiv (high).

Schlicht Quark... ;-)

Wenn der SPI als Master gesetzt ist und SS als Ausgang, dann ist SS ein 
normaler Portpin asl Ausgang, für den sich SPI nicht mehr interessiert.
Nur wenn es Eingang ist, wird es vom SPI beachtet.

Ich suche die Stelle im Datenblatt jetzt aber nicht.

Gruß aus Berlin
Michael

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.