Forum: Mikrocontroller und Digitale Elektronik SPI haut nicht hin... :(


von Andreas H (Gast)


Lesenswert?

Hallöchen!

Ich muß nochmal wegen meiner SPI-geschichte nerven. Irgendwie klappt das 
ganze nicht. Jetzt bastel ich heute schon den dritten Tag da dran rum 
und ich kriegs ums verrecken nicht hin. :-(

Disen Code hab ich mal eben verzapft:

Init:
    ; **** Stack Pointer Setup Code ****
    ldi temp,$02    ; Stack Pointer Setup
    out SPH,temp    ; Stack Pointer High Byte
    ldi temp,$5F    ; Stack Pointer Setup
    out SPL,temp    ; Stack Pointer Low Byte

    ; **** Register Setup (statische Werte) ****
    ldi zero, $0
    ldi allon, $FF

        ; **** Port B Setup Code ****
    ldi temp,0b10111111  ;
    out DDRB,temp    ; Ausgabe in "Data Direction Register B"
    ldi temp,0b11111111  ;
    out PORTB,temp    ; Ausgabe an PortB

        ; **** Port D Setup Code ****
    ldi temp,0b11111111  ;
    out DDRD,temp    ; Ausgabe in "Data Direction Register D"
    ldi r17,0b00000000  ;
    out PORTD,r17    ; Ausgabe an PortD

    rcall delay      ; Pause

;******************************   MAIN PROGRAM 
************************************


main:
    ldi temp, 0b11011001  ; SPI enable, Master, f/16, no Interr.
    out SPCR, temp      ; -> SPI Control Register
    ldi temp, 0b10100110  ; Wert zum Übertragen
    out SPDR, temp      ; -> senden...

waitsend:
    in temp, SPSR      ; lese SPI Status Register

    eor r17, allon      ;
    out PortD, r17

    sbrs temp, 7      ; wenn Bit 7 gesetzt = Übertragung Ende
    rjmp waitsend      ; ... wenn nicht Ende, noch warten

    rcall delay        ; Pause

ende:
    rjmp main        ;Endlosschleife....

Wenn ich nun mit meinem OscilloscopeInit:
    ; **** Stack Pointer Setup Code ****
    ldi temp,$02    ; Stack Pointer Setup
    out SPH,temp    ; Stack Pointer High Byte
    ldi temp,$5F    ; Stack Pointer Setup
    out SPL,temp    ; Stack Pointer Low Byte

    ; **** Register Setup (statische Werte) ****
    ldi zero, $0
    ldi allon, $FF

        ; **** Port B Setup Code ****
    ldi temp,0b10111111  ;
    out DDRB,temp    ; Ausgabe in "Data Direction Register B"
    ldi temp,0b11111111  ;
    out PORTB,temp    ; Ausgabe an PortB

        ; **** Port D Setup Code ****
    ldi temp,0b11111111  ;
    out DDRD,temp    ; Ausgabe in "Data Direction Register B"
    ldi r17,0b00000000  ;
    out PORTD,r17    ; Ausgabe an PortB

    rcall delay      ; Pause

;******************************   MAIN PROGRAM 
************************************


main:
    ldi temp, 0b11011001  ; SPI enable, Master, f/16, no Interr.
    out SPCR, temp      ; -> SPI Control Register
    ldi temp, 0b10100110  ; Wert zum Übertragen
    out SPDR, temp      ; -> senden...

waitsend:
    in temp, SPSR      ; lese SPI Status Register

    eor r17, allon      ;
    out PortD, r17

    sbrs temp, 7      ; wenn Bit 7 gesetzt = Übertragung Ende
    rjmp waitsend      ; ... wenn nicht Ende, noch warten

    rcall delay        ; Pause

ende:
    rjmp main        ;Endlosschleife....


Eigentlich sollte dieses Programm in einer Endlosschleife immer wieder 
ein "Test-Byte" über die SPI-Schnittstelle senden. Wenn ich mit meinem 
Oszilloskop allerdings an den Pins PB5 /6 /7 (also den 3 SPI-Pins) 
messe, hab ich dort keinerlei Signale. Nur eine gleichbliebende Spannung 
nahe der Betriebsspannung (5V).

Im Debugger (AVR-Studio 4.04) allerdings klappt es. Als Testboard 
benutze ich das STK500.

Das einzige, was ich feststellen kann, ist, daß die SPI-Schnittstelle 
scheinbar irgendwas tut. Jedenfalls wird die Schleife, wo auf das 
"Übertragungs-Ende-Bit (SPIF)" im SPSR-Register gewartet wird, nach 
etwas über 1 Sekunde beendet. Denn während der Pausenroutine (nicht mit 
im Listing) schalte ich zur Kontrolle die LEDS (am PortD) ein/aus, und 
zur Laufzeit blinken diese.

Also wird eine Sekunde lang auf das Übertragungsende gewartet (ziemlich 
lange, oder?), dann wird dieses mit dem SPIF-Bit angezeigt und eine 
Pause von 1 Sekunde eingelegt, bevor erneut das Byte gesendet wird ( / 
werden sollte).

Warum zum Teufel kann ich an den Ausgangspins des uC die SPI-Signale 
nicht messen??? Hat einer ne Idee?

ciao,
   Andi

von Andreas H (Gast)


Lesenswert?

uups - Code ist doppelt eingefügt, sorry. Endet da, wo "ende:" steht... 
;) ich hoffe, man kann es einigermassen entziffern. Danke schonmal für 
Eure Mühen!

von Frankl (Gast)


Lesenswert?

Vorsicht mit dem Studio 4.*** ist noch im Beta. Siehe auch 
www.avrfreaks.net forum studio 4

Ist der eine Master und der andere Slave ?. Liegt am Slave µ das SS auf 
low ?

von Andreas H (Gast)


Lesenswert?

Hallo!

Bisher habe ich mit dem Studio 4 noch keine Probleme gehabt, ich finds 
soweit ganz nett. :) Das es wohl noch ne Beta ist, weiß ich, aber daran 
kann mein Problem nicht liegen.

