Tach allerseits, ich habe Probleme das bit-timing der CAN controller zu verstehen. So viel habe ich gerafft: Als erstes wird eine bit clock aus dem IO clock per prescaler erzeugt. Die längen der bit Segmente werden dann als natürliche Vielfache der bit clock angegeben. Die bitrate wird dann als Summe aller Segmentlängen berechnet. Des weiteren scheint es wohl Standard zu sein das sync Segment und die resync jump width auf 1 zu setzten. Nun ein Paar Fragen: Unter 19.4.3 im Datenblatt wird erwähnt, dass wenn der prescaler auf 0 steht der sample point zu früh kommt. Dies zeigt sich auch unter 19.12 Tabelle 19-2 16MHz 1MBaud 16TQ. Der sample point kommt nach 11 und nicht 12 TQs. Er liegt damit noch innerhalb des phase segment 1 obwohl er ersts danach stattfinden sollte. Ist das mit "This leads to a fail according the ISO16845 Test plan." unter 19.4.3 gemeint? Außerdem frage ich mich ob das überhaupt schlim ist, denn Atmel schreibt ja selbst, dass man den sample point verschieben kann um sich an die Gegebenheiten des Bus anzupassen. ZB lange Laufzeiten vs. hohe Datenraten. Außerdem habe ich nicht ganz verstanden warum es Sinn macht ein bit in mehr als 8 TQs aufzuspalten. Warum mehr nehmen als mann muss? Thor
Hab es so gemacht: Für AT90CAN128 mit 16MHz Quarz -> SCLOCK == 8 führt nur zu einem anderen Prescaler! Der Aufruf erfolgt dann meist so für 250kb/s: CAN128_init(250,0,0);
1 | //8 MHz
|
2 | #define CAN128_8SPD_1000 0x00,0x04,0x12 // 8TQs
|
3 | #define CAN128_8SPD_800 0x00,0x04,0x24 //10TQs
|
4 | #define CAN128_8SPD_500 0x02,0x04,0x13 // 8TQs
|
5 | #define CAN128_8SPD_250 0x02,0x0C,0x37 //16TQs below
|
6 | #define CAN128_8SPD_125 0x06,0x0C,0x37
|
7 | #define CAN128_8SPD_100 0x08,0x0C,0x37
|
8 | #define CAN128_8SPD_50 0x12,0x0C,0x37
|
9 | #define CAN128_8SPD_25 0x26,0x0C,0x37
|
10 | #define CAN128_8SPD_20 0x30,0x0C,0x37
|
11 | |
12 | //16 MHz
|
13 | #define CAN128_16SPD_1000 0x02,0x04,0x13 // 8TQs
|
14 | #define CAN128_16SPD_800 0x02,0x04,0x25 //10TQs
|
15 | #define CAN128_16SPD_500 0x02,0x0C,0x37 //16TQs below
|
16 | #define CAN128_16SPD_250 0x06,0x0C,0x37
|
17 | #define CAN128_16SPD_125 0x0E,0x0C,0x37
|
18 | #define CAN128_16SPD_100 0x12,0x0C,0x37
|
19 | #define CAN128_16SPD_50 0x26,0x0C,0x37
|
20 | #define CAN128_16SPD_25 0x3E,0x0E,0x4B //20TQs
|
21 | #define CAN128_16SPD_20 0x3E,0x0E,0x7F //25TQs
|
22 | |
23 | void CAN128_setBitRate(u08 Canbt1,u08 Canbt2,u08 Canbt3) { |
24 | CANBT1=Canbt1; |
25 | CANBT2=Canbt2; |
26 | CANBT3=Canbt3; |
27 | }
|
28 | |
29 | /*=====================================================================*/
|
30 | u08 CAN128_init(u16 bitrate, u08 BT2, u08 BT3) |
31 | {
|
32 | //keep for Controller-Reset
|
33 | CAN128_ActBitrate=bitrate; |
34 | CAN128_CanBT2=BT2; |
35 | CAN128_CanBT3=BT3; |
36 | //
|
37 | sbi(DDRD,5); |
38 | cbi(DDRD,6); |
39 | //
|
40 | CAN128_reset(); |
41 | //bit timing -> datasheet page 260 (check table)
|
42 | if ((BT2==0)&&(BT3==0)) { |
43 | if (SCLOCK==16) |
44 | {
|
45 | if (bitrate==1000) CAN128_setBitRate(CAN128_16SPD_1000); |
46 | else if (bitrate== 800) CAN128_setBitRate(CAN128_16SPD_800); |
47 | else if (bitrate== 500) CAN128_setBitRate(CAN128_16SPD_500); |
48 | else if (bitrate== 250) CAN128_setBitRate(CAN128_16SPD_250); |
49 | else if (bitrate== 125) CAN128_setBitRate(CAN128_16SPD_125); |
50 | else if (bitrate== 100) CAN128_setBitRate(CAN128_16SPD_100); |
51 | else if (bitrate== 50) CAN128_setBitRate(CAN128_16SPD_50); |
52 | else if (bitrate== 25) CAN128_setBitRate(CAN128_16SPD_25); |
53 | else if (bitrate== 20) CAN128_setBitRate(CAN128_16SPD_20); |
54 | else CAN128_setBitRate(CAN128_16SPD_250); |
55 | }
|
56 | else //if (SCLOCK==8) |
57 | {
|
58 | if (bitrate==1000) CAN128_setBitRate(CAN128_8SPD_1000); |
59 | else if (bitrate== 800) CAN128_setBitRate(CAN128_8SPD_800); |
60 | else if (bitrate== 500) CAN128_setBitRate(CAN128_8SPD_500); |
61 | else if (bitrate== 250) CAN128_setBitRate(CAN128_8SPD_250); |
62 | else if (bitrate== 125) CAN128_setBitRate(CAN128_8SPD_125); |
63 | else if (bitrate== 100) CAN128_setBitRate(CAN128_8SPD_100); |
64 | else if (bitrate== 50) CAN128_setBitRate(CAN128_8SPD_50); |
65 | else if (bitrate== 25) CAN128_setBitRate(CAN128_8SPD_25); |
66 | else if (bitrate== 20) CAN128_setBitRate(CAN128_8SPD_20); |
67 | else CAN128_setBitRate(CAN128_8SPD_250); |
68 | }
|
69 | }
|
70 | else { |
71 | CAN128_setBitRate((bitrate&0xFF),BT2,BT3); |
72 | }
|
73 | //...
|
74 | }
|
Hoffe es hilft dir.
Ah ja, das ist gut. Ich habe momentan das Problem, dass ich wegen eines dämlichen UARTs mit hoher baudrate ein binäres Quarz verwenden muss (18,432MHz). Der CAN läuft auf 125kBaud. Das ist ekelig. Die nächste baudrate die man nach Atmel Vorschlag bekommen würde ist 128kBaud. Das ist deutlich zu weit daneben. Ich habe mal ein wenig rumgerechnet und bin auf folgendes Ergebnis gestoßen. Kannst du das mal verifizieren? Prescaler auf 21 und 7 bitclocks: 2 prs + 2 ph1 + 2 ph2 + 1 sync Gibt eine baudrate von 125.387baud. Das liegt 0,31% daneben. Sample point sollte bei 71,43% liegen. Eigentlich ziemlich gut. Wenns stimmt... Hier noch die Register settings: CANBT1 = 0x28 CANBT2 = 0x02 CANBT3 = 0x12 Thor
Sorry, habe es nie selbst gerechnet. Die Werte stammen aus der Tabelle im Datenblatt. Benutze nur niedrige Baudraten und da passt es.
OK, ich werde dann einfach hier noch mal einen post drunter setzten, wenn ich Gelegenheit hatte es auszuprobieren. Das kann allerdings noch einen Monat dauern. Thor
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.