STM32F107VC, CAN Neuling, Beispiel oder Hilfe gesucht

Gast #2508294
Lesenswert?

Hallo, ich versuche gerade den CAN des STM32F107VC zum laufen zu bringen 
und habe dazu mal ein ST-Beispiel angepasst, da die ja auf bestimmte 
Eval Boards ausgelegt sind. Allerdings funktioniert hier überhaupt 
nichts bzw. ich bin Anfänger und habe keine Ahnungt vom CAN. Ich dachte 
dass bei korrekter Funktion vom TX Pin ein Signal ausgehen würde. Ein 
Transciever ist noch nicht angeschlossen. Kann mir jemand helfen oder 
mich auf ein konkretes Beispiel verweisen? Ich hänge mal den Code an. 
Danke

main:
1
/* Includes ------------------------------------------------------------------*/
2
#include "stm32f10x.h"
3

4
/* Private define ------------------------------------------------------------*/
5
//#define __CAN1_USED__
6
 #define __CAN2_USED__*/   /* Please check that you device is
7
                                Connectivity line when using CAN2 */
8

9
#ifdef  __CAN1_USED__
10
  #define CANx CAN1
11
#else /*__CAN2_USED__*/
12
  #define CANx CAN2
13
#endif  /* __CAN1_USED__ */
14

15
/* Private typedef -----------------------------------------------------------*/
16
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
17
/* Private macro -------------------------------------------------------------*/
18
/* Private variables ---------------------------------------------------------*/
19
__IO uint32_t ret = 0; /* for return of the interrupt handling */
20
volatile TestStatus TestRx;
21

22
/* Private function prototypes -----------------------------------------------*/
23
void NVIC_Configuration(void);
24
TestStatus CAN_Polling(void);
25
TestStatus CAN_Interrupt(void);
26

27
/* Private functions ---------------------------------------------------------*/
28

29
  
30
int main(void)
31
{
32

33

34
    /* CAN1 Periph clock enable */
35
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
36

37
//  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
38
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
39
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
40

41

42

43
GPIO_InitTypeDef GPIO_InitStructure;
44

45
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
46
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
47
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
48
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
49
    GPIO_Init(GPIOC, &GPIO_InitStructure);
50

51
    // Configure CAN Tx as push-pull
52
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
53
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
54
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
55
      GPIO_Init(GPIOB, &GPIO_InitStructure);
56
    // Configure CAN Rx as input floating
57
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
58
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
59
      GPIO_Init(GPIOB, &GPIO_InitStructure);
60

61

62
#ifdef  __CAN1_USED__
63
  /* CANx Periph clock enable */
64
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
65
#else /*__CAN2_USED__*/
66
  /* CAN1 & 2  Periph clock enable */
67
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
68
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
69
#endif  /* __CAN1_USED__ */
70

71
  /* NVIC Configuration */
72
  NVIC_Configuration();
73

74

75
  /* CAN transmit at 125Kb/s and receive by polling in loopback mode */
76
  TestRx = CAN_Polling();
77

78
  if (TestRx == FAILED)
79
  {
80
    /* Turn on led LD3 */
81
   // STM_EVAL_LEDOn(LED3);
82

83
  GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);
84

85
  }
86
  else
87
  {
88
    /* Turn on led LD1 */
89
    //STM_EVAL_LEDOn(LED1);
90
    GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET);
91

92
  }
93

94
  /* CAN transmit at 500Kb/s and receive by interrupt in loopback mode */
95
  TestRx = CAN_Interrupt();
96

97
  if (TestRx == FAILED)
98
  {
99
    /* Turn on led LD4 */
100
   //STM_EVAL_LEDOn(LED4);
101
    GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_SET);
102
  }
103
  else
104
  {
105
    /* Turn on led LD2 */
106
   // STM_EVAL_LEDOn(LED2);
107
    GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_RESET);
108
  }
109

110
  /* Infinite loop */
111
  while (1)
112
  {
113

114

115
  }
116
}
117

118
/**
119
  * @brief  Configures the CAN, transmit and receive by polling
120
  * @param  None
121
  * @retval PASSED if the reception is well done, FAILED in other case
122
  */
