Forum: Mikrocontroller und Digitale Elektronik STM32 CAN Problem Remap Problem


von Stefan Z. (derdespot)


Lesenswert?

Hallo STM32 Freunde,

ich habe folgendes Problem:

Ich benutze das STM3210B_EVAL Board von ST. Der CAN Transceiver ist mit 
den Pins PD0 (RX) und PD1 (TX) verbunden. Da ich ein Projekt auf einem 
kleinerem Evalboard (Olimex STM32-H103) umsetzen möchte, bei dem die 
Pins PD1 und PD0 nicht nutzbar sind, wollte ich die Remap Funktionalität 
des STM32 nutzen. Man muss dazu sagen, dass ohne Remap die Pins PA12 und 
PA11 verwendet werden. Das remappen auf die Pins PD0 und PD1 auf dem 
STM3210B_EVAL funktioniert ohne Probleme jedoch nicht das ummappen auf 
die Pins PB8 und PB9. Hat jemand Ähnliche Erfahrungen gemacht?

kurz:

Remap auf PD0 & PD1 : GPIO_Remap2_CAN1
Remap auf PB8 & PB9 : GPIO_Remap1_CAN1

Letzteres funktioniert nicht, auch nicht auf dem kleinen Olimex 
Evalboard. Die Pins sind unbeschaltet, es hängt also keine Hardware 
dahinter. (JP6 auf dem STM3210B_EVAL Jumper entfernt + R78 Widerstand 
ausgelötet) An den Pins PB8 und PB9 auf dem Olimexboard hängt auch keine 
Schaltung.

Ich bin schon seit 2 Tagen auf der Suche nach einer Lösung, aber ich 
kann dazu leider nichts finden...

Viel Dank schonmal.

Grüße Stefan

von Stefan Z. (derdespot)


Lesenswert?

Achjam, beim ramap auf die Pins PB8 und PB9 hat der TX Pin (PB9) einen 
konstanten Highpegel.

von Ecke (Gast)


Lesenswert?

Hallo, ich hänge gerade am gleichen Problem. Hast du eine Lösung dafür 
gefunden?? Viele Grüße, Sven

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Schon mal gelesen was im "RM0008" unter 9.3.3 in der Fußnote (3) steht?

Alles vom RM0008 9.3.x ist interessant.

von holger (Gast)


Lesenswert?

>Hallo, ich hänge gerade am gleichen Problem. Hast du eine Lösung dafür
>gefunden?? Viele Grüße, Sven

CAN lässt sich problemlos auf PB8,9 remappen. Zeig mal deinen
Code.

von Sven Wagner (Gast)


Lesenswert?

Markus Müller schrieb:
> Schon mal gelesen was im "RM0008" unter 9.3.3 in der Fußnote (3) steht?
Welche Version? Bei mir (doc 13902, rev 11) steht das was von:
1
9.3.3 Rising trigger selection register (EXTI_RTSR)

Grüße
Sven

von (prx) A. K. (prx)


Lesenswert?

Er meint vielleicht die Rev 13: "This remapping is available only on 
100-pin and 144-pin packages, when PD0 and PD1 are not remapped on 
OSC-IN and OSC-OUT." Was dem Thema zwar näher ist, aber trotzdem daneben 
trifft, denn mit PDx solle es ja funktionieren, aber nicht mit PBx.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ja, ich hatte das in der Rev 12 an der gleichen Stelle.

Vermutlich ist irgend ein Clock noch nicht an, den es benötigt.

In jedem Fall sollte 9.3.x gelesen werden, denn darüber bin ich damals 
erst gestolpert als ich den CAN auf PDx bereits gelegt hatte und nachher 
nichts ging.

von Ecke (Gast)


Lesenswert?

Die Fußnoten habe ich gelesen. Bei meinem Derivat handelt es sich um den 
64 Pin. Das Mappen auf B sollte laut Datenblatt funktionieren. Hier mein 
Code:

Initialisierungroutine :


