Timer2 stm32f107vc

OP #2279287
Lesenswert?

Guten Tag zusammen!


Ich arbeite mit dem STM32F107VC, uVision von Keil

Ich möchte mit dem Timer2 arbeiten, habe ihn als downcounter 
eingestellt. Bei underflow möchte ich einen Interrupt auslösen.

Das Problem ist, dass bei jedem Zählschritt ein Event, also ein 
Interrupt ausgelöst wird! Habe aber das 2 Bit von CR2 gesetzt:

Bit 2 URS: Update request source:   1: Only counter overflow/underflow 
generates an update interrupt or DMA request if enabled.
1
// Timer2
2

3
    TIM2    ->  CR1     =   0x0000001C;//
4
    TIM2    ->  CR2     =   0x00000000;//CONTROLLREG2;                     // Reset Controllregister 2
5
    TIM2    ->  PSC     =   0x00000000;//PRESCALE;                         // Prescaler
6
    TIM2    ->  ARR     =   0x0000FFFF;//AUTORELOAD;                       // Auto-Reload Register
7
    TIM2    ->  CCMR1   =   0x00000000;//COMPAREMODREG1;                   // Compare Mode Register 1  Outputcompare Mode
8
    TIM2    ->  CCMR2   =   0x00000000;//COMPAREMODREG2;                   // Compare Mode Register 2  Output Compare 1 Mode; Output Compare 2 Mode 
9
    TIM2    ->  CCER    =   0x00000000;//COMPAREENABLEREG;                 // Compare Enable Register; Compare 1 Output Enable; Compare 2 Output Enable
10
    TIM2    ->  SMCR    =   0x00000000;//SLAVEMODECONTROLLREG;             // Slave Mode Controll Register
11
    TIM2    ->  CCR1    =   0x00000000;//COMPAREREG1;                      // Compare Register 1
12
    TIM2    ->  CCR2    =   0x00000000;//COMPAREREG2;                      // Compare Register 2
13
    TIM2    ->  SR      =   0x00000000;//STATUSREG;                        // Status Register: Interrupt Flagbits
14
    TIM2    ->  DIER    =   0x00000001;//INTERRUPTENABLEREG;               // Interrupt Enable Register: Interrupt Compare 1 und Compare 2 enable
15
    TIM2    ->  EGR     =   0x00000000;//EVENTGENERATREG;                  // Event Generator Register: Update generation; Compare 1 Generation / Compare 2 Generation 
16
    TIM2    ->  BDTR    =   0x00000000;//BRAKDEATTIMEREG;                  // Lock off, break inputs disable

Was habe ich übersehen oder weis jemand, was falsch ist??

Vielen dank und Gruss!
OP #2280006
Lesenswert?

Warum wird nicht erst bei underflow ein Interrupt ausgelöst? Seltsam ist 
auch, dass egal welchen Wert ich ins PSC oder ins ARR lade, der 
Interrupt jede 1us ausgelöst wird!? die Register sind doch richtig 
eingestellt, warum funktioniert das nicht??


Vielen Dank und Gruss!!

M. B.
OP #2280134
Lesenswert?

1
void TIM2_IRQHandler(void)
2
{
3

4
    if(TIM2 ->  SR & (1 << 0))
5
    {
6

7
        TIM2 ->  SR |= (1 << 0);
8
    
9
        GPIOE   ->  BSRR    |=   (1 << 8);                     // AD-Wert an Port E ausgeben
10
        GPIOE   ->  BSRR    |=  0xFF000000;
11
    
12
    }
13

14
}

Ja, so sollte es gehen. Mache das auch bei anderen Interrupts so!

Danke und Gruss!

M.B.
#2280311
Lesenswert?

M. B. schrieb:
1
TIM2    ->  SR |= (1 << 0);
>
> dieser Befehl sollte das Statusbit doch löschen??

Was kommt denn Raus, wenn du z.b. 0xFF mit 0x00 bitweise oder 
verknüpfst? :)

Mit einem "oder" kannst du nichts löschen, nur setzen.

das löschen des Bits solltest du mal so probieren
1
TIM2    ->  SR &= ~(1 << 0);

Wobei ich jetzt nicht nachgesehen habe, ob das Bit (hier Bit 0) das 
richtige ist.
#2280327
Lesenswert?

Hier die Variante mit der FW-Lib, kannst ggf. mal in den entsprechenden 
Routinen dort nachsehen:
1
//***********************************************************************************************
2
// Timer 2 Interrupt-Handler
3
//***********************************************************************************************
4
void TIM2_IRQHandler(void) {
5
  if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
6
    // Überlauf des Zählregisters
7
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
8
  }
9
}
#2280330
Lesenswert?

M. B. schrieb:

> dieser Befehl sollte das Statusbit doch löschen??

Nicht jeder Controller löscht Interrupt-Flags indem man sie setzt. 
Manche zwar schon, aber verallgemeinern lässt sich das nicht.

Abgesehen von der Code/Kommentar-Schere in
> GPIOE   ->  BSRR    |=   (1 << 8);      // AD-Wert an Port E ausgeben
> GPIOE   ->  BSRR    |=  0xFF000000;
kann man einen AD-Wert beispielsweise auch eleganter ausgeben, hier mal 
für 12 Bits auf GPIOE0..11
  GPIOE->BSRR = (0x0FFF << 16+0) | (value & 0x0FFF) << 0;
Was speziell in einer ISR etliche Takte einspart.

Das BSRR zu erst lesen ist schon vom Ansatz her sinnfrei und überdies 
auch nicht vorgesehen.

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