123
TestStatus CAN_Polling(void)
124
{
125
  CAN_InitTypeDef        CAN_InitStructure;
126
  CAN_FilterInitTypeDef  CAN_FilterInitStructure;
127
  CanTxMsg TxMessage;
128
  CanRxMsg RxMessage;
129
  uint32_t i = 0;
130
  uint8_t TransmitMailbox = 0;
131

132
  /* CAN register init */
133
  CAN_DeInit(CANx);
134

135
  CAN_StructInit(&CAN_InitStructure);
136

137
  /* CAN cell init */
138
  CAN_InitStructure.CAN_TTCM=DISABLE;
139
  CAN_InitStructure.CAN_ABOM=DISABLE;
140
  CAN_InitStructure.CAN_AWUM=DISABLE;
141
  CAN_InitStructure.CAN_NART=DISABLE;
142
  CAN_InitStructure.CAN_RFLM=DISABLE;
143
  CAN_InitStructure.CAN_TXFP=DISABLE;
144
  CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
145

146
  /* Baudrate = 125kbps*/
147
  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
148
  CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;
149
  CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;
150
  CAN_InitStructure.CAN_Prescaler=48;
151
  CAN_Init(CANx, &CAN_InitStructure);
152

153
  /* CAN filter init */
154
#ifdef  __CAN1_USED__
155
  CAN_FilterInitStructure.CAN_FilterNumber=0;
156
#else /*__CAN2_USED__*/
157
  CAN_FilterInitStructure.CAN_FilterNumber=14;
158
#endif  /* __CAN1_USED__ */
159
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
160
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
161
  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
162
  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
163
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
164
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
165
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
166

167

168
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
169
  CAN_FilterInit(&CAN_FilterInitStructure);
170

171
  /* transmit */
172
  TxMessage.StdId=0x11;
173
  TxMessage.RTR=CAN_RTR_DATA;
174
  TxMessage.IDE=CAN_ID_STD;
175
  TxMessage.DLC=2;
176
  TxMessage.Data[0]=0xCA;
177
  TxMessage.Data[1]=0xFE;
178

179
  TransmitMailbox=CAN_Transmit(CANx, &TxMessage);
180
  i = 0;
181
  while((CAN_TransmitStatus(CANx, TransmitMailbox) != CANTXOK) && (i != 0xFFFF))
182
  {
183
    i++;
184
  }
185

186
  i = 0;
187
  while((CAN_MessagePending(CANx, CAN_FIFO0) < 1) && (i != 0xFFFF))
188
  {
189
    i++;
190
  }
191

192
  /* receive */
193
  RxMessage.StdId=0x00;
194
  RxMessage.IDE=CAN_ID_STD;
195
  RxMessage.DLC=0;
196
  RxMessage.Data[0]=0x00;
197
  RxMessage.Data[1]=0x00;
198
  CAN_Receive(CANx, CAN_FIFO0, &RxMessage);
199

200
  if (RxMessage.StdId!=0x11)
201
  {
202
    return FAILED;
203
  }
204

205
  if (RxMessage.IDE!=CAN_ID_STD)
206
  {
207
    return FAILED;
208
  }
209

210
  if (RxMessage.DLC!=2)
211
  {
212
    return FAILED;
213
  }
214

215
  if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE)
216
  {
217
    return FAILED;
218
  }
219

220
  return PASSED; /* Test Passed */
221
}
222

223
/**
224
  * @brief  Configures the CAN, transmit and receive using interrupt.
225
  * @param  None
226
  * @retval PASSED if the reception is well done, FAILED in other case
227
  */