uint8_t  CAN_init_se(void){
  uint32_t baudRate = 500000;
  uint8_t retVal = CANINITFAILED;
  GPIO_InitTypeDef GPIO_InitStructure;

  /* CAN register init */
  CAN_DeInit( CAN1);

  /* CAN cell init */
  CAN_InitStructure.CAN_TTCM = DISABLE;
  CAN_InitStructure.CAN_ABOM = DISABLE;
  CAN_InitStructure.CAN_AWUM = DISABLE;
  CAN_InitStructure.CAN_NART = ENABLE;
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal  ;


  if (0 != CalculateBitTiming(baudRate, &CAN_InitStructure))
    {
      return 1;
    }
  CAN_StructInit(&CAN_InitStructure);

  // Enable GPIOB and AFIO clock
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, 
ENABLE);
  // Enable CAN 1 Clock
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);


  //GPIO_PinRemapConfig(GPIO_Remap1_CAN, ENABLE);

  // Configure CAN Tx as push-pull
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  // Configure CAN Rx as input floating
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  //GPIO_PinRemapConfig(GPIO_Remap1_CAN, ENABLE);

  // Remap CAN1 to PB8 and PB9
  AFIO->MAPR &= ~(AFIO_MAPR_CAN_REMAP);
  AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_REMAP2;

  retVal = CAN_Init(CAN1,&CAN_InitStructure);

  return retVal;
}

Senderoutine:

void Test_CAN(void)
{
  CanTxMsg TxMessage;
  CanRxMsg RxMessage;
  uint32_t i = 0;
  uint8_t TransmitMailbox = 0;
  TxMessage.StdId = 0x11;
  TxMessage.RTR = CAN_RTR_DATA;
  TxMessage.IDE = CAN_ID_STD;
  TxMessage.DLC = 2;
  TxMessage.Data[0] = 0xCA;
  TxMessage.Data[1] = 0xFE;

  uint32_t temp =0;
  temp = CAN1->TSR;
  temp = CAN1->ESR;
  TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);
  temp = CAN1->TSR;
  temp = CAN1->ESR;


  i = 0;
  while ((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK)
      && (i != 0xFF))
  {
    i++;
  }
}

von Matthias K. (matthiask)


Lesenswert?

Hier meine funktionierende INIT mit Remap. µC ist STM32F103RE.

1
//***********************************************************************************************
2
// CAN Initialisierung
3
//***********************************************************************************************
4
void init_can (void) {
5
  CAN_InitTypeDef       CAN_InitStructure;
6
  CAN_FilterInitTypeDef CAN_FilterInitStructure;
7
  GPIO_InitTypeDef  GPIO_InitStructure;
8
9
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIO B Takt 
10
11
  // CAN RX
12
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;           // PB8=CANRX
13
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;        // Pin Mode
14
  GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_50MHz;    // Pin Taktung
15
  GPIO_Init(GPIOB, &GPIO_InitStructure);
16
17
  // CAN TX
18
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;             // PB9=CANTX
19
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;       // Pin Mode
20
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     // Pin Taktung
21
  GPIO_Init(GPIOB, &GPIO_InitStructure);
22
23
  // CAN1 Periph clock enable
24
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);          // CAN1 Takt freigeben
25
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);          // AFIO Takt freigeben (für Remapping)
26
27
  // Remapping CANRX und CANTX von PA11 und PA12 auf PB8 und PB9
28
  // (PA11/12 sind die USB-Pins)
29
  GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
30
31
  // CAN Register init
32
  CAN_DeInit(CAN1);
33
  CAN_StructInit(&CAN_InitStructure);
34
35
  // CAN cell init
36
  CAN_InitStructure.CAN_TTCM=DISABLE;
37
  CAN_InitStructure.CAN_ABOM=DISABLE;
38
  CAN_InitStructure.CAN_AWUM=DISABLE;
39
  CAN_InitStructure.CAN_NART=DISABLE;
40
  CAN_InitStructure.CAN_RFLM=DISABLE;
41
  CAN_InitStructure.CAN_TXFP=DISABLE;
42
  CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
43
  //CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
44
  
45
  // CAN Bitrate
46
  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;    // SJW (1 bis 4 möglich)
47
  CAN_InitStructure.CAN_BS1=CAN_BS1_12tq;   // Samplepoint 72%
48
  CAN_InitStructure.CAN_BS2=CAN_BS2_5tq;    // Samplepoint 72%
49
  
50
  //CAN_InitStructure.CAN_Prescaler=1;        // 2000 kbit/s
51
  //CAN_InitStructure.CAN_Prescaler=2;        // 1000 kbit/s
52
  //CAN_InitStructure.CAN_Prescaler=4;        //  500 kbit/s
53
  //CAN_InitStructure.CAN_Prescaler=5;        //  400 kbit/s
