Hallo an alle Elektronikfreunde,
ich versuche derzeit den CAN-Bus meines Autos auszulesen und habe mit zu
dem Zweck ein fertiges Can-Shield für mein Arduino geholt. Da ich kein
Fan von den ganzen fertigen Libraries und Arduino Befehlen bin, versuche
ich grade mich durch das SPI-Protokoll zu arbeiten und den MCP2515
selber zu konfigurieren. Vielleicht könnt ihr mir bei zwei Dingen
helfen.
1. Ich verstehe die Funktion der Bits CPOL und CPHA aber nicht wie bei
CPHA=0 zuerst ein bit empfangen werden kann wenn MOSI bzw. MISO nicht
gesetzt sind. Ich habe zwar gelesen, dass der Slave seinen Ausgang MISO
bereits bei SS=0 setzt aber der Master scheint MOSI zu diesem Zeitpunkt
nicht zu setzen. Nach meinem Verständnis wird doch dann ein Takt mehr
benötigt um alle bits zu übertragen, oder sehe ich das falsch?
2. Um den MCP2515 zu initialisieren bzw. Interuppts beispielweise zu
aktivieren muss ich den Controller in den Configurationmodus versetzen.
Dazu kann ich gemäß Datenblatt das Reset-Byte 11000000 senden. Was
passiert wenn ich zufällig genau diese Byte später übertragen möchte?
Gehe ich dann jedes mal in den Konfiguartionsmodus oder geht das nur
einmal nach dem Einschalten?
Ich bin in den unendlichen Weiten des Internet nicht fündig geworden.
Danke schonmal für eure Hilfe
Schöne Grüße
Patrick
Patrick S. schrieb:> 2. Um den MCP2515 zu initialisieren bzw. Interuppts beispielweise zu> aktivieren muss ich den Controller in den Configurationmodus versetzen.> Dazu kann ich gemäß Datenblatt das Reset-Byte 11000000 senden. Was> passiert wenn ich zufällig genau diese Byte später übertragen möchte?> Gehe ich dann jedes mal in den Konfiguartionsmodus oder geht das nur> einmal nach dem Einschalten?
Das angedachte Problem kann nicht passieren, da du um eine Übertragung
zum MCP einzuleiten, erst mal die /CS Leitung auf Low ziehen musst.
Danach wertet der MCP das erste Byte, das du ihm übergibst als Kommando.
Und nachdem du ein Kommando inklusive der dazu nowendigen Daten dann
Byteweise an den MCP übertragen hast, geht die /CS Leitung wieder zurück
auf High. Wodurch sicher gestellt ist, dass die nächste Übertragung
wieder mit einem Kommando-Byte beginnt. Zu einer Verwechslung der zu
übertragenden Daten kann es daher nicht kommen.
> Ich bin in den unendlichen Weiten des Internet nicht fündig geworden.http://ww1.microchip.com/downloads/en/DeviceDoc/21801d.pdf
Seite 63 und folgende
Patrick S. schrieb:> 1. Ich verstehe die Funktion der Bits CPOL und CPHA aber nicht wie bei> CPHA=0 zuerst ein bit empfangen werden kann wenn MOSI bzw. MISO nicht> gesetzt sind. Ich habe zwar gelesen, dass der Slave seinen Ausgang MISO> bereits bei SS=0 setzt aber der Master scheint MOSI zu diesem Zeitpunkt> nicht zu setzen. Nach meinem Verständnis wird doch dann ein Takt mehr> benötigt um alle bits zu übertragen, oder sehe ich das falsch?
Die Sache ist viel einfacher als du denkst.
Zunächst mal erzeugt ja der Master einen Takt. So ein Takt besteht ja
aus Pulsen
(Ich ignorier jetzt mal die Rolle von CPOL und gehe davon aus, dass CPOL
so eingestellt ist, dass der Ruhepegel der Taktleitung 0 ist)
1
Taktleitung:
2
+----+
3
| |
4
---------+ +----------
5
6
-----> Zeit
jeder Puls hat daher 2 Flanken. Eine steigende und eine fallende.
Mit CPAH stellst du jetzt beim Empfänger ein, welche der beiden Flanken
zur Datenübernahme benutzt werden soll.
Legt der Sender die Polarität der Datenleitung bereits zu diesem
Zeitpunkt korrekt fest
1
Taktleitung:
2
+----+
3
| |
4
---------+ +----------
5
6
^
7
|
8
zu diesem Zeitpunkt hat der Sender die Datenleitung
9
bereits auf den Pegel gebracht, den er übergeben will
dann kann man logischerweise die steigende Flanke des Pulses dazu
benutzen, an der Datenleitung nachzusehen, ob der Sender eine 0 oder
eine 1 übergeben will.
Legt der Sender aber die Datenleitung erst hier
1
Taktleitung:
2
+----+
3
| |
4
---------+ +----------
5
6
^
7
|
8
zu diesem Zeitpunkt hat der Sender die Datenleitung
9
auf den Pegel gebracht, den er übergeben will
fest, indem er zuerst die steigende Flanke an der Taktleitung erzeugt
und erst dann die Dateleitung bedient, dann wird das mit der steigenden
Flanke wohl nichts werden, sondern man sieht dann eben erst bei der
fallenden Flanke an der Datenleitung nach, ob das eine 0 oder eine 1
sein soll.
D.h. mittels CPAH sagt man implizit dem Empfänger, welches Muster der
Sender benutzt: bedient er zuerst die Taktleitung und dann erst die
Datenleitung oder umgekehrt.
Das ganze ist einfach nur die Festlegung der Reihenfolge in der die
beiden Leitungen bedient werden.
(Bzw. wenn man das beim Sender einstellt, dann teilt man eben dem mit,
wie er das machen soll.)
Vielen Dank für deine ausführliche Antwort.
Deine Antwort zu Punkt zwei leuchtet mir ein. Ich stand wohl etwas auf
dem Schlauch und hatte nicht daran gedacht dass ich das write Kommando
jedes mal schreiben muss.
Zu 1.:
CPHA legt doch so wie ich das verstehe fest ob die Sender (Master und
Slave) die Datenleitungen bei der ersten oder zweiten Flanke auf den
jeweiligen Pegel bringen. Ob dies eine steigende oder fallende Flanke
ist richtet sich also nach der Polarität (CPOL=1 v CPOL=0).
Taktleitung:
CPHA=1/CPOL
+----+
| |
---------+ +----------
^ ^
| |
| Datenübernahme
Bit senden
Taktleitung:
CPHA=0/CPOL
+----+
| |
---------+ +----------
^ ^
| |
| Bit senden
Datenübernahme
Mit dem letzten Fall habe ich unabhängig von der Polarität ein Problem
weil der Master noch nichts gesendet hat.
Laut Wikipedia sendet der Slave bereits wenn der SS bzw. CS Pin auf Low
gezogen wird um dem Master Daten zum empfangen bereitzustellen,
umgekehrt gilt dies aber scheinbar nicht.
Was empfängt also der Slave in diesem Fall?
Patrick S. schrieb:> CPHA legt doch so wie ich das verstehe fest ob die Sender (Master und> Slave) die Datenleitungen bei der ersten oder zweiten Flanke auf den> jeweiligen Pegel bringen. Ob dies eine steigende oder fallende Flanke> ist richtet sich also nach der Polarität (CPOL=1 v CPOL=0).
Richtig.
Drum hab ich auch CPOL erst mal aussen vorgelassen. Ist CPOL anders rum,
denn drehen sich 'steigende' und 'fallende' Flanke logischerweise um.
Ich wollte ganz einfach die Begriffe 'erste' und 'zweite' vermeiden.
War vielleicht keine so gute Idee.
> +----+> | |> ---------+ +---------->> ^ ^> | |> | Datenübernahme> Bit senden
Nicht 'Bit senden'. Das ist ein Vorgang, dass die Dateleitung auf den
richtigen Pegel gebracht wird und dass der Puls auf der Clock Leitung
kommt. Beides zusammen sind 'Bit senden'.
> +----+> | |> ---------+ +---------->> ^ ^> | |> | Bit senden> Datenübernahme
Eben nicht.
Es geht einfach darum: zu welchem Zeitpunkt kann sich der Empfänger
darauf verlassen, dass die Datenleitung bereits den richtigen Pegel
angenommen hat. Ist das wenn die Clock Leitung ihre erste Flanke macht
oder ist das wenn die Clock Leitung ihre zweite Flanke macht?
Also nicht 'Bit senden', sondern eher so
bei Einstellung auf 2. Flanke
1
+----+
2
| |
3
---------+ +----------
4
5
^
6
|
7
Datenübernahme
8
d.h. die Datenleitung kann bis zu diesem Zeitpunkt
9
ihren Pegel noch wechseln. Ab hier, bei der 2.ten
10
Flanke gilt es: Der Pegel der jetzt anliegt ist
11
der Pegel, der als übertragenes Bit gilt
bei Einstellung auf 1. Flanke
1
+----+
2
| |
3
---------+ +----------
4
5
^
6
|
7
Datenübernahme
8
d.h. die Datenleitung kann bis zu diesem Zeitpunkt
9
ihren Pegel noch wechseln. Ab hier, bei der 1.ten
10
Flanke gilt es: Der Pegel der jetzt anliegt ist
11
der Pegel, der als übertragenes Bit gilt
> Laut Wikipedia sendet der Slave bereits wenn der SS bzw. CS Pin auf Low> gezogen wird um dem Master Daten zum empfangen bereitzustellen,
Was immer du da gelesen hast.
Bei SPI kann ein Slave von sich aus überhaupt nichts 'senden'.
Er kann maximal sein Ausgangsleitung auf einen Pegel legen. Aber das ist
kein 'senden'.
Dir scheint nicht klar zu sein, dass die beiden Leitungen
zusammenspielen. Das eine ist die Datenleitung und das andere ist die
Clockleitung. Die Clockleitung steuert den Datentransfer. Die beiden
gehören untrennbar miteinander zusammen. Um 1 Bit zu übertragen müssen 2
Dinge passieren: Die Datenleitung muss auf den Pegel gebracht werden und
es muss einen Clock Puls geben. Erst dann ist ein Bit gesendet.
> umgekehrt gilt dies aber scheinbar nicht.> Was empfängt also der Slave in diesem Fall?
Ich denke du denkst viel zu kompliziert.
SPI funktioniert viel simpler.
Sorry, ich merke grade, dass ich mich falsch ausgedrückt habe.
Ich meinte mit Senden auch, dass Die Ausgangspegel gesetzt werden.
Mein Problem liegt nichtmal grundsätzlich darin, dass ich nicht verstehe
wann in welchem Modus die Ausgänge gesetzt oder übernommen werden
sondern vielmehr was beim ersten zu übertragenden Bit passiert, wenn
CPHA=0 ist und der Ausgang eben noch nicht gesetzt ist.
Entschuldige bitte die Verwirrung.
Patrick S. schrieb:> sondern vielmehr was beim ersten zu übertragenden Bit passiert, wenn> CPHA=0 ist und der Ausgang eben noch nicht gesetzt ist.
Die Gegenstelle nimmt den Pegel her, der dann gerade auf der Leitung
liegt.
Was soll sie auch sonst tun?
So etwas wie 'nicht gesetzt' gibt es ja eigentlich nicht. Ein Draht hat
entweder 0V oder 5V (oder wenn keiner aktiv dem Draht eine Spannung
beaufschlagt dann hat er eben aus Sicht desjenigen der die Spannung
analysiert irgendeine Spannung je nachdem welches elektromagnetische
Feld gerade einkoppelt). Aber irgendeine Spannung hat er immer.
Das ist genauso wie eine Variable nicht 'keinen Wert' haben kann.
Irgendeinen Wert hat sie immer. Die einzige Frage ist: ist es definiert
irgendein spezieller Wert oder kann man über den Wert keine gesicherte
Aussage treffen. Aber in
1
voidfoo()
2
{
3
intj;
4
...
5
}
hat das j irgendeinen Wert, auch wenn wir umgangssprachlich sagen, dass
es keinen Wert hätte. Gemeint ist: keinen irgendwie definierten Wert.
Aber logischerweise muss die Variable irgendeinen Wert haben, denn der
Speicher ist ja da und die Bits stehen irgendwie. Keiner weiss wie sie
genau stehen, aber eines von beiden, 0 oder 1, müssen sie sein. Der
Speicher materialisiert ja nicht aus dem Nichts, nur weil da jetzt eine
Funktion mit einer lokalen Variablen aufgerufen wird.
Genauso auch hier.
Wenn vereinbart ist, dass die erste Flanke zählt, dann sampelt der
Empfänger zu diesem Zeitpunkt die Datenleitung. Und welchen Pegel die zu
diesem Zeitpunkt hat, das gilt. Unabhängig davon, ob der Sender das auch
so wollte, weil er die Datenleitung erst später (zwischen erster und
zweiter Flanke) auf den von ihm gewollten Pegel bringt, in der Annahme
der Empfänger würde erst bei der zweiten Flanke die Datenleitung
abfragen.
Dichte dem ganzen nicht mehr Intelligenz an, als wirklich drinnen
steckt. Das ganze beruht einfach nur auf der Konvention welche Flanke
zählt. Sender und Empfänger wissen nichts voneinander. Daher muss man
ihnen jeweils sagen, nach welcher Konvention sie vorzugehen haben und
sie müssen sich danach richten. Wenn die Konvention besagt, dass die
erste Flanke zählt, dann muss eben der Sender seine Datenleitung in dem
Zustand haben, der dem zu übertragenden Bit entspricht, noch ehe dann
die erste Flanke tatsächlich generiert wird. Wobei natürlich der Slave
das 'Problem' hat, dass nicht er es ist, der den Taktpuls erzeugt, er
daher a priori nicht wissen kann, wann diese Flanke daher kommt. Das
kann Sekundenbruchteile nach dem Chip Select sein, das kann aber auch 2
Stunden später sein.
Karl Heinz schrieb:> Wenn die Konvention besagt, dass die> erste Flanke zählt, dann muss eben der Sender seine Datenleitung in dem> Zustand haben, der dem zu übertragenden Bit entspricht, noch ehe dann> die erste Flanke tatsächlich generiert wird.
Genau das ist mein Punkt.
Auf Wikipedia steht dazu folgendes:
"Der Slave legt bei CPHA=0 seine Daten schon beim Runterziehen von SS an
MISO an, damit der Master sie beim ersten Flankenwechsel übernehmen
kann. Bei CPHA=1 werden die Daten vom Slave erst beim ersten
Flankenwechsel an MISO gelegt, damit sie beim zweiten Flankenwechsel vom
Master übernommen werden können. Der Master hingegen legt seine Daten
immer zum gleichen Zeitpunkt an, meist kurz nach der fallenden Flanke
von SCK."
http://de.wikipedia.org/wiki/Serial_Peripheral_Interface
Ich bin halt der Meinung dass der Master seine Datenleitung bereits auch
vor Generierung der ersten Flanke in dem Zustand haben sollte der dem
LSB bzw. MSB bit entspricht. Natürlich kann der Pin trotzdem nur 0 oder
1 sein aber ich möchte ja ein definiertes Bit übertragen und nicht
irgendwas was da zufällig anliegt.
Patrick S. schrieb:> Karl Heinz schrieb:>> Flankenwechsel an MISO gelegt, damit sie beim zweiten Flankenwechsel vom> Master übernommen werden können. Der Master hingegen legt seine Daten> immer zum gleichen Zeitpunkt an, meist kurz nach der fallenden Flanke> von SCK.">> http://de.wikipedia.org/wiki/Serial_Peripheral_Interface
Ich bin der Meinung, das ist in Wikipedia zumindest etwas
missverstaendlich geschrieben.
Gemeint ist die fallende Flanke vom vorhergehenden Bit (falls es eines
gab, sonst eben nach dem Select.) D.h. der Master zieht die Datenleitung
so frueh es nur geht auf den richtigen Pegel, noch ehe er beginnt den
Clock Puls zu erzeugen.