Forum: Mikrocontroller und Digitale Elektronik STM32- Timerinterrupt


von LBubble (Gast)


Lesenswert?

Guten Morgen
Ich arbeite mich gerade in den STM32 ein, und habe bei dem Timer ein 
paar Probleme.
Das Programm unten soll folgendes tun:
1.) Blinklicht: LED1 ein, warten, LED1 aus, warten, LED2 ein, warten,
    LED2 aus. Wieder von vorne, LED1 ein, ...
2.) Bei Timer-Interrupt (alle 5s) beide LEDs einschalten, etwas länger
    leuchten lassen, und wieder in den Betrieb von 1.) wechseln.

Punkt eins ist kein Problem.
Bei zwei gehts schon nicht mehr.


Daher meine Fragen:

Woher bekomm ich den Namen für die ISR? Momentan hab ich einfach die 
Bezeichnung aus einem Beispielprogramm von keil übernommen.

Woher bekomm ich den Wert für den Timer2 (oder irgendeine andere 
Interruptquelle) für das NVIC_ISER - Register? Das es ISER[0] sein muss, 
weiß ich ja aus der Interruptnummer aus dem reference manual. Aber 
welches Set-enable bit von ISER[0] muss ich setzen?
Hier hab ich auch einfach mal "TIM2_IRQChannel" aus dem Beispielprogramm 
übernommen, konnte allerdings kein entsprechendes #define finden.

Gibt es irgendetwas Grundlegendes, dass ich hier übersehe?

Den Configuration Wizard möchte ich ungern verwenden, dann weiß ich ja 
erst nicht, was da vor sich geht.

1
#include <stm32f10x_lib.h>                    // STM32F10x Library Definitions
2
3
int irupt=0;
4
5
6
void syti_wait(void)
7
{
8
  while( (SysTick->CTRL & 0x10000 ) == 0 ){}
9
}
10
11
12
void TIM2_UP_IRQHandler (void) {
13
14
  if ((TIM2->SR & 0x0001) != 0)                       // check interrupt source
15
   {
16
    irupt=1;
17
      TIM2->SR &= ~(1<<0);                            // clear UIF flag
18
  }
19
} // end TIM1_UP_IRQHandler
20
21
22
int main (void)
23
{   
24
  unsigned short n;
25
26
  RCC->APB2ENR |= 0x4;                               // Port A mit Takt versorgen
27
  GPIOA->ODR |= 0x22;                                // PA5,PA1:    Output
28
29
  RCC->APB1ENR |= 0x01;                              // Timer 2 mit Takt versorgen
30
  
31
  // TIM2 Control Register
32
  // ARPE:
33
  // CMS: Edge-aligned mode           (reset value, nicht extra zu setzen)
34
  // DIR: upcounter               (reset value, nicht extra zu setzen)
35
  // OPM: 1, one pulse mode
36
  // URS: 1, only overflow/underflow generates an update interrupt
37
  // UDIS: UEV enabled             (reset value, nicht extra zu setzen)
38
  // CEN: Counter Enable, nach Bedarf setzen (OPM ist aktiviert!!!)
39
//  TIM2->CR1 |= (1<<3);                              // OPM setzen
40
  TIM2->CR1 |= (1<<2);                                // URS
41
  
42
  // TIM2 Prescaler
43
  // delta_t_Timer: 1ms -> f_Timer: 1000 Herz = 1MHz
44
  // f_APD : 72MHz (36MHz * 2)
45
  // => reload = 72MHz / 1MHz = 72
46
  //    72 - 1 = 71  TIM2->PSC = 71;
47
  TIM2->PSC = 71;
48
  
49
  // TIM2 Counter Value
50
  TIM2->CNT = 0;
51
52
  // TIM2 Auto Reload Value
53
  // 50.000 * 1/1000s = 5s
54
  TIM2->ARR = 50000;
55
56
  // INTERRUPT KONFIGURATION
57
  // TIM2-Interrupt: Interrupt Nr. 28 (Aus Vector Table, S. 197 reference manual)
58
  // CMSIS Mapping: ISER[0], ICER[0], ISPR[0], ICPR[0], IABR[0]: CMSIS (Cortex-M3 programming manual)
59
  NVIC->ISER[0] |= (1 << TIM2_IRQChannel);
60
61
  TIM2->CR1 |= 0x01;
62
63
64
65
  SysTick->CTRL |= 0x4;                           // SysTick aktivieren
66
  SysTick->LOAD = 800000;                 
67
  SysTick->CTRL |= 0x1;                           // SysTick starten
68
69
  for(n=0; n<1000; n++)
70
  {
71
    if (irupt==0)                                // Falls kein Timer-Interrupt
72
    {
73
      GPIOA->CRL = 0x44344444;          // LED1 an PA5 an: Output, Push-Pull, 50MHz
74
      syti_wait();
75
            
76
      GPIOA->CRL = 0x44444444;          // LED1 aus, Port resetten.
77
      syti_wait();
78
    
79
      GPIOA->CRL = 0x44444434;          // LED2 an PA1 an: Output, Push-Pull, 50MHz
80
      syti_wait();
81
            
82
      GPIOA->CRL = 0x44444444;          // LED2 aus, Port resetten.
83
      syti_wait();
84
    }
85
    else
86
    {
87
      GPIOA->CRL = 0x44344434;          // LED1 & LED2 an
88
      syti_wait();                      // Warten
89
      syti_wait();
90
      syti_wait();
91
      syti_wait();
92
      syti_wait();
93
      syti_wait();
94
            
95
      GPIOA->CRL = 0x44444444;          // LED1  & LED2 aus
96
      syti_wait();
97
      irupt=0;      
98
    }
99
  }
100
  SysTick->CTRL &= 0x0;                // SysTick stoppen
101
  while(1);
102
}

