Forum: Mikrocontroller und Digitale Elektronik STM32F103 CAN Problem


von Alex Z. (alexz)


Lesenswert?

Hallo,

ich versuche gerade verzweifelt den CAN-Bus zum Laufen zu bringen mit 
einem STM32F103R4. Dazu habe ich mir den Beispielcode von Keil 
(http://www.keil.com/download/docs/351.asp) angeschaut. Leider ist schon 
während der Initialisierung schluss.

Wenn ich nämlich aus dem "initialization mode" in den "normal mode" 
wechseln will, also das INRQ Bit rücksetze, setzt mir die hardware das 
INAK bit nicht zurück. Das passiert sowohl wenn ich den Beispielcode 
ausführe als auch meinen eigenen.

Hier der Auszug aus dem Keil-Code:
1
void CAN_setup (void)  {
2
  unsigned int brp = stm32_GetPCLK1();
3
4
  RCC->APB1ENR |= RCC_APB1ENR_CANEN;              // enable clock for CAN
5
6
                                                  // Note: MCBSTM32 uses PB8 and PB9 for CAN
7
  RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;             // enable clock for Alternate Function
8
  AFIO->MAPR   &= 0xFFFF9FFF;                     // reset CAN remap
9
  AFIO->MAPR   |= 0x00004000;                     //   set CAN remap, use PB8, PB9
10
                          
11
  RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;             // enable clock for GPIO B
12
  GPIOB->CRH &= ~(0x0F<<0);
13
  GPIOB->CRH |=  (0x08<<0);                       // CAN RX pin PB.8 input push pull 
14
  
15
  GPIOB->CRH &= ~(0x0F<<4);
16
  GPIOB->CRH |=  (0x0B<<4);                       // CAN TX pin PB.9 alternate output push pull 
17
18
  NVIC->ISER[0] |= (1 << (USB_HP_CAN_TX_IRQChannel  & 0x1F));// enable interrupt
19
  NVIC->ISER[0] |= (1 << (USB_LP_CAN_RX0_IRQChannel & 0x1F));// enable interrupt
20
21
  CAN->MCR = (CAN_MCR_NART | CAN_MCR_INRQ);       // init mode, disable auto. retransmission
22
                                                  // Note: only FIFO 0, transmit mailbox 0 used
23
  CAN->IER = (CAN_IER_FMPIE0 | CAN_IER_TMEIE);    // FIFO 0 msg pending, Transmit mbx empty
24
25
  /* Note: this calculations fit for PCLK1 = 36MHz */
26
  brp  = (brp / 18) / 500000;                     // baudrate is set to 500k bit/s
27
                                                                          
28
  /* set BTR register so that sample point is at about 72% bit time from bit start */
29
  /* TSEG1 = 12, TSEG2 = 5, SJW = 4 => 1 CAN bit = 18 TQ, sample at 72%    */
30
  CAN->BTR &= ~(((        0x03) << 24) | ((        0x07) << 20) | ((         0x0F) << 16) | (          0x1FF)); 
31
  CAN->BTR |=  ((((4-1) & 0x03) << 24) | (((5-1) & 0x07) << 20) | (((12-1) & 0x0F) << 16) | ((brp-1) & 0x1FF));
32
}
33
34
35
36
37
void CAN_testmode (unsigned int testmode) {
38
39
  CAN->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM);     // set testmode
40
  CAN->BTR |=  (testmode & (CAN_BTR_SILM | CAN_BTR_LBKM));
41
}
42
43
44
void CAN_start (void)  {
45
46
  CAN->MCR &= ~CAN_MCR_INRQ;                      // normal operating mode, reset INRQ
47
  while (CAN->MSR & CAN_MCR_INRQ);
48
49
}

Die Funktionen werden nacheinander aufgerufen. In CAN_start bleibt er 
dann endlos in der while-Schleife hängen, weil eben das INAK bit im MSR 
Register nicht gecleared wird.

Ich hoffe mir kann jemand helfen, ich kanns mir jedenfalls nicht 
erklären.


Gruß, Alex

von Reinhard B. (brainstorm)


Lesenswert?

Hi!

Aus dem Reference Manual:
INAK:
...
This bit is cleared by hardware when the CAN hardware has left the 
initialization mode (to be synchronized on the CAN bus). To be 
synchronized the hardware has to monitor a sequence of 11 consecutive 
recessive bits on the CAN RX signal.

Ist das der Fall? Was hängt am CAN RX Pin?

mfg

von Alex Z. (alexz)


Lesenswert?

Hallo,
naja...der RX Pin ist offen, ebenso der TX Pin, wo soll ich die denn 
anschließen? Ich befinde mich doch im Testmode, dafür is der doch da!?
...
Testmodus:
Loop back combined with silent mode
It is also possible to combine Loop Back mode and Silent mode by setting 
the LBKM and
SILM bits in the CAN_BTR register. This mode can be used for a “Hot 
Selftest”, meaning the
bxCAN can be tested like in Loop Back mode but without affecting a 
running CAN system
connected to the CANTX and CANRX pins. In this mode, the CANRX pin is 
disconnected
from the bxCAN and the CANTX pin is held recessive.

von Reinhard B. (brainstorm)


Lesenswert?

Sorry, das mit dem Testmode habe ich überlesen. Sonst sehe ich leider 
nichts Verdächtiges.

von Alex Z. (alexz)


Lesenswert?

So, zur Vollständigkeit:

Das Problem konnte durch anschließen eines Transceivers behoben werden. 
Hab das im Datenblatt so aufgefasst, dass es im Testmodus egal ist, was 
am RX und TX angeschlossen ist.

Jetzt funzt alles Einwandfrei.

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.