Forum: Mikrocontroller und Digitale Elektronik Lm3s9b96 CAN controller initialisierung


von Timmi (Gast)


Lesenswert?

Hallo,
bin grad dabei mich mit dem LM3s9b96 vom Stellaris auseinander zu 
setzen. Bin dabei über das Stellaris Board, wobei auf dem 2 CAN 
controller drauf sind, mit dem canalyzer anzuschließen. Hab zwar in c 
schon die initialisierung komplett durchgenommen, jedoch kommt da nichts 
gescheites dabei raus, die CAN0H und CAN0L Pins geben am Oszi nichts 
gescheites bei raus. Ich kann ja mal meinen code hier reinstellen, 
vielleicht erkennt ja jemand den Fehler, vielleicht vergesse ich nur 
etwas. Ich möchte über dem CAN 0 Daten zum Canalyzer senden, dort 
sollten normalerweise die ID und Daten zu sehen sein, jedoch gibt er mir 
nur ein ERROR Frame zurück. Immerhin sagt er dass auf dem Can 1 Daten 
empfangen oder gesendet werden.

Kann mir da einer weiterhelfen?
1
int
2
main(void)
3
{
4
5
      // Set the clocking to run directly from the PLL.
6
      //
7
    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
8
9
10
      //
11
      // Configure CAN 0 Pins.
12
      //
13
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
14
15
16
      // Configure the GPIO pin muxing to select CAN0 functions for these pins.
17
      // This step selects which alternate function is available for these pins.
18
      // This is necessary if your part supports GPIO pin function muxing.
19
      // Consult the data sheet to see which functions are allocated per pin.
20
      // TODO: change this to select the port/pin you are using
21
      //
22
      GPIOPinConfigure(GPIO_PB4_CAN0RX);
23
      GPIOPinConfigure(GPIO_PB5_CAN0TX);
24
25
//      GPIOPinConfigure(GPIO_PF0_CAN1RX);
26
//      GPIOPinConfigure(GPIO_PF1_CAN1TX);
27
28
      GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5);
29
30
31
      //
32
      // Enable the CAN controller.
33
      //
34
      SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
35
36
      //
37
      // Reset the state of all the message object and the state of the CAN
38
      // module to a known state.
39
      //
40
      CANInit(CAN0_BASE);
41
42
      //
43
      // Set up the bit rate for the CAN bus.  This function sets up the CAN
44
      // bus timing for a nominal configuration.  You can achieve more control
45
      // over the CAN bus timing by using the function CANBitTimingSet() instead
46
      // of this one, if needed.
47
      // In this example, the CAN bus is set to 500 kHz.  In the function below,
48
      // the call to SysCtlClockGet() is used to determine the clock rate that
49
      // is used for clocking the CAN peripheral.  This can be replaced with a
50
      // fixed value if you know the value of the system clock, saving the extra
51
      // function call.  For some parts, the CAN peripheral is clocked by a fixed
52
      // 8 MHz regardless of the system clock in which case the call to
53
      // SysCtlClockGet() should be replaced with 8000000.  Consult the data
54
      // sheet for more information about CAN peripheral clocking.
55
      //
56
      CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);
57
                //
58
59
60
      //
61
      // Enable interrupts from CAN controller.
62
      //
63
      CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR);// | CAN_INT_STATUS
64
65
      //
66
      // Enable the CAN interrupt on the processor (NVIC).
67
      //
68
      //IntEnable(INT_CAN0);
69
70
      // Enable the CAN for operation.
71
      //
72
      CANEnable(CAN0_BASE);
73
74
      // Initialize message object 1 to be able to send CAN message 1.  This
75
      // message object is not shared so it only needs to be initialized one
76
      // time, and can be used for repeatedly sending the same message ID.
77
78
      g_sCANMsgObject1.ulMsgID = 0x100;
79
      g_sCANMsgObject1.ulMsgIDMask = 0;
80
      g_sCANMsgObject1.ulFlags = MSG_OBJ_TX_INT_ENABLE;
81
      g_sCANMsgObject1.ulMsgLen = sizeof(g_ucMsg1);