von Noname (Gast)


Lesenswert?

>Gibt es irgendetwas Grundlegendes, dass ich hier übersehe?

Die Standard Peipheral Library enthält Header Files in denen die 
Control-Bits definiert sind. Der enthaltene Beispielcode zeigt Dir auch 
wie Du sie verwendest. Du kannst natürlich mit diesen Konstanten 
weiterhin selbst die Peripherieeinheiten konfigurieren wie Du es schon 
tust.


Ich habe mir die Namen der ISRs aus einer der Startdateien herausgesucht 
in der auch die Vektortabelle gesetzt wird. Weiß leider gerade nicht 
welche.

von LBubble (Gast)


Lesenswert?

Noname schrieb:
> Du kannst natürlich mit diesen Konstanten
> weiterhin selbst die Peripherieeinheiten konfigurieren wie Du es schon
> tust.

Nö, tu ich ja nur zwangsweiße, weil ich die Werte nicht kenne.

Wühl mich mal durch.
Danke für den Tipp.

von Noname (Gast)


Lesenswert?

>Nö, tu ich ja nur zwangsweiße, weil ich die Werte nicht kenne.

Kommt mir vor wie ein Missverständnis. Schau Dir den Beispielcode in der 
SPL an. Dann siehst Du vielleicht was ich meine.
Dort werden Hilfsfunktionen zur Konfiguration der Peripherie benutzt. 
Diese benutzen symbolische Konstanten (defines).

Du kannst nun in Deinem Code auch diese defines verwenden ohne jedoch 
die von der Library bereitgestellten Funktionen zu verwenden. D.h. Deine 
Code bliebe bis auf die Literale identisch.

Du musst das nicht tun. Aber da Du Deinen Code so angefangen hast, hatte 
ich angemommen Du hattest dabei eine Absicht. Deswegen meine Bemerkung.

von LBubble (Gast)


Lesenswert?

Noname schrieb:
> Du musst das nicht tun. Aber da Du Deinen Code so angefangen hast, hatte
> ich angemommen Du hattest dabei eine Absicht. Deswegen meine Bemerkung.´

Die symbolischen Konstanten stehen nur deshalb drin, weil ich es nicht 
besser wusste ;-).

Die ISRs hab ich hier gefunden:
1
stm32f10x_it.h
2
...
3
* Description        : This file contains the headers of the interrupt handlers.
4
...

1
void TIM2_UP_IRQHandler (void)
Aus meinem Code oben wird damit zu
1
void TIM2_IRQHandler (void)

von LBubble (Gast)


Lesenswert?

defines der IRQChannels in stm32f10x_nvic.h

von Noname (Gast)


Lesenswert?

>Die symbolischen Konstanten stehen nur deshalb drin, weil ich es nicht
>besser wusste ;-).

Hm. Ich glaube wir verstehen uns nicht. Vor allem wird es schlimmer, :-) 
Du hast keine symbolischen Konstanten dastehen, sondern Literale .

>> Du musst das nicht tun. Aber da Du Deinen Code so angefangen hast, hatte
>> ich angemommen Du hattest dabei eine Absicht.

Du hattest anscheinend gar keine "Absicht" sondern einfach gar keine 
Wahl der Mittel, wie ich nun zu verstehen meine. Das konnte ich nicht 
wissen, denn die Verwendung von
1
#include <stm32f10x_lib.h>                    // STM32F10x Library Definitions
legte nahe, das Du im Prinzip weisst, was Du tust.

Ich gehe aber im Moment davon aus, das die Frage nicht weiter von 
Bedeutung ist. Bzw. das Problem wird erneut auftauchen. Also lassen wir 
es hier erstmal ruhen, denke ich.

von LBubble (Gast)


Lesenswert?

Noname schrieb:
> Du hattest anscheinend gar keine "Absicht" sondern einfach gar keine
> Wahl der Mittel, wie ich nun zu verstehen meine.

Das trifft den Nagel auf den Kopf ;-)

von LBubble (Gast)


Lesenswert?

Ich könnte k...

Was ich vergessen hatte, war das Interrupt enable bit in TIM2_DIER zu 
setzen.

Naja, der Prescaler passt wohl auch noch nicht.

Aber der Interrupt kommt jetzt.

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.