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
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...)
Wo findet eigentlich das remappen der CAN-pins im AFIO_MAPR mit CAN_REMAP [1:0] = "00" auf PA11 und PA12 bei Dir statt?
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.
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?
Ich kann auch leider nur etwas AVR-Assembler. Schon komisch, da ja CAN_Receive in Deinem geposteten Code gar nicht vorkommt ...
Hi Ray@h, an was für ein Projekt arbeitest du gerade? Reine Interesse mit CAN und LCD hört sich interesant an :)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.