STM32- Timerinterrupt

Gast #2629383
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
}
Gast #2629401
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.
Gast #2629423
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.
Gast #2629477
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)
Gast #2629508
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren