Forum: Mikrocontroller und Digitale Elektronik STM32 Problem


von Ray@h (Gast)


Lesenswert?

Hallo,

seit kurzem schlage ich mich mit einem STM32 (STM32F103C8T8) herum und 
der tut inzwischen auch einigermaßen was er soll, aber jetzt habe ich 
ein Problem bei dem ich nicht weiter komme:
Die IOs GPIOA4-7 verwende ich als Datenleitungen zum ansteuern eines 
LCDs, die Steuerleitungen des LCDs habe ich an GPIOC13-15 angeschlossen. 
Funktioniert soweit auch hervorragend.
Nun wollte ich die CAN-Schnittstelle an GPIOA11-12 in Betrieb nehmen und 
habe das Problem, dass ich jedes mal, wenn der Controller die 
Datenrichtung der Datenleitungen umschalten soll in der 
HardFaultException lande, nehme ich nur die Pin-Konfiguration für die 
CAN-PINs:

  // Configure CAN pin: RX
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // Configure CAN pin: TX
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

aus dem Programm, funktioniert zwar meine CAN-Schnittstelle nicht, dafür 
bekomme ich aber auch keinen HardFault mehr. Konfiguriere ich die 
CAN-Pins wieder und initialisiere die CAN:

/* CAN register init */
  CAN_DeInit(CAN1);
  CAN_StructInit(&CAN_InitStructure);

  /* CAN cell init */
  CAN_InitStructure.CAN_TTCM = DISABLE;
  CAN_InitStructure.CAN_ABOM = ENABLE;
  CAN_InitStructure.CAN_AWUM = DISABLE;
  CAN_InitStructure.CAN_NART = DISABLE;
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_5tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
  CAN_InitStructure.CAN_Prescaler = 4;  // CLK=64MHz/2
  CAN_Init(CAN1, &CAN_InitStructure);

 /* CAN filter init */
  CAN_FilterInitStructure.CAN_FilterNumber=0;
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);

   /* transmit */
  TxMessage.StdId = 0x321;
  TxMessage.ExtId = 0x01;
  TxMessage.RTR = CAN_RTR_DATA;
  TxMessage.IDE = CAN_ID_STD;
  TxMessage.DLC = 8;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

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

  CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

kann ich danach die Datenrichtung meines LCD-Ports nicht mehr anfassen.
Als IDE verwende ich Crossworks, Jtag-Adapter ist ein Olimex 
ARM-USB-OCD.

Falls irgendjemand einen Tipp hat, warum ich an der Stelle auf die 
Schnauze falle, bin für jeden Rat dankbar.

Vielen Dank und sorry für den vielen (Quell-) Text.

Ray

von Lutz (Gast)


Lesenswert?

Ist im richtigen Programm denn auch die Reihenfolge eingehalten (erst 
jeweiliges Peripheral clock enable und dann erst Peripheral 
konfigurieren)? Am besten immer den auf ein Minimum reduzierten, aber 
kompletten Sourcecode posten. Dann erübrigen sich viele Rückfragen. 
(Viel mehr werde ich wohl leider nicht "helfen" können, da ich selbst 
gerade erst starte...)

von Lutz (Gast)


Lesenswert?

Wo findet eigentlich das remappen der CAN-pins im AFIO_MAPR mit 
CAN_REMAP [1:0] = "00" auf PA11 und PA12 bei Dir statt?

von Lutz (Gast)


Lesenswert?

Ähem, vergiß den letzten Post; "00" ist der reset value ...

von Ray@h (Gast)


Lesenswert?

Lutz schrieb:
> Ist im richtigen Programm denn auch die Reihenfolge eingehalten (erst
> jeweiliges Peripheral clock enable und dann erst Peripheral
> konfigurieren)?

jein, zuerst werden alle GPIOs auf floating input gesetzt (sollten sie 
zwar schon sein, aber ...)
dann wird der Systemclock (PLL) angeworfen und anschliessend alle 
Peripherie-Clocks gesetzt, nun NVIC, GPIOs und ADC und Timer und CAN 
konfiguriert.

von Ray@h (Gast)


Lesenswert?

Hallo,

ich habe jetzt etwas herum geschaut und festgestellt, dass Crossworks 
den call_stack zur Verfügung stellt, die letzte aufgerufene Funktion 
war:
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage)
und
dort steht der PC auf -> Disassembler

RxMessage->Data[3] = (uint8_t)0xFF & 
(CANx->sFIFOMailBox[FIFONumber].RDLR >> 24);
    793B        ldrb r3, [r7, #4]
    68BA        ldr r2, [r7, #8]
    EA4F1303    mov.w r3, r3, lsl #4
    4413        add r3, r2
    F50373DC    add.w r3, r3, #0x1B8
->  681B        ldr r3, [r3, #0]
    EA4F6313    mov.w r3, r3, lsr #24
    B2DA        uxtb r2, r3
    683B        ldr r3, [r7, #0]
    739A        strb r2, [r3, #14]

sehe ich das recht, dass hier gerade das 4.Byte aus dem Receive-FIFO 
kopert werden soll (kann leider [noch] kein Assembler)? Kann es sein, 
dass die CAN-Hardware im selbem Moment den FIFO neu beschreibt und es 
daher zu einem Zugriffskonflikt kommt?

von Lutz (Gast)


Lesenswert?

Ich kann auch leider nur etwas AVR-Assembler.
Schon komisch, da ja CAN_Receive in Deinem geposteten Code gar nicht 
vorkommt ...

von Jackie73 (Gast)


Lesenswert?

Hi Ray@h,
an was für ein Projekt arbeitest du gerade?

Reine Interesse mit CAN und LCD hört sich interesant an :)

von Ray@h (Gast)


Lesenswert?

Lutz schrieb:
> Schon komisch, da ja CAN_Receive in Deinem geposteten Code gar nicht
> vorkommt ...

Naja ich wollte jetzt nicht die ganzen libs von ST mit posten, da im 
geposteten Code aber ein Interrupt für CAN initialisiert wird, ergibt es 
sich fast schon von selbst, dass es dazu auch eine passende 
Interrupt-Routine gibt - auch schön brav aus den Beispielen von ST 
übernommen. Da ich im Moment aber keine Zeit für weitere Fehlersuche 
habe, ist das Ganze erst einmal auf Eis gelegt, bis ich wieder etwas 
Luft und Lust habe.

Jackie73 schrieb:
> Hi Ray@h,
> an was für ein Projekt arbeitest du gerade?
>
> Reine Interesse mit CAN und LCD hört sich interesant an :)
Eigentlich ein PWM-Controller der über CAN eingestellt werden kann - so 
ein einfaches Display (2x16) ist immer schön, wenn man ein paar 
Statusausgaben haben will. Jeder Teil für sich funktioniert auch, nur 
sobald CAN mit etwas anderem laufen soll, wird es instabil und früher 
oder später landet der Controller im
HardFault (default) Handler (Endlosschleife).

Bye

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.