Beim Slave bin ich noch gar nicht, das o.g. Problem lag ja auf 
Master-Seite. Ich konnte einfach keine Signale an den Pins messen. 
Nachdem ich jetzt aber erstmal laut geschrien habe und ne kurze Pause 
gemacht hab, ist mir die Eingebung gekommen: Es lag nur indirekt am 
Programm. Ich habe die laaaange (1Sekunde)-Pause raus genommen und habe 
gemerkt, daß gar nicht die SPI-Schnittstelle so lange braucht, bis sie 
fertig mit senden ist, sondern meine Kontroll-LEDs nur den Eindruck 
vermittelten, da sie einmal nach der 1sek-Pause an und nach dem nächsten 
Durchlauf aus waren. Ich hab die Pause entfernt, so das endlos gesendet 
wird, und kann jetzt auch meine Signale an den SPI-Pins messen. Vorher 
waren sie halt nur so kurz, daß sie nicht wahrnehmbar waren.

Soweit ist also der von mir gepostete Code wirklich i.O., der Master 
sendet. Jetzt muß ich es nur noch schaffen, den Slave so zu 
programmieren, daß er auch empfängt. Puhhhh.... Folgendes Problem tut 
sich da jetzt auf:

--->
Das Problem ist doch, daß ich gar nicht weiß, wann der Master sendet, 
denn er wird im Betrieb später nicht pausenlos senden. Wie also reagiere 
ich auf der Slave-Seite auf die eintrudelnden Daten?
<---

Gibts schon irgendwo nen Beispielcode in Assembler, woraus ich erkennen 
kann, wie man einen AVR geschickt als Slave betreibt?

ciao,
   Andi

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.