82
      g_sCANMsgObject1.pucMsgData = g_ucMsg1;
83
84
      // Initialize message object 2 to be able to send CAN message 2.  This
85
      // message object is not shared so it only needs to be initialized one
86
      // time, and can be used for repeatedly sending the same message ID.
87
      //
88
      g_sCANMsgObject2.ulMsgID = 0x200;
89
      g_sCANMsgObject2.ulMsgIDMask = 0;
90
      g_sCANMsgObject2.ulFlags = MSG_OBJ_TX_INT_ENABLE;
91
      g_sCANMsgObject2.ulMsgLen = sizeof(g_ucMsg2);
92
      g_sCANMsgObject2.pucMsgData = g_ucMsg2;
93
94
      for(;;)
95
          {
96
              //
97
              // Send message 1 using CAN controller message object 1.  This is
98
              // the only message sent using this message object.  The
99
              // CANMessageSet() function will cause the message to be sent right
100
              // away.
101
              //
102
              //PrintCANMessageInfo(&g_sCANMsgObject1, 1);
103
              CANMessageSet(CAN0_BASE, 1, &g_sCANMsgObject1, MSG_OBJ_TYPE_TX);
104
105
              //
106
              // Send message 2 using CAN controller message object 2.  This is
107
              // the only message sent using this message object.  The
108
              // CANMessageSet() function will cause the message to be sent right
109
              // away.
110
              //
111
             // PrintCANMessageInfo(&g_sCANMsgObject2, 2);
112
              CANMessageSet(CAN0_BASE, 2, &g_sCANMsgObject2, MSG_OBJ_TYPE_TX);
113
114
              //
115
              // Load message object 3 with message 3.  This is needs to be done each
116
              // time because message object 3 is being shared for two different
117
              // messages.
118
              //
119
              g_sCANMsgObject3.ulMsgID = 0x300;
120
              g_sCANMsgObject3.ulMsgIDMask = 0;
121
              g_sCANMsgObject3.ulFlags = MSG_OBJ_TX_INT_ENABLE;
122
              g_sCANMsgObject3.ulMsgLen = sizeof(g_ucMsg3);
123
              g_sCANMsgObject3.pucMsgData = g_ucMsg3;
124
125
              //
126
              // Clear the flag that indicates that message 3 has been sent.  This
127
              // flag will be set in the interrupt handler when a message has been
128
              // sent using message object 3.
129
              //
130
              g_bMsgObj3Sent = 0;
131
132
              //
133
              // Now send message 3 using CAN controller message object 3.  This is
134
              // the first message sent using this message object.  The
135
              // CANMessageSet() function will cause the message to be sent right
136
              // away.
137
              //
138
              PrintCANMessageInfo(&g_sCANMsgObject3, 3);
139
              CANMessageSet(CAN0_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);
140
141
              //
142
              // Wait for the indication from the interrupt handler that message
143
              // object 3 is done, because we are re-using it for another message.
144
              //
145
//              while(!g_bMsgObj3Sent)
146
//              {
147
//              }
148
149
              //
150
              // Load message object 3 with message 4.  This is needed because
151
              // message object 3 is being shared for two different messages.
152
              //
153
              g_sCANMsgObject3.ulMsgID = 0x300;
154
              g_sCANMsgObject3.ulMsgIDMask = 0;
155
              g_sCANMsgObject3.ulFlags = MSG_OBJ_TX_INT_ENABLE;
156
              g_sCANMsgObject3.ulMsgLen = sizeof(g_ucMsg4);
157
              g_sCANMsgObject3.pucMsgData = g_ucMsg4;
158
159
              //
160
              // Now send message 4 using CAN controller message object 3.  This is
161
              // the second message sent using this message object.  The
162
              // CANMessageSet() function will cause the message to be sent right
163
              // away.
164
              //
165
              //PrintCANMessageInfo(&g_sCANMsgObject3, 3);
166
              CANMessageSet(CAN0_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);
167
168
              //
169
              // Wait 1 second before continuing
170
              //
171
              SimpleDelay();
172
173
              //
174
              // Check the error flag to see if errors occurred
175
              //
176
              if(g_bErrFlag)
177
              {
178
                  UARTprintf(" error - cable connected?\n");
179
              }
180
              else
181
              {
182
                  //
183
                  // If no errors then print the count of message sent
184
                  //
185
                  UARTprintf(" total count = %u\n",
186
                             g_ulMsg1Count + g_ulMsg2Count + g_ulMsg3Count);
187
              }
188
189
              //
190
              // Change the value in the message data for each of the messages.
191
              //
192
              (*(unsigned long *)g_ucMsg1)++;
193
              (*(unsigned long *)g_ucMsg2)++;
194
              (*(unsigned long *)g_ucMsg3)++;
195
              (*(unsigned long *)&g_ucMsg4[0])++;
196
              (*(unsigned long *)&g_ucMsg4[4])--;
197
          }
198
199
          //
200
          // Return no errors
201
          //
202
          return(0);
203
}

von Timmi (Gast)


Lesenswert?

keiner der mir hierbei helfen kann?

von Timmi (Gast)


Lesenswert?

Ich sehe nun zwar eine CAN Frame jedoch entspricht sie nicht der 
normalen Frame, da ich nnur 16 bits sehe, normalerweise sollte ich mehr 
bits sehen, zumal 11 bits vom identifier sind und mehrere bits der Daten 
dayu kommen noch start und stop bits etc. kann mir einer vielleicht hier 
helfen und und weis das das Problem sein koennte.

von Hannes (Gast)


Lesenswert?

HAllo, ich habe mir ma deinen Code angeschaut weil ich gerad den CAN bus 
bei einem lm3s5749 inbetrieb nehmen will.

Wo sind denn deine INitialiserungen der entsprechenden Register???
kannst du bitte das gesamte projekt mal posten ....da ich nciht weiß was 
sich hinter deien Fuktionen verbirgt..


Mit freundlcihen Grüßen

von Hannes (Gast)


Lesenswert?

hatte vergessen meien email anzugeben

;-)

von Markus R. (maggus)


Lesenswert?

Hannes schrieb:
> Wo sind denn deine INitialiserungen der entsprechenden Register???

Die werden durch die Funktionen (z.B. CANBitRateSet(...)) gesetzt. Die 
Funktionen sind in den StellarisWare Bibliotheken enthalten, zu denen es 
auch ein Manual (Stellaris Peripheral Driver Library User's Guide) gibt.

Die Funktion CANBitRateSet gibt die tatsächlich eingestellte Bitrate als 
unsigned long zurück, schau mal ob das richtig eingestellt wird (bei 
manchen Taktraten sind nicht alle Bitraten möglich).

Probier mal zum Testen dieses Msg-Object:
unsigned char buffer[10];
tCANMsgObject sMsgObjectTx;

sMsgObjectTx.ulMsgID = 0x100;
sMsgObjectTx.ulMsgIDMask = 0;
sMsgObjectTx.ulFlags = 0;
sMsgObjectTx.ulMsgLen = 8;
sMsgObjectTx.pucMsgData = buffer;

Versenden mit
CANMessageSet(CAN0_BASE, 1, &sMsgObjectTx, MSG_OBJ_TYPE_TX);

Bei CAN ist es ausgesprochen wichtig, dass auch ein Emfänger (mit 
gleicher Bitrate) am Bus hängt, der die Nachrichten durch das ACK-Bit 
bestätigt. Außerdem muss der Bus mit 120 Ohm abeschlossen sein und es 
müssen RX UND TX des Transceivers mit dem Mikrocontroller verbunden sein 
(der CAN-Protokollcontroller muss "sich selbst hören können").

Wenn du keine Interrupts verwendest, CANIntEnable(...) auskommentieren.
Mit CANRetrySet(CAN0_BASE, true); kannst du die automatische 
Retransmission ein bzw. ausschalten.

// Edit: Ich seh grad, der Beitrag war schon älter. Vllt. hilfts ja 
trotzdem irgendwann mal jemandem...

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.