Forum: Mikrocontroller und Digitale Elektronik STM32 externer Interrupt funktioniert nicht immer!


von obamoa (Gast)


Lesenswert?

Hallo Experten!

Ich bin neu in der ARM-Welt. Zum Einstieg beschäftige ich mich mit dem 
Bsp. von ST.

Nun zum Problem:
Ich möchte gerne das EXTI Beispiel der STM32F10x Standard Peripheral Lib 
zum laufen bringen. Das Bsp. läuft auch, nur wird nicht in die ISR 
gesprungen. Wenn ich das Board von der Spannungversorgung trenne openOCD 
neustarte und das Bsp. auf den Controller lade und debugge funktioniert 
alles wunderbar (Breakpoint in der ISR wird erreicht). Stoppe ich aber 
die Ausführung und starte sie neu wird nicht mehr in die ISR gesprungen.


Ich verwende das STM32-LCD Board von Olimex (STM32-F103ZE) zum Debugen 
verwende ich den ARM-USB-OCD mit OpenOCD. Als Entwicklungsumbebung ist 
das IAR - Kickstart V 6.0 im Einsatz.

Ich habe keine Ahnung wo der Fehler liegt, zumal ich 1:1 das ST Beispiel 
verwende.

Währe Dankbar für jeden Hinweis/Hilfe!

von Matthias K. (matthiask)


Lesenswert?

obamoa schrieb:
> Ich habe keine Ahnung wo der Fehler liegt, zumal ich 1:1 das ST Beispiel
> verwende.

Wirklich 1:1?

Richtiges Startup und Linkerscript für den ZE?

von obamoa (Gast)


Lesenswert?

In IAR habe ich die das Projekt STM3210E-EVAL eingestellt damit wird der 
Startup startup_stm32f10x_hd.s verwendet. Ist das so nicht Richtig?

Bezüglich des Linkerscripts weis ich nicht wo ich schauen soll. Ist das 
nicht richtig voreingestellt?

Bin eben noch recht neu.

von Matthias K. (matthiask)


Lesenswert?

_hd sollte passen.

Kenne IAR nicht genau, weiß nicht wie es dort mit den 
Linker-Einstellungen geht.

Hat denn Dein Testboard die selbe Portbelegung wie das im Demo 
verwendete STM EVAL-Board?

Eigentlich laufen die Demos der STM-Lib. Das Exti habe ich auch schon 
als Vorlage (mit Modifikationen) in einem Projekt verwendet, klappte. 
Damals war die LIB 3.3.0. Jetzt ist 3.5.0 aktuell.

von obamoa (Gast)


Lesenswert?

Ich habe zum Testen einen Schalter und einen externen Pullup an den 
PortG.8 angeschlossen. Der Schalter zieht mir den Pin gegen Masse. Habe 
das auch mit einem Oszi überprüft. Das müsste passen. Es funktioniert ja 
auch nach dem die Versorgungsspannung getrennt und wieder verbunden 
wurde und OpenOCD neu gestartet wurde. Nur bei erneuter Ausführung nicht 
mehr.

PS: ich verwende die Lib V.3.4.0

von Matthias K. (matthiask)


Lesenswert?

Ziemliches Rätselraten!

Liegt das Programm auch im Flash und nicht im RAM?

von obamoa (Gast)


Lesenswert?

> Liegt das Programm auch im Flash und nicht im RAM?
unter Projekt-Optionen->Debugger->Downloads ist das Häckchen bei Use 
Flashloader gesetzt.

> Ziemliches Rätselraten!
ich weis, ich bin auch am verzweifeln!

von Matthias K. (matthiask)


Lesenswert?

Das Demo geht von einen konfigurierten System aus. Probiers mal so 
(getestet habe ich es nicht) PA0.0 im BSP. verwendet:
1
#include <stddef.h>
2
#include "stm32f10x.h"
3
4
volatile uint8_t  my_EXTI = 0;
5
6
//***********************************************************************************************
7
// System-Einstellungen
8
//***********************************************************************************************
9
void SetupSystem (void) {
10
GPIO_InitTypeDef  GPIO_InitStructure;
11
12
  RCC_DeInit ();                        // RCC System Reset(for debug purpose)
13
14
  // Enable HSE (Umschaltung auf externen Quarz)
15
  RCC_HSEConfig (RCC_HSE_ON);
16
17
  // HSE-Umschaltung abwarten
18
  while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
19
20
  // System-Taktung
21
  RCC_HCLKConfig   (RCC_SYSCLK_Div1);   // HCLK   = SYSCLK
22
  RCC_PCLK2Config  (RCC_HCLK_Div1);     // PCLK2 (APB2) = HCLK
23
  RCC_PCLK1Config  (RCC_HCLK_Div2);     // PCLK1 (APB1) = HCLK/2
24
  RCC_ADCCLKConfig (RCC_PCLK2_Div6);    // ADCCLK = PCLK2/6
25
26
  // FLASH-Speicher Zugriff
27
  FLASH_SetLatency(FLASH_Latency_2);                        // Flash - 2 wait states
28
  FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);     // Pipeline freigeben
