ASM für SPI .. ist das richtig so?
Hallo
Mein CAN Controller (Slave) will einfach nicht funktionieren.
Vielleicht ist das SPI falsch konfiguriert. Wäre echt schön wenn jemand
helfen könnte. Das ganze ist auf nem Steckbrett aufgebaut. Hier der Code der im Mega8515 (Master) abgelegt ist:
; -------------------------- KONFIGURIEREN -------------------
ldi temp, 0b10100000 ; Output = SCK & MOSI
out DDRB, temp
ldi temp, 0b01010001 ; SPIEnabled, MasterMode, SPI Clock Rate=
; OSC/16 = 250kHz @ 4MHz OSC
out SPCR, temp
; ---------------------- per SPI was senden ------------------
cbi PortB, 4 ; /CS pull down
ldi temp, 0b00000010 ; WRITE-Instruction
rcall spiout
sbi PortB, 4 ; release /CS
; -------------------- SUBFUNKTION FÜR SENDEN ------------
spiout:
out SPDR, temp
wait_spi:
sbis SPSR,SPIF ; Transmission complete?
rjmp wait_spi
ret ; back...
Ich bin schon am verzweifeln, ich weis echt nicht wo ich den Fehler
suchen soll. Mein restliches Programm bin ich schon hundertmal
durchgegangen. Leider programmieren das alle bis auch mich in C.
Deshalb krieg ich auch von nirgendwo Hilfe. Ist doch zum heulen.
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo!
Ich habe die abgespeckte aktuelle Version im Anhang. Am PC kann ich über HTerm sehen, dass 2 Bytes ankommen: 11001100 und 00110011
Danach ist Ruhe. Wenn empfangen wird leuchtet auch kurz die Empfangs-LED (PortA, 0) synchron zur Sende-LED.
Sollte es doch ein SW Problem sein?
Habs eigentlich gut dokumentiert...
Liste der Anhänge anzeigen (Anzahl: 2)
Hi Bernhard
Bin aber auch Neuling mit SPI. Das angefügte Blatt aus dem Datasheet des mcp veranschaulicht das ganz gut.
Grundsätzlich wird der Slave immer mit auf Low-gehaltener /SS Leitung aktiviert. Danach legt man irgendein Byte in das Register SPDR:
out SPDR, temp
Sobald das Register gefüllt ist, gibt der AVR automatisch das Byte raus, mit gleichzeitiger Taktschaltung am SCK-Pin. Sobald das letzte der 8 Bit raus ist, hört auch der Takt wieder auf zu schlagen. SPDR ist nun wieder frei. Dabei wird auch das SPIF-Flag gesetzt. Wenn man es also nach dem Beschreiben von SPDR zyklisch abfragt, weis man wann SPDR wieder frei ist:
wait_spi:
sbis SPSR,SPIF ; Transmission complete?
rjmp wait_spi
Damit man wieder etwas in SPDR schreiben kann muss das Bit vorher wieder von Hand gelöscht werden. Das geht z.B. durch Auslesen des SPDR:
in temp2, SPDR ; release SPIF by reading Register
Der SPI ist ein Ringpuffer. Bei rausgehen eines Bytes kommt eins "von draussen" gleichzeitig rein. Es ist ein Kreis. Meist hat das reinkommende aber keine Bedeutung (z.B. wenn man nur was senden will).
Will man was von "draussen" holen, muss man irgendetwas senden um danach das empfangene Byte nur noch zu lesen.
Das ist das grobe Geschehen.Wenn noch Fragen, oder mehr Details. Bitte, ich bin hier!
viele Grüße
Liste der Anhänge anzeigen (Anzahl: 1)
@Magnetus
Danke für Deine sehr fleißige Zuarbeit ;)
Ich habe mich in den letzten Stunden etwas reingelesen in diese interessante Materie.
Grundsätzlich muss man ersteinmal festlegen, in welcher Bertriebsart der Master und der Slave arbeiten soll.
Ich denke, für die meisten Anwendungsfälle (1Master 1Slave) genügt es wenn man ohne Chip-Selct arbeitet.
SS-PIN beim Master und beim Slave.
MASTER:
Wird als Ausgang konfiguriert.
Wird LOW, wenn Master was senden möchte.
SLAVE:
SS ist als Eingang definiert.
Slave bleibt so lange inaktiv, bis SS low wird
Diese Betriebsart wird im
"SPI Control Register – SPCR" festgelegt.
Bei der Grund -Initialisierung des Masters und des Slaves sind / können o.g. Einstellungen vorzunehmen. s.Datenblatt:
SPI_MasterInit:
; Set MOSI and SCK output, all others input
ldi r17,(1<<DD_MOSI)|(1<<DD_SCK)
out DDR_SPI,r17
; Enable SPI, Master, set clock rate fck/16
ldi r17,(1<<SPE)|(1<<MSTR)|(1<<SPR0)
out SPCR,r17
ret
SPI_SlaveInit:
; Set MISO output, all others input
ldi r17,(1<<DD_MISO)
out DDR_SPI,r17
; Enable SPI
ldi r17,(1<<SPE)
out SPCR,r17
ret
Überprüfe mal bitte Dein Programmcode, ob die Initialisierung genauso vorgenommen wurde? Ob die gleichen Bits in dem Register SPCR gesetzt wurden sind?
Wenn ich alles jetzt richtig vertstanden habe, dann kein ein Master immer Daten senden !!!, auch wenn kein Slave vorhanden ist, d.h. werden pausenlos Daten vom Master gesendet, dann hat man immer Pegeländerungen an: SCK MOSI und SS oder?
>Grundsätzlich wird der Slave immer mit auf Low-gehaltener /SS Leitung >aktiviert.
Ja das sehe ich auch so, dass der Slave immer mit einem LOW an SS aktiviert wird.
Ich habe etwas im Internet dazu gefunden, ich stell es Dir / Euch mal zur Verfügung.
Ich werde mir als nächstes einen MASTER programmieren,
ich denke, wir bekommen SPI schon zum laufen ;)
PS:
in Deinem Programm steht:
ldi temp, 0b01010001 ; SPIEnabled, MasterMode, SPI .....
out SPCR, temp
besser wäre:
ldi temp, ,(1<<SPE)|(1<<MSTR)|(1<<SPR0); SPIEnabled.....
out SPCR, temp
Denn Durch die Schreibweise "0b01010001" muss man erst auwändig im Datenblatt nachschauen, welches Bit gesetzt ist.
und
durch "0b01010001" kann man sich schnell mal verzählen, oder vertippen, gel ? ;)
Gruß
Bernhard
Liste der Anhänge anzeigen (Anzahl: 1)
Wie meinst du denn das:
>> Eine von Avcc gegen PIN
>> und eine von GND gegen PIN
?
Ich habe normal die SPI-Leitungen angezapft mit je einem R und ner LED nach Masse.
Beim Senden an den Slave ist nun folgendes zu beobachten:
/SS leuchtet immer, halbe Leuchtkraft
MISO leuchtet nicht
MOSI leuchtet immer, sehr hell
SCK blinkt intervallmäßig kurz auf (alle 2 sek, wie programmiert)
Die 2 zu übertragenden Bytes werden ca. 3 mal übertragen, danach 2 Bytes Nullen und alles steht still...nur die Sende-LED blitzt normal weiter alle 2 Sek. Also muss das Problem Empfängerseitig liegen.
Hast du bei dir eine ähliche Schaltung, dass du das mal dort testen kannst?
Ich weis nicht woran es noch liegen könnte. Habe den ASM Code nochmal freundlicher gestaltet. Schaue ihn doch mal durch. Vor allem interssiert mich ob ich unten die Unterprogramme (Senden, Lesen,..) richtig habe. Eine C-Datei ist dabei, die funzt auf jeden Fall. Man müsste nur prüfen ob ich daraus den richtigen ASM Code generiert habe.
Liste der Anhänge anzeigen (Anzahl: 1)
>>Wie meinst du denn das:
>> Eine von Avcc gegen PIN
>> und eine von GND gegen PIN
eine LED von +5V gegen MOSI (natürlich mit einem Widerstand)
eine LED von Masse gegen MOSI (natürlich mit einem Widerstand)
Und so könnte man das für jeden AUSGANGS-PIN machen, um festzustellen, ob Impulse anliegen, ein OSZI würde auch nicht viel weiter helfen ;)
>Hast du bei dir eine ähliche Schaltung, dass du das mal dort testen >kannst?
Hab hier zwei ATmega8 vor mir auf einem Experimentierboard
>SS leuchtet immer, halbe Leuchtkraft
SS leuchtet auch bei mir, d.h. SS-PIN ist LOW
>MISO leuchtet nicht
bei mir auch nicht, denn ich habe noch kein SLAVE angeschlossen
>MOSI leuchtet immer, sehr hell
zuckt kurz auf, wenn daten gesendet werden
>SCK blinkt intervallmäßig kurz auf (alle 2 sek, wie programmiert)
zuckt kurz auf, wenn daten gesendet werden
> Man müsste nur prüfen ob ich daraus den richtigen ASM Code >generiert habe.
ich kann momentan bei Deinem Master kein Problem finden
>Habe den ASM Code nochmal freundlicher gestaltet.
Dann zeige ihn doch mal (haste vergessen mit zuzusenden) ;)
>Also muss das Problem Empfängerseitig liegen.
vielleicht, so weit bin ich noch nicht
Habe mal eine kleine MASTER-Routine geschrieben (ganz einfach)
jede Sekunde wird ein DUMMY gesendet, ich lege es mal mit bei.
Bin momentan noch am überlegen, ob beim senden das
"SPIF: SPI Interrupt Flag" beachtet werden muss, nach meiner Meinung nach nicht ?
Wie lange bist Du heute noch fleißig?
Bernhard
Liste der Anhänge anzeigen (Anzahl: 1)
>> "SPIF: SPI Interrupt Flag" beachtet werden muss, nach meiner Meinung nach nicht ?
Ganz oben im Beitrag hat jemand gesagt dass es so sein muss. DIe C-Codes von 2 Leuten weisen da saber auch auf. Ich denke es stimmt. Steht auch im Datenblatt "... SPIF is cleared by first reading SPSR with SPIF is set and then acessing SPDR..."
Liste der Anhänge anzeigen (Anzahl: 1)
>Hab jetzt pro SPI Port 8 LEDs dran:
GROSSES LOB ;) ich habe 9 angeschlossen :)
>LEDs nach Vdd: _______ LEDs nach Masse:
>/SS zuckt wenn sendet _______ leuchtet konstant
OK, bei mir auch
>MISO leuchtet konstant _______ leuchtet konstant
d.h es werden keine DATEN vom SLAVE gesendet, oder nurdas
ZEICHEN "NULL" (alle 8 Bits vom SLAVE sind 0)
>MOSI zuckt wenn sendet _______ leuchtet konstant
OK, bei mir auch
>SCK leuchtet konstant _______ zuckt wenn sendet
OK, bei mir auch
>Aber so richtig schlau werd ich nicht draus..
Das menschliche Auge ist zu träge, dass es schnelle Helligkeitsunterschiede von Hell auf Dunkel erfasst (siehe Fernseher)
(Einbrenn-Effekt bei der menschlichen Netzhaut)
Aber Helligkeitsunterschiede von dunkel auf hell das erkennt man besser.
Mein MASTER ist soweit fertig,
- er sendet pausenlos ein BYTE (welches aber nach jedem senden um eins erhöt wird)
- er liest das Empfangsbyte aus, welches vom SLAVE gesendet wurde
und zeigt es an 8 LEDs an
Habe mal, weil ich noch kein SLAVE habe, die PINS MISO und MOSI miteinander verbunden,
der MASTER hat sich also "selber" etwas zugesendet.
UNd das was der MASTER empfängt sieht ganz vernünftig aus.
(Die abwechselnd leuchtenden LEDs sehen gut aus) ;)
Ich lege mal den ASSEMBLER-CODE mit bei.
Und gehe jetzt mal zum SLAVE über, AUSBAUSTUFE 2 :)