Forum: Mikrocontroller und Digitale Elektronik [STM32F4] IRQHandler


von Olli (Gast)


Lesenswert?

Hallo Leute,

folgendes Problem.
Ich habe einen funktionierenden IRQHandler in der main.c definiert.
Der Ordnung halber möchte ich diesen aber in die stm32f4xx_it.c
verfrachten.
Wenn ich ihn dorthin kopiere und in der stm32f4xx_it.h deklariere,
dann funktioniert es nicht mehr. Der Interrupt wird nicht mehr
ausgelöst.
Im Debug-Modus finde ich keinen Hinweis darauf warum.
Meine Entwicklungsumgebung ist Keil.

Hat einer von eine Idee was dahinterstecken könnte?

von ???????? (Gast)


Lesenswert?

Wie wäre es mit den Quellen?

von Stephan K. (nightowl)


Lesenswert?

Ich würde doch mal bei Keil nachfragen.
Bei den Preisen ist denen sicher an Kundenbindung gelegen.

von ???????? (Gast)


Lesenswert?

Stephan K. schrieb:
> Ich würde doch mal bei Keil nachfragen. Bei den Preisen ist denen
> sicher an Kundenbindung gelegen.

Die können auch nichts dafür, wenn er den kram nicht richtig zusammen 
packt. Es wird bestimmt aus einem anderen Verzeichnis etwas eingebunden. 
Er hat nur den Überblick verloren.

von Olli (Gast)


Lesenswert?

Stephan K. schrieb:
> Ich würde doch mal bei Keil nachfragen.
> Bei den Preisen ist denen sicher an Kundenbindung gelegen.
Bis 32kb Code ist Keil kostenlos, wenn man es nicht kommerziell
nutzen möchte.

???????? schrieb:
> Stephan K. schrieb:
>> Ich würde doch mal bei Keil nachfragen. Bei den Preisen ist denen
>> sicher an Kundenbindung gelegen.
>
> Die können auch nichts dafür, wenn er den kram nicht richtig zusammen
> packt. Es wird bestimmt aus einem anderen Verzeichnis etwas eingebunden.
> Er hat nur den Überblick verloren.
Erstaunlich, wie man einen Beitrag wieder sinnlos aufblähen kann.
Gerade wegen solcher sinnlosen Kommentare ist es immer schwer eine
Lösung zu finden, weil man sich erst durch Kommentare durcharbeiten
muss, die mit dem Thema nichts zu tun haben.

Zurück zum Thema:
Ich habe das Standalone-TCP-Ethernet-Example des STM32F4 Discoverys 
genommen,
dort einen USART hinzugefügt, der beim Empfang einen Interrupt auslöst.
Wie gesagt, funktioniert prima, wenn der IRQHandler in der main.c
definiert wird. Aber eben nicht mehr, wenn er in der stm32f4xx_it.c
und .h definiert/deklariert wird.
Ich habe nix "falsch eingebunden", denn ich habe dafür nichts 
eingebunden.

von ???????? (Gast)


Lesenswert?

Da du nichts falsch gemacht hast ist ja alles gut. Ist bestimmt ein 
Compiler bug. :-D :-D :-D

Deine  Selbstüberschätzung steht dir im weg.

von Olli (Gast)


Lesenswert?

???????? schrieb:
> Da du nichts falsch gemacht hast ist ja alles gut. Ist bestimmt
> ein
> Compiler bug. :-D :-D :-D
>
> Deine  Selbstüberschätzung steht dir im weg.
Hör gefälligst auf beleidigend zu werden.
Wenn Du keine Ahnung hast woran es liegen könnte,
das schreibe einfach nichts.
Vielleicht liegt es auch an Deiner Selbstüberschätzung, dass,
wenn Dir keine Lösung zum Thema einfällt, alle anderen
bescheuert sein müssen.
Aber, wenn Du so schlau bist und ich mich selbst überschätze
kannst Du mir ja sicherlich sagen was man alles falsch einbinden
kann, wenn man gar nichts eingebunden hat.
Wenn Du darauf keine Antwort hast, brauchst Du nicht zu antworten.

von ???????? (Gast)