29
30
  // PLL Konfiguration
31
  // PLLCLK = 8MHz * 9 = 72 MHz
32
  RCC_PLLConfig (RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);     // Externer Quarz, Faktor 9
33
  RCC_PLLCmd (ENABLE);                                      // Enable PLL
34
35
  // PLL-Konfiguration abwarten
36
  while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
37
38
  // PLL als System-Takt auswählen
39
  RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK);
40
41
  // PLL-Umschaltung abwarten
42
  while (RCC_GetSYSCLKSource() != 0x08);
43
44
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // GPIO A Takt freigeben
45
46
  /* Configure PA.00 pin as input PULL-UP */
47
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
48
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
49
  GPIO_Init(GPIOA, &GPIO_InitStructure);
50
51
  /* Connect EXTI0 Line to PA.00 pin */
52
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
53
}
54
55
//***********************************************************************************************
56
// Nested Vectored Interrupt Controller initialisieren
57
//***********************************************************************************************
58
void NVIC_Configuration (void) {
59
  NVIC_InitTypeDef NVIC_InitStructure;
60
  EXTI_InitTypeDef EXTI_InitStructure;
61
62
  EXTI_DeInit();
63
64
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); // FLASH Vector Table
65
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // Pre = 2 Bit / Sub = 2 Bit
66
67
  /* Configure EXTI0 line */
68
  EXTI_InitStructure.EXTI_Line = EXTI_Line0;
69
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
70
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  
71
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
72
  EXTI_Init(&EXTI_InitStructure);
73
74
  /* Enable and set EXTI0 Interrupt to the lowest priority */
75
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
76
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
77
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
78
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
79
  NVIC_Init(&NVIC_InitStructure);
80
}
81
82
83
// sollte ins stm32f10x_it.c
84
extern volatile uint8_t  my_EXTI;
85
void EXTI0_IRQHandler(void)
86
{
87
  if(EXTI_GetITStatus(EXTI_Line0) != RESET)
88
  {
89
    my_EXTI = 1;
90
91
    /* Clear the  EXTI line 0 pending bit */
92
    EXTI_ClearITPendingBit(EXTI_Line0);
93
  }
94
}
95
96
97
// MAIN
98
main...
99
100
SetupSystem();
101
NVIC_Configuration(): 
102
while(1) {
103
104
  if (my_EXTI) {
105
   // mach was , LED toggle oder so
106
   // Pause
107
   my_EXTI = 0;
108
  }
109
110
}

von obamoa (Gast)


Lesenswert?

Funktioniert leider nicht. Im Bsp steht das der Controller in dem 
Startupfile konfiguriert wird.

Eins ist mir noch aufgefallen: da zugehörige Bit im EXTI Pending 
register wird bei richtig gesetzt (im Bsp. bei fallender Flanke). Er 
erkennt also das Interruptereignis, nur springt er nicht in die ISR.

von Matthias K. (matthiask)


Lesenswert?

Gehen denn andere Interrupts? Lass beispielsweise einfach mal den 
SysTick mit passender ISR laufen.
1
 // SysTick aktivieren
2
  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);          // SysTick Takt von HCLK (voller Systemtakt)
3
  SysTick_Config(SystemCoreClock / 100);                    // Wiederholrate 10ms, Interrupt-Handle freigeben
4
5
6
// sollte ins stm32f10x_it.c
7
// wird aller 10ms aufgerufen (bei 72MHz)
8
void SysTick_Handler(void)
9
{
10
  // Mach was, Pin toggeln oder Variable hochzählen
11
}

von obamoa (Gast)


Lesenswert?

> Gehen denn andere Interrupts?
Scheinbar nicht! hab es eben mal versucht. Es tut sich nichts.

Ich habe jetzt leider keine Zeit mehr weiter zu forschen. Werde Morgen 
wieder mein Glück versuchen.

von obamoa (Gast)


Lesenswert?

Ich habe jetzt einen neuen Beitrag aufgemacht (mit jetzt passenderen 
Titel):

[Beitrag "STM32 Interrupts funktionieren nicht!"]

von Tomasz (Gast)


Lesenswert?

AFIO Takt hast du Freigegeben??
Ich sehe in deiner RCC
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
daß nur Port GPIOA getaktet ist und AFIO nicht...

Vielleicht geht es so:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, 
ENABLE);

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.