CAN Konfiguration

OP #1451539
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?
OP #1451873
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 */

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren