Hallo,
ich arbeite mit einem MCP201, welches über USART an einem PIC18f242
angeschlossen ist. Wenn ich den CS-Eingang vom MCP201 auf High lege und
per USART etwas schicke und dann den CS-Eingang auf low lege, kann ich
auf dem Oszi sehen, dass etwas über den LIN gesendet wird. Jedoch gibt
CANoe immer eine Fehlermeldung aus, dass der Header nicht stimmt.
Hat jemand mit diesem IC schon mal gearbeitet? Ich finde leider keinen
Besispielcode oder ein Tutorial. Ich weiß leider nicht, wie ich den
Identifier und die Daten per USART an den MCP201 schicke.
Kann mir jemand helfen???
Gruß Paul
Wenn CANoe sagt, dass der Header nicht stimmt, so liegt das nicht an dem
MCP201. Dieser Baustein macht ja nur die physikalische Umsetzung von
TTL-UART auf LIN-1-Draht. Vereinfacht kann man sagen, dass der MCP201
die LIN-Leitung auf Low zieht, wenn TX des Controller = 0 ist. Der
aktuelle Pegel des LIN-BUS wird auf den RX des Controllers
"zurückgespiegelt".
Was ist denn der PIC18F242, Lin-Master oder Slave? Falls Slave, der
Header wird NUR vom Master gesendet, niemals vom Slave!
Der PIC ist Master. Muss ich dann einfach den Header bzw. Identifier und
danach die Daten nacheinander per USART an den MCP201 übertragen? Der
Start und die Synchronisation erfolgen automatisch?
Zunächst einmal muss der MCP201 in den aktivn Modus versetzt werden -->
siehe Datenblatt, das ist ein Flankenwechsel an -WAKE.
Gesendet wird folgendes:
- Break 13 bit low Pegel (kann z.B. durch temporäres Herunterschalten
der Baudrate erreicht werden --> Byte 0 senden)
- Auf gewünschter Datenrate (z.B 19200 Baud) 0x55 senden (Sync)
- ID incl. 2 Paritybits (siehe Norm, ich hole die vorbereitete 6-bit-ID
+ 2 Partity-Bits aus einer Tabelle mit 64 Einträgen)
- Jetzt gibt es zwei Möglichkeiten:
- 1. Wenn der Master Daten an den Slave sendet, werden jetzt 1..8 Daten
gesendet, anschliessend Checksumme laut Norm (V1.3 oder V2.0)
- 2. Wenn der Slave Daten senden soll, sendet der Slave jetzt 1..8 Daten
(der Slave führt sozusagen den vom Master initiierten Frame weiter),
anschliessend Checksumme laut Norm
Wenn alles richtig gemacht wurde, sollte man mit CANoe etwas sehen.
Ist das ein privates Projekt oder ein kommerzielles?
Wenn Du offensichtlich schon Vector-Kunde bist: Die haben ein Poster, wo
die LIN-Kommunikation schön übersichtlich dargestellt ist. Frag dort mal
an, die senden Dir das sicherlich gerne. Übrigens gibt es die Poster
auch für CAN und FlexRay.
Kannst du dir vielleicht mal mein Programm angucken und sagen, ob das so
ungefähr stimmt?
Habs versucht wie du beschriben hast zu machen, aber bei CANoe kommt
trotzdem eine Fehlermeldung.
Gern, was mir sofort auffällt:
Beim Senden des 0-Bytes als Break musst Du die Baudrate umschalten.
Ansonsten bekommst Du ja keinen 13-bit langen Break. Es müssen meines
Wissens auch nicht genau 13 bit sein, es kann auch etwas länger sein.
Probiere es also in etwa so;
- Baudrate auf 4800 schalten
- Byte 0 senden
- Baudrate auf 9600 schalten
- Byte 0x55 senden
- Byte ID senden
- usw.
Nach außen hin sieht dieses mit niedriger Baudrate gesendete 0 Byte dann
wie der gewünschte Break aus.
Viel Erfolg!
Danke für den Tipp. Hab ich ausprobiert und funktioniert leider immer
noch nicht. Theoretisch könnte ich doch auch statt die Baudrate zu
halbieren einfach zweimal 0x00 senden (hab mit beidem keinen Erfolg).
Oder sehe ich das falsch? Zudem wird auf den Veranschaulichungen (z.B.
Vector) ein Delimiter am Ende des Break gesendet. Dann müsste ich doch
eigentlich 0x01 (oder 0x02) senden? Außerdem steht auf der Vector-Seite,
dass das Sync-Feld und das PID-Feld 10 bit lang sind. Das PID-Feld ist
doch aber 0x55 und das sind nur 8 Bit. Das verwirrt mich. Manchmal steht
noch ein Start- und ein Stopp-Bit, dann würde man auf 10 Bit kommen. Da
ich die zu sendenden Daten per USART schicke, kann ich ja nicht 10 Bit
senden.
>Oder sehe ich das falsch?
Ja, zwei 0-Bytes kannst Du NICHT hintereinander senden, da dazwischen
zwangläufig 1 Stopbit liegen würde. Anhand des Start- und Stopbits
erfolgt ja die UART-Synchronisation. Mit den 10 bit ist das Datenbyte +
Start und Stopbit gemeint. Der Break ist ja mit seinen >> 10 bit eine
bewusste Verletzung dieses Framings, damit kann jeder Teilnehmer den
Beginn eines neuen Frame eindeutig erkennen. In den Empfängern mache ich
die Break-Detektion anhand eines Framing-Errors:
Ist das ein Framing-Error aufgetreten
UND
ist das empfangene Datenbyte = 0
UND
ist das Portbit ebenfalls bei Eintritt in den Interrupt noch '0'
1. Schritt
Du könntest versuchen, mit einem normalen RS232 Transceiver an den PC zu
gehen. Trotz des Breaks sollte man den Frame in einem Terminal-Programm
wie HTERM erkennen.
2. Schritt
Bist Du dir überhaupt sicher, dass der MCP201 sendet? Am besten mit
einem Oszi überprüfen, zur Not tut es auch eine LED mit einem 1..3k
Widerstand gegen +UB. Im Ruhezustand ist die LED aus, bei Sendung sollte
die dann sichtbar flackern.
Also ich hatte schon mit einem Oszi geguckt und es war zu sehen, dass
etwas auf dem LIN gesendet wird. Habs grad nochmal mit einer LED
ausprobiert und gleiches Ergebnis.
Hab mein Programm grad so umgeschrieben, dass ich die Baudrate veränder.
Anscheinend reicht es nicht, dass ich einfach SPBRG mit einem anderen
Wert beschreibe? Ich dachte, nach dem ich die USART initialisiert habe,
brauch ich nur noch SPBRG mit dem berechneten Wert zu beschreiben....
Wie ist WriteUSART() aufgebaut? Wird das Byte in die HW geschrieben und
dann gewartet? Oder wird erst geprüft ob UART busy und dann das Byte
geschrieben? Im letzteren Fall würde das erneute Umschalten auf 9600 zu
früh kommen.
Wenn Du ein Oszi zur Verfügung hast, könntest Du ja etwas genauer
prüfen: Eine Bitzeit ist 104µs, d.h. ein Byte sind 8*104µs+2*104µs
(Startbit + 8 Bit + Stopbit). Ein Byte auf der UART ist immer Startbit =
0, dann die 8 bit Daten + Stopbit = 1. Bei dem Break müsstest Du eine
'0'-Lücke sehen, die signifikant breiter als die anderen Bytes ist.
Dabei muss das Break bei 9600 Baud also mindestens 13*104µs '0' sein.
Danach der Delimiter (einfach eine Mindest-Ruhepause) und dann das
charackteristische Muster von dem Sync, sprich 0x55 (01010101)
Ich kann leider nicht genau sagen, der von dir beschriebene erste oder
zweite Fall auf WriteUSART zutrifft. Ich kann in meiner verwendeten
usart.h keine vernüftige Funktionsweise der WriteUSART erkennen. Kannst
du mir vielleicht sagen, wie ich das Problem für den zweiten Fall
umgehe? Habs grad mit einem delay versucht, aber scheint auch nichts zu
nützen.
Das Oszi hab ich leider nicht zu Hause, nur an der Uni :-(
(Hab mal die usart.h mit hochgeladen, falls du rein gucken möchtest)
Und schon mal ein riesen Dank, dass du mir so viel hilfst.
Das mit dem Delay war auf jeden Fall der richtige Ansatz, das würde
diese Problematik in jedem Fall abfangen. Ich würde sagen, schau erstmal
mit dem Oszi und dann gehts weiter!
So...ich komm grad aus der Uni. Hab mit dem Oszi nachgesehen und eine
ganze Weile hin und her probiert. Mein Ergebnis ist:
Baudratenumschaltung funktioniert. Sogar ohne ein Delay. Die Daten, die
ich per UART schicke, werden auch auf dem LIN gesendet. Man muss
allerdings beachten, das der MCP201 das LSB zuerst sendet. Wenn ich also
0xF0 (11110000) gesendet hab, kam auf dem LIN 0xF (00001111) an. Aber
gut zu wissen.
Hab mich gefreut und bin nach Hause....hier jetzt die Ernüchterung.
Immer noch ein Fehler. Illegal Sync-Byte und nicht mehr illegal Header.
Ich steiger mich :-) Als Sync-Byte sendet man doch 0x55. Damit
funktionierts nicht und mit 0xAA leider auch nicht.
Also der MCP201 kann nichts an der Bitfolge drehen, er ist nur der
physikalische Umsetzer. Da ist keine Intelligenz drin, gar nichts, null!
Der UART sendet IMMER das LSB first, das ist aber immer so (siehe auch
http://de.wikipedia.org/wiki/EIA-232). Ich wüsste keine
UART-Implementation, wo man das überhaupt drehen könnte (SPI schon, aber
nicht UART).
Nimm dir doch einfach das Oszi und lege die LIN-Norm daneben. Bis zur ID
kann man das Timing doch ganz einfach selbst auszählen.
Ich könnte mir noch vorstellen, dass CANoe sehr resitriktiv auf das
Timing reagiert. Vielleicht passen auch die Delimiter-Zeiten auch nicht.
Ist CANoe überhaupt auf Autobaud-Erkennung geschaltet oder geht es von
einer festen Baudrate aus? Könnte mir nämlich vorstellen, dass ansonsten
die meist gängigere Rate 19200 eingestellt ist. In diesem Fall könnte er
die auf 9600 gesendete 0x55 nicht erkennen.
So hab mal wieder mit dem Oszi gemessen. Signal vom MCP201 sieht so weit
sehr gut aus. Muss wohl an den Einstellungen von CANoe liegen, da denke
ich aber auch schon alle ausprobiert.
Hier mal ein Bild, wo nur Break und Sync gesendet werden. (Da ist mir
auch aufgefallen, dass ich ein Fehler bei der Baudrate gemacht hatte)
Hier mal ein Bild von einem kompletten Frame. Ich habe mal als Break
eine 0x80 gesendet, weil auf einigen Bildern im Inet zu sehen war, das
eine kleine Pause zwischen Break und Sync liegt (Delimiter).
Funktioniert so aber auch nicht. Der Rest stimmt auch, als Identifier
hatte ich glaub 0x3C gesendet und als Daten-Byte 0xF0.
Sieht gut aus, vielleicht liegt es - wie schon gesagt - an CANoe. Könnte
sein, dass die aufgrund Einhaltung von Automobilnormen ein
ultrakorrektes Timing erwarten. Wenn Du es nur für private Zwecke
benötigst, würde ich es dabei belassen und mich um die
"Gegenstation(en)" kümmern. Oder Du versucht es noch mal mit 19200 Baud.
Das wollte ich vorhin machen, hab aber festgestellt, dass ich dazu erst
ein anderes Qurtz brauch. Bis jetzt ist eins mit 8 MHz drauf und mit den
PIC-internen 2 MHz schaff ich keine 19200. Wird auch morgen besorgt.