228
TestStatus CAN_Interrupt(void)
229
{
230
  CAN_InitTypeDef        CAN_InitStructure;
231
  CAN_FilterInitTypeDef  CAN_FilterInitStructure;
232
  CanTxMsg TxMessage;
233
  uint32_t i = 0;
234

235
  /* CAN register init */
236
  CAN_DeInit(CANx);
237

238

239
  CAN_StructInit(&CAN_InitStructure);
240

241
  /* CAN cell init */
242
  CAN_InitStructure.CAN_TTCM=DISABLE;
243
  CAN_InitStructure.CAN_ABOM=DISABLE;
244
  CAN_InitStructure.CAN_AWUM=DISABLE;
245
  CAN_InitStructure.CAN_NART=DISABLE;
246
  CAN_InitStructure.CAN_RFLM=DISABLE;
247
  CAN_InitStructure.CAN_TXFP=DISABLE;
248
  CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
249
  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
250

251
  /* Baudrate = 500 Kbps */
252
  CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;
253
  CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;
254
  CAN_InitStructure.CAN_Prescaler=12;
255
  CAN_Init(CANx, &CAN_InitStructure);
256

257
  /* CAN filter init */
258
#ifdef  __CAN1_USED__
259
  CAN_FilterInitStructure.CAN_FilterNumber=1;
260
#else /*__CAN2_USED__*/
261
  CAN_FilterInitStructure.CAN_FilterNumber=15;
262
#endif  /* __CAN1_USED__ */
263
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
264
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
265
  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
266
  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
267
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
268
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
269
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
270
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
271
  CAN_FilterInit(&CAN_FilterInitStructure);
272

273
  /* CAN FIFO0 message pending interrupt enable */
274
  CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);
275

276
  /* transmit 1 message */
277
  TxMessage.StdId=0;
278
  TxMessage.ExtId=0x1234;
279
  TxMessage.IDE=CAN_ID_EXT;
280
  TxMessage.RTR=CAN_RTR_DATA;
281
  TxMessage.DLC=2;
282
  TxMessage.Data[0]=0xDE;
283
  TxMessage.Data[1]=0xCA;
284
  CAN_Transmit(CANx, &TxMessage);
285

286
  /* initialize the value that will be returned */
287
  ret = 0xFF;
288

289
  /* receive message with interrupt handling */
290
  i=0;
291
  while((ret == 0xFF) && (i < 0xFFF))
292
  {
293
    i++;
294
  }
295

296
  if (i == 0xFFF)
297
  {
298
    ret=0;
299
  }
300

301
  /* disable interrupt handling */
302
  CAN_ITConfig(CANx, CAN_IT_FMP0, DISABLE);
303

304
  return (TestStatus)ret;
305
}
306

307
/**
308
  * @brief  Configures the NVIC and Vector Table base address.
309
  * @param  None
310
  * @retval None
311
  */
312
void NVIC_Configuration(void)
313
{
314
  NVIC_InitTypeDef NVIC_InitStructure;
315

316
  /* Enable CANx RX0 interrupt IRQ channel */
317
#ifndef STM32F10X_CL
318

319
#ifdef  __CAN1_USED__
320
  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
321
#else  /*__CAN2_USED__*/
322
  /* CAN2 is not implemented in the device */
323
   #error "CAN2 is implemented only in Connectivity line devices"
324

325
#endif /*__CAN1_USED__*/
326
#else
327
#ifdef  __CAN1_USED__
328
  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
329
#else  /*__CAN2_USED__*/
330
  NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
331
#endif /*__CAN1_USED__*/
332

333
#endif /* STM32F10X_CL*/
334
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
335
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
336
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
337
  NVIC_Init(&NVIC_InitStructure);
338
}
339

340
#ifdef  USE_FULL_ASSERT
341

342
/**
343
  * @brief  Reports the name of the source file and the source line number
344
  *         where the assert_param error has occurred.
345
  * @param  file: pointer to the source file name
346
  * @param  line: assert_param error line source number
347
  * @retval None
348
  */
349
void assert_failed(uint8_t* file, uint32_t line)
350
{
351
  /* User can add his own implementation to report the file name and line number,
352
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
353

354
  /* Infinite loop */
355
  while (1)
356
  {
357
  }
358
}
359

360
#endif
361

362
/**
363
  * @}
364
  */
365

366
/**
367
  * @}
368
  */
369

370
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/



ISR
1
  */