Lesenswert?

Da du nichts zeigt, wird dir keiner helfen können. Aber glaube, du bist 
nicht der einzige, der c  code in mehrere Module teilt und per header 
veröffentlicht. Und glaube auch, dass du bei deiner Projekt Verwaltung 
ein paar Dateien durcheinander würfelst.

So einfach ist das. Also komm runter von deinem hohen Ross. Ach ja, ich 
habe nicht das Problem, sondern du. Ein bisschen mehr Freundlichkeit 
kann nicht schaden.

von Olli (Gast)


Lesenswert?

???????? schrieb:
> So einfach ist das. Also komm runter von deinem hohen Ross. Ach ja, ich
> habe nicht das Problem, sondern du. Ein bisschen mehr Freundlichkeit
> kann nicht schaden.
Dass Du in der Position bist, nicht das Problem zu haben
berechtigt Dich nicht, den Fragestellenden als dumm verkaufen
zu können oder zu beleidigen.
Wenn das Deine Art ist, brauchst Du auch keine Freundlichkeit zu
erwarten.

Was möchtest Du denn für Quellen haben?
Mein Projekt funktioniert im Grundzustand.
Die 3 Schritte, welche ich dann durchführe habe ich präzise beschrieben.

Aber gut, auch wenn Du meinst ich hätte etwas falsch eingestellt.
Hier die funktionierende main.c

Ich will einfach nur den IRQHandler in die stm32f4xx_it haben:

/* Includes 
------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_dma.h"
#include "misc.h"
#include "stm32f4x7_eth.h"
#include "netconf.h"
#include "tcp_echoserver.h"
#include <stdio.h>

/* Private typedef 
-----------------------------------------------------------*/
/* Private define 
------------------------------------------------------------*/
#define SYSTEMTICK_PERIOD_MS  10

/* Private macro 
-------------------------------------------------------------*/
/* Private variables 
---------------------------------------------------------*/
DMA_InitTypeDef DMA_InitStructure;
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

__IO uint32_t LocalTime = 0;
uint32_t timingdelay;

/* Private function prototypes 
-----------------------------------------------*/

/* Private functions 
---------------------------------------------------------*/
void GPIO_Configuration(void);
void USART_Configuration(void);
void NVIC_Configuration(void);
void DMA_Configuration(void);

int main(void)
{
  GPIO_Configuration();
  USART_Configuration();
  DMA_Configuration();
  NVIC_Configuration();

  /* configure ethernet (GPIOs, clocks, MAC, DMA) */
  ETH_BSP_Config();

  /* Initilaize the LwIP stack */
  LwIP_Init();

  /* Infinite loop */
  while (1)
  {
    /* check if any packet received */
    if (ETH_CheckFrameReceived()) {
      /* process received ethernet packet */
      LwIP_Pkt_Handle();
    }
    LwIP_Periodic_Handle(LocalTime);

  }
}

void GPIO_Configuration(void)
{
  /* ----------------------------------------------- */
  /* USART3-RS485, TX = PC10, RX = PC11, RTS = PB14  */
  /* ----------------------------------------------- */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3);
}

void USART_Configuration(void)
{
  /* ----------------------------------------------- */
  /* USART3-RS485, TX = PC10, RX = PC11, RTS = PB14  */
  /* ----------------------------------------------- */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

  USART_InitStructure.USART_BaudRate = 38400;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = 
USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
  USART_Init(USART3, &USART_InitStructure);

  USART_Cmd(USART3, ENABLE);
  USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
}

void DMA_Configuration(void)
{
  /* ----------------------------------------------- */
  /* USART3 Enable DMA clock */
  /* ----------------------------------------------- */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);

  DMA_DeInit(DMA1_Stream1);
  while (DMA_GetCmdStatus(DMA1_Stream1) != DISABLE);

  DMA_InitStructure.DMA_Channel = DMA_Channel_4;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&USART3_RX_Buffer;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 4;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = 
DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA1_Stream1, &DMA_InitStructure);

  DMA_ITConfig(DMA1_Stream1, DMA_IT_TC, ENABLE);

  DMA_Cmd(DMA1_Stream1, ENABLE);
  while (DMA_GetCmdStatus(DMA1_Stream1) != ENABLE);

}

