www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 Problem


Autor: Ray@h (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...)

Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Lutz (Gast)
Datum:

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

Autor: Ray@h (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ray@h (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Lutz (Gast)
Datum:

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

Autor: Jackie73 (Gast)
Datum:

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

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

Autor: Ray@h (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.