Forum: Mikrocontroller und Digitale Elektronik AT90CAN sample point fehler bei BRP = 0


von Alex S. (thor368)


Lesenswert?

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

von Alex S. (thor368)


Lesenswert?

Hat noch keiner hier die baudrate eines AVR CAN controllers eingestellt?

Thor

von Horst (Gast)


Lesenswert?

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.

von Alex S. (thor368)


Lesenswert?

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

von Horst (Gast)


Lesenswert?

Sorry, habe es nie selbst gerechnet.
Die Werte stammen aus der Tabelle im Datenblatt.
Benutze nur niedrige Baudraten und da passt es.

von Alex S. (thor368)


Lesenswert?

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

von Alex S. (thor368)


Lesenswert?

Jap, geht.

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
Noch kein Account? Hier anmelden.