void NVIC_Configuration(void)
{
  /* ----------------------------------------------- */
  /* USART3 RS232 */
  /* ----------------------------------------------- */
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void Delay(uint32_t nCount)
{
  /* Capture the current local time */
  timingdelay = LocalTime + nCount;

  /* wait until the desired delay finish */
  while (timingdelay > LocalTime);
}

void Time_Update(void)
{
  LocalTime += SYSTEMTICK_PERIOD_MS;
}

void DMA2_Stream1_IRQHandler(void)
{
  int i = 0;
  if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1))
  {
    DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);
    tcp_server_send(tcp_debug_pcb, (uint8_t*)USART6_RX_Buffer, 13);
  }
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line 
number
  *   where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and 
line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, 
line) */

  /* Infinite loop */
  while (1)
  {}
}
#endif


/*********** Portions COPYRIGHT 2012 Embest Tech. Co., Ltd.*****END OF 
FILE****/

von nfet (Gast)


Lesenswert?

Gehen andere interrupts?

Es hat mich mal fast 2h gekostet herauszufinden, dass ich die Datei in 
der der Interrupt stand nicht mit in meinen Makefile hatte. Nun hast du 
wahrscheinlich ja kein Makefile, sondern musst das ganze irgendwie zu 
deinem Projekt hinzufügen. Hast du dabei vielleicht irgendetwas falsch 
gemacht?

von Olli (Gast)


Lesenswert?

Ach entschuldigt der IRQHandler heißt bei mir:
void DMA2_Stream1_IRQHandler(void)
Das ist aber nicht der Fehler, habs nur eben falsch rauskopiert.

von Detlef K. (adenin)


Lesenswert?

Dein Fehler ist, das die IRQHandler bereits speziell deklariert sind.
Die darfst Du nicht nochmal deklarieren.

von Olli (Gast)


Lesenswert?

Detlef Kunz schrieb:
> Dein Fehler ist, das die IRQHandler bereits speziell deklariert
> sind.
> Die darfst Du nicht nochmal deklarieren.

Aber in der stm32f4xx_it.h werden doch auch die anderen Handler 
deklariert.
Wie muss ich es denn sonst machen?
Wenn ich die Deklaration aus der .h nehme geht es aber auch nicht.

von Olli (Gast)


Lesenswert?

nfet schrieb:
> Gehen andere interrupts?
>
> Es hat mich mal fast 2h gekostet herauszufinden, dass ich die Datei in
> der der Interrupt stand nicht mit in meinen Makefile hatte. Nun hast du
> wahrscheinlich ja kein Makefile, sondern musst das ganze irgendwie zu
> deinem Projekt hinzufügen. Hast du dabei vielleicht irgendetwas falsch
> gemacht?

Wie gesagt, ich benutze Keil.
Ich habe das Ethernet Example genommen und in der Main.c
die Funktionen:
void GPIO_Configuration(void);
void USART_Configuration(void);
void NVIC_Configuration(void);
void DMA_Configuration(void);
sowie den IRGHandler hinzugefügt.

Ich habe an den Projekteinstellungen nichts angefasst oder verändert.
Nur die main.c erweitert.

von Stephan K. (nightowl)


Lesenswert?

Kann es denn sein daß jetzt einfach die Reihenfolge in der die 
Deklarationen abgearbeitet werden eine andere ist, und deshalb Deine 
extern verschobene an anderer Stelle wieder neu deklariert wird?

Ich habe das mit Keil übrigen nicht böse gemeint, ich denke die würden 
sich auch gut um potentielle Kunden kümmern.

von Philipp (Gast)


Lesenswert?

wenn du den IRQHandler auslagerst, musst du doch auch die stm32f4xx_it.h 
einbinden oder?
In deinem Code oben finde ich davon zumindest nichts.

von Detlef K. (adenin)


Lesenswert?

Wo initalisierst Du USART6 und DMA2?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Olli schrieb:
> Ich habe an den Projekteinstellungen nichts angefasst oder verändert.

