Forum: Mikrocontroller und Digitale Elektronik CAN Konfiguration


von Davos R. (richmand)


Lesenswert?

Ich möchte mit eine MCF52235 von Freescale ein kleines CAN-Netzwerk 
aufbauen, habe aber Probleme, bei der Einstellung der 
Übertragungsfrequenz. Wie bei vielen anderen Prozessoren auch, erfolgt 
diese über die Register PRESDIV, PROPSEG, PSEG1 und PSEG2. Nach längeren 
Recherechen muss ich allerdings gestehen, dass ich bei der 
Funktionsweise nicht so richtig durchsteige.

Mein Prozessor hat einen Systemtakt von 60MHz und einen externen Quarz 
mit 25MHz. Wie müsste ich die Register konfigurieren, dass ich bei 
Verwendung der 60MHz eine Übertragungsrate von 1MBit/s einstellen kann.

Gibt es da nicht vielleicht einfach ein Formel, mit der ich die 
einzelnen Registerwerte berechnen kann, bzw. wie schlimm ist es, wenn 
der eingestellte Wert von der gewünschten Übertragungsgeschwindigkeit 
abweicht?

von (prx) A. K. (prx)


Lesenswert?

Wenn du Glück hast, dann haben diese Felder eine ähnliche Bedeutung wie 
bei anderen CAN Controllern. Dann lässt sich mit den diversen 
Kalkulatoren im Netz was anfangen (Google: can bus bit timing 
calculator).

Die Grundlagen zum Timing findet man beispielsweise dort erklärt: 
http://www.microchip.com/stellent/groups/analog_sg/documents/appnotes/en011947.pdf

von Davos R. (richmand)


Lesenswert?

Ok, vielen Dank! Ich denke ich hab's jetzt. das jeder was davon hat 
werde ich meine Lösung hier kurz darstellen.
Werde doch den externen Quarz als Referenz nehmen, da er kleinere 
Toleranzen hat. Alles in Allem habe ich jetzt eine Funktion auf Basis 
einer von Freescale in MQX implementierten Initialisierung geschrieben, 
die mir die jeweilige Baudrate bei Aufruf der Funktion initialisiert:


Baudrate = Systemtakt / (PRESDIV * (PROPSEG + PSEG1 + PSEG2 +1))

PRESDIV = 1..256
PROPSEG = 1..8
PSEG1   = 1..8
PSEG2   = 1..8

In die Register wird jeweils der gewünschte Wert-1 geschrieben

FLEXCAN_REG_STRUCT_PTR beschreibt die Struktur der Register des FlexCAN 
Moduls
1
uint_32 FLEXCAN_Initialize
2
(
3
   /* FlexCAN base address */
4
   pointer can_ptr,
5
6
  /* Bit rate in Kbps */
7
   uint_32 frequency
8
)
9
10
{ /* Body */
11
   
12
   volatile FLEXCAN_REG_STRUCT_PTR        can_reg_ptr;
13
   volatile FLEXCAN_MSGBUF_STRUCT_PTR     can_bufstruct_ptr;
14
  
15
   can_reg_ptr = (FLEXCAN_REG_STRUCT_PTR)can_ptr;
16
17
   /*
18
   ** Select the clock source
19
   ** Default: external oscillator: 25MHz.
20
   **      used because of tighter tolerance
21
   */
22
  
23
   can_reg_ptr->CANCTRL &= FFFFDFFF;   //delets SYS_CLK bit
24
25
   /*
26
   **  Baud rate = System clock / (PRESDIV + PROPSEG + PSEG1 + PSEG2 +1)
27
   **
28
   **  Register values: Value -1  e.g.:  
29
   **   PRESDIV should be 1 so the  register value must be 0x00
30
   **
31
   */
32
   
33
   switch (frequency)
34
      {
35
      case (20):
36
       /*
37
       ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0
38
         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 50
39
       **
40
       **  sampling point @ 68%
41
       */
42
         
43
         can_reg_ptr->CANCTRL |= 
44
         (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) |MCF_FlexCAN_CANCTRL_RJW(1)
45
            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)
46
            | MCF_FlexCAN_CANCTRL_PRESDIV(49));
47
         break;
48
      
49
50
      case (50):
51
         /*
52
         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0
53
         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x3, PRESDIV = 25
54
         **
55
         **  sampling point @ 85%
56
         */
57
         
58
         can_reg_ptr->CANCTRL |= 
59
         (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)
60
            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(2)
61
            | MCF_FlexCAN_CANCTRL_PRESDIV(24));
62
         break;
63
      
64
65
      case (100):
66
         /*
67
         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0
68
         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 10
69
         **
70
         **  sampling point @ 68%
71
         */
72
         
73
         can_reg_ptr->CANCTRL |= 
74
         (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)
75
            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)
76
            | MCF_FlexCAN_CANCTRL_PRESDIV(9));
77
         break;
78
      
79
80
      case (125):
81
         /*
82
         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0
83
         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x3, PRESDIV = 10
84
         **
85
         **  sampling point @ 85%
86
         */
87
         
88
         can_reg_ptr->CANCTRL |= 
89
         (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)
90
            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(2)
91
            | MCF_FlexCAN_CANCTRL_PRESDIV(9));
92
         break;
93
      
94
95
      case (250):
96
         /*
97
         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0
98
         ** RJW = 0x2, PSEG1 = 0x8, PSEG2 = 0x3, PRESDIV = 5
99
         **
100
         **  sampling point @ 85%
101
         */
102
         
103
         can_reg_ptr->CANCTRL |= 
104
         (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(1)
105
            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(2)
106
            | MCF_FlexCAN_CANCTRL_PRESDIV(4));
107
         break;
108
      
109
110
      case (500):
111
         /*
112
         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x0
113
         ** RJW = 0x4, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 2
114
         **
115
         **  sampling point @ 68%
116
         */
117
         
118
         can_reg_ptr->CANCTRL |= 
119
         (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(3)
120
            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)
121
            | MCF_FlexCAN_CANCTRL_PRESDIV(1));
122
         break;
123
      
124
125
      case (1000):
126
         /*
127
         ** PROPSEG = 0x8, LOM = 0x0, LBUF = 0x0, TSYNC = 0x0, SAMP = 0x1
128
         ** RJW = 0x4, PSEG1 = 0x8, PSEG2 = 0x8, PRESDIV = 1
129
         **
130
         **  sampling point @ 68%
131
         */
132
         
133
         can_reg_ptr->CANCTRL |= 
134
         (0 | MCF_FlexCAN_CANCTRL_PROPSEG(7) | MCF_FlexCAN_CANCTRL_RJW(3)
135
            | MCF_FlexCAN_CANCTRL_PSEG1(7) | MCF_FlexCAN_CANCTRL_PSEG2(7)
136
            | MCF_FlexCAN_CANCTRL_PRESDIV(0));
137
         break;
138
      
139
      default:
140
         return (FLEXCAN_INVALID_FREQUENCY);
141
    
142
143
      return (FLEXCAN_OK);
144
} /* Endbody */

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.