Forum: Mikrocontroller und Digitale Elektronik STM32f1xx, Problem mit dem Timerinterrupt


von Mike (Gast)


Lesenswert?

Hallo,

ich arbeite mich gerade in das Thema STM32 ein. Nach erfolgreichen 
Versuchen mit den GPIO hänge ich nun an den Timern.

Ich habe mir das Notwendigste aus den Datenblättern und dem RM0008 
zusammen gesucht, aber ich erhalte keinen Einsprung in den 
Interrupthandler, wenn der Timer einen Overflow-Flag setzt.

Vielleicht könntet Ihr mir erklären:

1. wass ich alles bei einem Timer (oder generell bei Interrupts) beim 
STM32 beachten muss
2. Welche Registereinträge hier am Beispiel wirklich relevant sind
3. Ob ich einen ausglösten Interrupt aktiv wieder auflösen muss, oder ob 
die Hardware das macht
4. Warum das alles so unübersichtlich dokumentiert sein muss... :)

Ein Code-Beispiel: Timer 3 soll über einen Prescaler bis zu einem 
ARR-Wert zählen, dann einen Overflow setzen und über den 
Interrupthandler die LED PC8 auf meinem ST32-Discoveryboard blinken 
lassen. Soweit, so gut...


#include "stm32f10x.h"

void Tim3_Init ()
{

  RCC->APB1ENR        |= (1 << 1);
  TIM3->PSC        = 12000;
  TIM3->ARR        = 1000;
  TIM3->CR1        |= (1 << 0);
  TIM3->DIER        |= (1 << 0);
}

void TIM3_IRQHandler()
{
  GPIOC->ODR        ^= (1 << 8);
}

int main(void)
{
  Tim3_Init();
   RCC->APB2ENR        |= (1 << 2) | (1 << 3) | (1 << 4);
  GPIOC->CRL        = 0x33333333;
  while (1);
}

Das macht dieses Programm aber leider nicht.

Ich wäre über einen Tipp sehr dankbar!

Mit Gruß

Mike
von fdssd (Gast)


Lesenswert?

bei den ARMs müssen die IRQs in den NVIC eingrtrasgen werden

ebenso in der ISR der Interrupt bestätigt und rückgesetzt werden

in den CMSIS gibts dazu die NVIC tabelle
von fdssd (Gast)


Lesenswert?

achso .. oder du nutzt die meiner meinung nach etwas überladene LIB ^^
von RP6Conrad (Gast)


Lesenswert?

Ich benutze die Standard Lib von STM32. Da sind auch sehr fiele 
Beispielen in diesen Lib für EVAL-Boards von STM32. Mit kleine 
Anpassungen laufen die auch auf das Discovery board.
Algemein bei Timer :
Muss die Clock von jeden Timer separat eingeschaltet werden.
Muss die GPIO als AF (Alternate function) angegeven werden.
Muss den Timer "Enabled werden"
Muss den Interrupt frei geschaltet werden (NVIC). Beispiel ohne 
Interrupt und ohne GPIO_init :
[c]
void Timer_Config(void)
{
    /* 
-----------------------------------------------------------------------
    TIM1 Configuration: generate 2 PWM signals with 2 different duty 
cycles:
    TIM1CLK = 24 MHz, Prescaler = 23, TIM1 counter clock = 1 MHz
    TIM1 ARR Register = 19999=> TIM1 Frequency = TIM1 counter clock/(ARR 
+ 1)
    TIM1 Frequency = 50 Hz.
    TIM1 Channel1 pulse lenght = TIM1->CCR1 value gives servo between 
1000 and 2000 µs
    TIM1 Channel4 pulse lenght = TIM1->CCR4 value gives servo between 
1000 and 2000 µs
  ----------------------------------------------------------------------- 
*/
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  /* Time base configuration TIM1*/
  TIM_TimeBaseStructure.TIM_Period = 19999;//PWM freq. = 1MHz/20000 = 
50Hz
  TIM_TimeBaseStructure.TIM_Prescaler = 23;// Timer loopt aan 24 MHz/24 
= 1MHz
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
  /* PWM1 Mode configuration: TIM 1, Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
  /* PWM1 Mode configuration: TIM 1, Channel4 */
  TIM_OC4Init(TIM1, &TIM_OCInitStructure);
  TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
von fdssd (Gast)


Lesenswert?

ich versuchs mal nur auf einen timer zu reduzieren:

kein plan ob es geht


Ich arbeite mit den NXP typen
da geht der Timer mit nem 2zeiler
finde die lib von ST aber iwie zu krank ...

1
void TIM2_IRQHandler(void)
2
{
3
  /* Clear TIM2 update interrupt */
4
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
5
6
// wackel mit der LED
7
8
}
9
10
11
int main(void)
12
{
13
 
14
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
15
  TIM_OCInitTypeDef  TIM_OCInitStructure;
16
  NVIC_InitTypeDef  NVIC_InitStructure;
17
18
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
19
20
  TIM_TimeBaseStructure.TIM_Period = 0x95F;    
21
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
22
23
  TIM_PrescalerConfig(TIM2, ((SystemCoreClock/1200) - 1),  TIM_PSCReloadMode_Immediate);
24
25
  TIM_ClearFlag(TIM2, TIM_FLAG_Update);
26
27
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
28
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
29
  NVIC_Init(&NVIC_InitStructure);
30
31
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
32
  TIM_Cmd(TIM2, ENABLE);
33
34
  while (1)
35
  { 
36
  }
37
}
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.