Das neue Modul muss natürlich auch hinzugefügt werden.

von Olli (Gast)


Lesenswert?

Detlef Kunz schrieb:
> Wo initalisierst Du USART6 und DMA2?
Mach ich nicht, ich benutze USART3 und DMA1

Philipp schrieb:
> wenn du den IRQHandler auslagerst, musst du doch auch die
> stm32f4xx_it.h
> einbinden oder?
> In deinem Code oben finde ich davon zumindest nichts.
Du hast Recht. Hab ich nun eingefügt.
Hat aber auch nicht zur Lösung geführt.

Johann L. schrieb:
> Olli schrieb:
>> Ich habe an den Projekteinstellungen nichts angefasst oder verändert.
>
> Das neue Modul muss natürlich auch hinzugefügt werden.
Was denn für ein neues Modul?
Falls Du die stm32f4xx_it.c/.h meinst, die war schon im Projekt mit 
drin.

von Detlef K. (adenin)


Lesenswert?

Olli schrieb:
> Detlef Kunz schrieb:
>> Wo initalisierst Du USART6 und DMA2?
> Mach ich nicht, ich benutze USART3 und DMA1


Ahja, und was soll dann das:

Olli schrieb:
> Ach entschuldigt der IRQHandler heißt bei mir:
> void DMA2_Stream1_IRQHandler(void)

und das:

Olli schrieb:
> void DMA2_Stream1_IRQHandler(void)
> {
>   int i = 0;
>   if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1))
>   {
>     DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);
>     tcp_server_send(tcp_debug_pcb, (uint8_t*)USART6_RX_Buffer, 13);
>   }
> }
>

Und wo ist der Handler für DMA1?

von Olli (Gast)


Lesenswert?

Detlef Kunz schrieb:
> Olli schrieb:
>> Detlef Kunz schrieb:
>>> Wo initalisierst Du USART6 und DMA2?
>> Mach ich nicht, ich benutze USART3 und DMA1
>
> Ahja, und was soll dann das:
>
> Olli schrieb:
>> Ach entschuldigt der IRQHandler heißt bei mir:
>> void DMA2_Stream1_IRQHandler(void)
>
> und das:
>
> Olli schrieb:
>> void DMA2_Stream1_IRQHandler(void)
>> {
>>   int i = 0;
>>   if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1))
>>   {
>>     DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);
>>     tcp_server_send(tcp_debug_pcb, (uint8_t*)USART6_RX_Buffer, 13);
>>   }
>> }
>>
>
> Und wo ist der Handler für DMA1?
Tut mir leid, war ein Fehler beim kopieren.
Dieser Handler ist nicht in Benutzung.
Das ist leider nicht der Fehler.

Hier ist der korrekte Handler:
void DMA1_Stream1_IRQHandler(void)
{
  if(DMA_GetITStatus(DMA1_Stream1, DMA_IT_TCIF1))
  {
    DMA_ClearITPendingBit(DMA1_Stream1, DMA_IT_TCIF1);
    while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
    USART_SendData(USART3, (uint16_t)USART3_RX_Buffer[i]);
    }
  }
}

von Detlef K. (adenin)


Lesenswert?

Olli schrieb:
> Tut mir leid, war ein Fehler beim kopieren.

Olli schrieb:
> Ach entschuldigt der IRQHandler heißt bei mir:
> void DMA2_Stream1_IRQHandler(void)
> Das ist aber nicht der Fehler, habs nur eben falsch rauskopiert.

Na klar doch.
Das übliche "Ich sehe was, was Du nicht siehst"-Spiel.

von ????????????????? (Gast)


Lesenswert?

Olli schrieb:
> Ich habe an den Projekteinstellungen nichts angefasst oder verändert.
> Nur die main.c erweitert.

Nur etwas nicht ändern reicht nicht. Man sollte schon wissen, was 
abgeht.

Die Datei stm32f4xx_it.c gibt es bestimmt mehrfach auf deiner 
Festplatte. Welche davon ist in das Projekt eingebunden?
Speicher die Datei unter einem anderen Namen, entferne die alte aus dem 
Projekt und binde die neue ein. Was passiert dann?

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.