2
#ifndef STM32F10X_CL
3
void USB_LP_CAN1_RX0_IRQHandler(void)
4
#else
5
void CAN1_RX0_IRQHandler(void)
6
#endif
7
{
8
  CanRxMsg RxMessage;
9

10
  RxMessage.StdId=0x00;
11
  RxMessage.ExtId=0x00;
12
  RxMessage.IDE=0;
13
  RxMessage.DLC=0;
14
  RxMessage.FMI=0;
15
  RxMessage.Data[0]=0x00;
16
  RxMessage.Data[1]=0x00;
17

18
  CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
19

20
  if((RxMessage.ExtId==0x1234) && (RxMessage.IDE==CAN_ID_EXT)
21
     && (RxMessage.DLC==2) && ((RxMessage.Data[1]|RxMessage.Data[0]<<8)==0xDECA))
22
  {
23
    ret = 1;
24
  }
25
  else
26
  {
27
    ret = 0;
28
  }
29
}
30

31
/**
32
  * @brief  This function handles CAN2 Handler.
33
  * @param  None
34
  * @retval None
35
  */
36
#ifdef STM32F10X_CL
37
void CAN2_RX0_IRQHandler(void)
38

39
{
40
  CanRxMsg RxMessage;
41

42
  RxMessage.StdId=0x00;
43
  RxMessage.ExtId=0x00;
44
  RxMessage.IDE=0;
45
  RxMessage.DLC=0;
46
  RxMessage.FMI=0;
47
  RxMessage.Data[0]=0x00;
48
  RxMessage.Data[1]=0x00;
49

50
  CAN_Receive(CAN2, CAN_FIFO0, &RxMessage);
51

52
  if((RxMessage.ExtId==0x1234) && (RxMessage.IDE==CAN_ID_EXT)
53
     && (RxMessage.DLC==2) && ((RxMessage.Data[1]|RxMessage.Data[0]<<8)==0xDECA))
54
  {
55
    ret = 1;
56
  }
57
  else
58
  {
59
    ret = 0;
60
  }
61
}
62
#endif
#2508347
Lesenswert?

> Ich dachte dass bei korrekter Funktion vom TX Pin ein Signal ausgehen
> würde.

Dies ist (fast) richtig:
Hast du keinen Tranceifer/keinen Gegenspieler sollte der CAN-Kontroller
das Paket ein paar mal senden (jeweils mit einem Errorframe angehängt)
und dann in den BUS-OFF Zustand wechseln. Dies geht sehr schnell.

Vielleicht hilft dir auch dieser Beitrag:
Beitrag "CAN Problem Freescale S12X"
Gast #2508372
Lesenswert?

Danke, ich denke das könnte helfen. Ich habe mich natürlich etwas mit 
der Theorie beschäftigt, also welche Pakete werden verschickt bzw. wie 
sind die Frames aufgebaut ect. Aber ich habe halt noch nie einen auf 
einem µC programmiert und habe dahingehend keine Ahnung. Das meinte ich. 
Auch dachte ich, den den Controller dazu zwingen kann die Botschaft 
mittels einer Schleife ständig zu senden, so dass man ein Signal sehen 
kann, auch ohne Transceiver . Ich wollte ja noch nichts konkretes 
auslesen, sonder im ersten Schritt nur mal etwas zappeln sehen. Ich 
versuchs noch mal mit dem Transceiver.. sobald er da ist.

Ich habs doch gerade noch mal schnell durchlaufen lassen. Du hast recht, 
am Anfang kommt wirklich ein Paket. Wie gesagt ich dachte ich könnte ihn 
zwingen das öfter zu schicken durch mehrmaligen Aufruf.


Ich meine mal gelesen zu haben dass man sich auf kurzen Strecken den 
Transceiver schenken kann. Also zum Testen auf wenigen cm z.B. Hat 
dahingehend jemand Erfahrungen?
Gast #2508447
Lesenswert?

Ja, wie gesagt ich habe es erst später gesehen. Da ich von einer 
Widerholung ausgegangen bin habe ich das Programm gestartet und dann 
erst die Oszispitze an den Pin gehalten bzw. Mich auf die Triggerung 
verlassen die Wiederholte Signale darstellen sollte.

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