Hallo an alle. Ich habe ein LIN-Slavemodul gebaut auf dem ein ATMega168 und ein ATA6662 (LIN-Transceiver) sitzt. Nutze auserdem AVRStudio mit gcc Ich will mein LIN-Slavemodul auf eine LIN-Header-Nachricht des Masters synchronisieren. Dazu habe ich folgendes Datenblatt gefunden. http://www.atmel.com/dyn/resources/prod_documents/doc7653.pdf ich versteh nur leider nicht wie ich es anwenden muss. Kann mir jemand bei der Synchronisation meines Slaves helfen? Ich danke im voraus.
Gast
#1238116
>Ich will mein LIN-Slavemodul auf eine LIN-Header-Nachricht des Masters >synchronisieren. Die Application Note bezieht sich - nach kurzer Sichtung - mehr auf das Autobauding, d.h. Abgleich der Slave-Baudrate auf den Master. Insbesondere erforderlich bei Eisatz von RC-Oszillatoren. Du meinst wahrscheinlich mehr die grundsätzliche Synchronisation auf die LIN-Nachricht, oder?
Gast
#1238122
Falls Du die grundsätzliche Synchronisation meinst, geht das wie folgt: - Im Receive-Interrupt als erstes prüfen, ob ein Framing-Error vorliegt (Verdacht auf Break) - Prüfen, ob das empfangene Byte = 0 ist. - Ich prüfe zusätzlich zu diesem Zeitpunkt noch, ob der Portpin RXD an dieser Stelle ebenfalls noch '0' ist. Nur empfehlenswert bei Interrupt-basierender Verarbeitung. - Empfangs-State-Machine an dieser Stelle auf jeden Fall zurücksetzen, ein Break hat immer Vorrang. - Nächstes Byte sollte ein 0x55 sein (An dieser Stelle kann man einige Prozessoren auf das Autobauding mittels 0x55 Character vorbereiten, z.B. PIC) - Als nächstes Byte die ID empfangen. Parität prüfen und feststellen, ob ID für einen selbst bestimmt ist. - Je nach geplanter Frame Datenrichtung nun 1..8 Datenbytes senden oder empfangen. - Checksumme empfangen und prüfen oder Checksumme berechnen und senden. - Fertig. Die Prüfung mittels Framing Error mag einigen Usern nicht genügen, sie hätte theoretisch noch einige Unzulänglichkeiten. In der Praxis machen das aber viele Implementationen so. Ich auch.
Harald wrote: > Du meinst wahrscheinlich mehr die grundsätzliche Synchronisation auf die > LIN-Nachricht, oder? ja! mein code
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
das ist was ich soweit habe. doch muss ich nicht dafür sorgen, dass sich der slave synchronisiert? oder reicht es das ich einen Quarz nutze ?
Gast
#1238147
Wenn Du einen Quarz nutzt, sehe ich bei festgelegter Baudrate (nicht Norm-konform) für Synchronisation keinen Bedarf. Sonst müsste sich ja jede beliebige UART-Schnittstelle auf geeignete Art und Weise synchronisieren. Im großen Stückzahl-Bereich tut man sicherlich alles dafür, um auf einen Quarz verzichten zu können. Ganz nebenbei sollte ein RC-Oszillator auch weniger Ausfallrisiko haben (Quarzbruch etc.). Für ein privates Projekt oder Kleinserie indes völlig unerheblich.
Gast
#1238160
Sichte gerade deien Code. Du solltest nicht ernsthaft im Interrupt auf
neue Bytes warten, das frisst ja deine ganze Rechenzwit auf. Viel besser
baust Du eine State-Machine auf, stark vereinfacht dargestellt:
if (FramingError) state = 1;
switch (state)
{
case 0 : break; // Standby, nichts zu tun
case 1 : Empfangsbyte==0x55 --> nein= state=0, ja=state++
case 2 : Empfangsbyte==ID ? --> nein=state=0, ja=state++
case 3 : Bytes in Schleife empfangen/senden
case 4 : Checksumme senden bzw. prüfen --> Gültig=state++ /
ungültig=state=0
case 5 : Frame an Applikation übergeben, state=0
}
Is es notwendig es in einer statemashine zu machen? Denn ich sammel mit meinem Modul Daten mit den ADC und wandle diese um. Das tue ich solange bis ich ein Anfrage vom Master erhalte die gesammelten Daten an ihn (Master) zu senden. gibt es eine bessere Möglischkeit?
Gast
#1238173
Wie gesagt, ich würde den Code auf State-Machine umstellen. Die meisten UART sind ja double-buffered, d.h. ein nachfolgend empfangenes Byte schlägt im nächsten Durchlauf auf. In deinem Code gibst Du aber dem Break nicht die höchste Priorität. Wenn sich der Master den Abbruch des Frames überlegt (ist - glaube ich - in der Norm vorgesehen) würde dein Code das nicht berücksichtigen bzw. durcheinander kommen.
steht denn im Empfangsregister das Syncbreak solange bis ich es mittels receiveByte() abrufe? Erhalte ich beim 2. Aufruf von receiveByte() dann das Sync-Field? tut mir leid die fragen mögen sehr trivial und dumm erscheinen.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Gast
#1239221
Ich bin jetzt beim AVR nicht so im Thema. Bei einigen Prozessoren muss man nach einem Framing Error erstmal alle Fehler zurücksetzen, bevor es weiter geht. In diesem Fall würde es so nicht funktionieren. Baue deine Interrupt-Routine so auf, dass immer nur ein Byte verarbeitet wird. Dann veranlasst Du alles notwendige und bereitest den Interrupt auf den Empfang des nächsten Bytes vor.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.