54
  //CAN_InitStructure.CAN_Prescaler=8;        //  250 kbit/s
55
  //CAN_InitStructure.CAN_Prescaler=10;       //  200 kbit/s
56
  //CAN_InitStructure.CAN_Prescaler=16;       //  125 kbit/s
57
  CAN_InitStructure.CAN_Prescaler=20;       //  100 kbit/s
58
  //CAN_InitStructure.CAN_Prescaler=40;       //   50 kbit/s
59
  //CAN_InitStructure.CAN_Prescaler=80;       //   40 kbit/s
60
  //CAN_InitStructure.CAN_Prescaler=200;      //   10 kbit/s
61
  //CAN_InitStructure.CAN_Prescaler=1023;      //    ganz langsam
62
63
  CAN_Init(CAN1, &CAN_InitStructure);
64
65
  // CAN filter init
66
  CAN_FilterInitStructure.CAN_FilterNumber=1;
67
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
68
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
69
  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
70
  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
71
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
72
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
73
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
74
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
75
  CAN_FilterInit(&CAN_FilterInitStructure);
76
77
  // CAN FIFO0 message pending interrupt enable
78
  CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
79
}

von Markus 1234 (Gast)


Lesenswert?

Ich habe ebenfalls ein Problem mit dem PinRemap des CAN auf die Pins B8 
und B9.
Controller ist ein STM32F103ZET6, besitzt 144 Pins, OSC ist nicht 
ramapped auf D (RM0008).
Nutze aus der STM  Lib die CAN LoopBack Funktion. An A12 kann ich 
mittels Oszi auch ein CAN Signal abgreifen, die Software scheint also zu 
funktionieren, bloß nicht der Remap auf PB8 und PB9.

Kann mir jemand sagen, was noch getan werden muss? Welche Clocks noch 
aktiviert werden müssen?
1
// Config CAN pin TX
2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
3
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
5
GPIO_Init(GPIOB, &GPIO_InitStructure);
6
7
// Config CAN pin RX
8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
11
GPIO_Init(GPIOB, &GPIO_InitStructure);
12
13
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
14
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);
15
16
GPIO_PinRemapConfig(GPIO_Remap1_CAN, ENABLE);

Der Remap auf PD0, PD1 funktioniert auch nicht. Was hab ich vergessen?

von Markus 1234 (Gast)


Lesenswert?

Prima mit dem Code von Matthias K. (matthiask) läuft es jetzt auch bei 
mir. Hatte wohl wirklich einen Clock vergessen frei zu geben.
Danke

von Ecke (Gast)


Lesenswert?

Hey Matthias, Danke für den Code. Bei mir klappt es leider nicht. Beim 
initialisieren (CANinit()) löscht die HW das Bit im MSR Register nicht. 
Dadurch kann der CAN nicht initialisiert werden.
Das Bord ist eine STM103-STK von Olimex. Vielleicht hat jemand schon mal 
damit Erfahrung gehabt.

von Matthias K. (matthiask)


Lesenswert?

Ecke schrieb:
> Hey Matthias, Danke für den Code. Bei mir klappt es leider nicht. Beim
> initialisieren (CANinit()) löscht die HW das Bit im MSR Register nicht.
> Dadurch kann der CAN nicht initialisiert werden.

Ich würde entweder konsequent die STM Lib benutzen oder Alternativ nur 
die Register-Variante wählen. Beides zusammen ist nicht optimal und 
führt zu Fehlern und unübersichtlichen Programmen. Zumal bekommst Du 
hier weniger Hilfe, wenn beides zusammen ist. Es gibt da nämlich 2 
Helfer-Fraktionen ;-)))

Welche STM Lib Version hast Du eingebunden? Schau darin mal in die 
Examples für CAN. Könnte hilfreich sein.

von Ecke (Gast)


Lesenswert?

Die zwei Zeilen zum Mappen hatte ich aus einem anderen Beispiel. Sonst 
nutze ich die STM Lib. Zufällig habe ich meinen Code zur CAN 
Initialisierung + Senden auf einen MCBSTM32 Bord von Keil getestet. Die 
Beschaltungen zwischen meinem Bord und dem Keil Bord sind identisch.Ein 
Remapping erfolgt genau so. Entweder hat der Controller ein Problem oder 
der Fehler liegt an einer anderen Stelle.

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.