Forum: Mikrocontroller und Digitale Elektronik SPI (Arduino Uno) verhält sich komisch


von Mgns (Gast)


Angehängte Dateien:

Lesenswert?

Moin,

ich habe ein für mich merkwürdiges Problem.
Ich möchte über die SPI meines Arduino ein einfaches Byte schicken.
Dazu nutze ich SPI.transfer().
Soweit so gut, vielleicht als Zusatzinfo:
1
 SPI.beginTransaction(SPISettings(125000, MSBFIRST, SPI_MODE1));

Wenn ich nun die Bitfolge: 0b00000110 schicke, ist das kein Problem. 
Mache ich hingegen daraus 0b00010001, dann wird im Anschluss die 
MOSI-Leitung auf High gezogen. Ich tausche lediglich die Bitfolge im 
Code aus, Das Problem tritt immer dann auf, wenn meine Bitfolge auf "1" 
endet, jemand eine Idee?
Das ganz verfälscht ja letztendlich die Funktionsweise bzw. den Modus in 
der die SPI arbeiten soll.
Ich hab zwei Screenshots angehängt, um mein Problem zu verdeutlichen...

von Gerhard O. (gerhard_)


Lesenswert?

Das ist normal. SPI schiebt die Daten mit jedem CLK Impulse hinaus in 
die Welt. Wenn nun das letzte Bit auf 1 steht, dann bleibt dieser 
Zustand bestehen bis ein anderes Byte abgeschickt wird. Da kein weiterer 
CLK Pulse bis zur nächsten Transaktion zu erwarten ist, macht das in der 
Regel auch nichts aus und ist wie gesagt ganz normal. Da die HW ein 
Shift Register ist, kann das Bit nach dem letzten CLK Pulse nicht 
willkürlich auf Null zuerueck gesetzt werden, sondern nur wenn das 
nächste Byte gesendet wird. Es besteht normalerweise kein Grund das 
Shift Register zurückzusetzen. Ohne CLK - No Action:-)

von Mgns (Gast)


Lesenswert?

Okay, danke!
Dann bin ich beruhigt! :)

von Reiner Gast (Gast)


Lesenswert?

Mgns schrieb:
> Soweit so gut, vielleicht als Zusatzinfo:
> SPI.beginTransaction(SPISettings(125000, MSBFIRST, SPI_MODE1));
> Wenn ich nun die Bitfolge: 0b00000110 schicke, ist das kein Problem.
> Mache ich hingegen daraus 0b00010001, dann wird im Anschluss die
> MOSI-Leitung auf High gezogen.

Hier hilft ein Blick ins Datenblatt vom AtMega328... Kapitel zu SPI:

Table 19-2. SPI Modes
SPI Mode Conditions Leading Edge Trailing eDge
0 CPOL=0, CPHA=0 Sample (Rising) Setup (Falling)
1 CPOL=0, CPHA=1 Setup (Rising) Sample (Falling)
2 CPOL=1, CPHA=0 Sample (Falling) Setup (Rising)
3 CPOL=1, CPHA=1 Setup (Falling) Sample (Rising)

Bei dem von Dir verwendeten Mode 1 findet das Samplen des Bit auf der 
fallenden Flanke des Clock Signals statt, während das Setzen der MOSI 
Leitung zuvor auf der steigenden Flanke des Clock Signals erfolgt (ist 
aus den Bildern von Dir auch erkennbar)... MOSI muss also den korrekten 
Bitwert "nur" zum Zeitpunkt der fallenden Flanke haben. Ausserhalb 
dieser Clock Flanke ist der Zustand egal.

von Gerhard O. (gerhard_)


Lesenswert?

Mgns schrieb:
> Okay, danke!
> Dann bin ich beruhigt! :)

Wenn Du die SPI Daten mittels Bit-Banging machst, dann hast Du komplette 
Kontrolle über den SPI-Pin. Nachteil ist, es blockiert den CPU und ist 
in der Regel langsamer. Deshalb ist es meistens besser SPI in Hardware 
zu machen.

Bei HW SPI braucht man nur das nächste Byte in das SPI Sende Register zu 
laden und den Rest erledigt die HW selber und kann im Hintergrund mit 
Interrupts gemacht werden. Ob die Arduino LIb das macht weiß ich nicht 
weil ich SPI immer selber mache.

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Gerhard O. schrieb:
> Ob die Arduino LIb das macht weiß ich nicht
Ja, macht sie...
Die umhüllende Methode ist dennoch blockierend.
Leider.

Das gleiche gilt für I2C/Wire im Master Modus.
Der Slave Code läuft allerdings vollständig im ISR Betrieb

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.