Forum: Mikrocontroller und Digitale Elektronik STM32F411 Timer-IR -> falsche Zykluszeit


von Tom W. (nericoh)


Lesenswert?

Hallo zusammen,

vermutlich sehe ich gerade den Wald vor lauter Bäumen nicht, daher hier 
mein Hilferuf - vllt. sieht ja jemand auf die Schnelle, was ich 
vergessen habe.

Ich möchte auf dem STM32F411 mit dem Timer11 einen zyklischen Interrupt 
auslösen. Das gelingt auch grundsätzlich, ich habe aber bei der 
Zykluszeit einen Faktor zwei drin, den ich nicht nachvollziehen kann.

Code:
1
char Toggle = 0;
2
void TIM1_TRG_COM_TIM11_IRQHandler(void)
3
{
4
  TIM11->SR   = 0;                           /* clear Timer 11 IRQ */
5
6
  if(Toggle == 0)
7
  {
8
    Toggle = 1;
9
    GPIOD->ODR &= ~GPIO_ODR_ODR_13;
10
  }
11
  else
12
  {
13
    Toggle = 0;
14
    GPIOD->ODR |= GPIO_ODR_ODR_13;
15
  }
16
17
}
18
19
#define CYCLE_250US             (250-1)
20
#define TIMER_PRESCALER_DIV_100 (100-1)
21
int main(void)
22
{
23
  int i = 0;
24
25
  RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
26
  GPIOD->MODER |= GPIO_MODER_MODER13_0;     /* PD13 as output */
27
28
  /* Clock für Timer 11 einschalten */
29
  RCC->APB2ENR |= RCC_APB2ENR_TIM11EN;
30
31
  TIM11->DIER   = 0;                         /* Timer Interrupts disablen */
32
  TIM11->CR1    = 0;                         /* On-Pulse-Mode OFF, Update Enabled, Counter Disabled */
33
  TIM11->CR2    = 0;                         /* Master-Mode OFF */
34
  TIM11->SMCR   = 0;                         /* Slave-Mode Disabled */
35
36
  TIM11->ARR    = CYCLE_250US;               /* 250us cycletime */
37
  TIM11->PSC    = TIMER_PRESCALER_DIV_100;   /* PCLK = 100MHz -> Rescaler = 100 -> Timer-Tick = 1us */
38
  TIM11->EGR   |= TIM_EGR_UG;                /* Update-Event auslösen, Prescaler-Wert übernehmen */
39
  TIM11->EGR    = 0;
40
41
  TIM11->SR     = 0;                         /* Clear Timer11 Interrupts  */
42
  TIM11->DIER  |= TIM_DIER_UIE;              /* Update Interrupt enabled */
43
44
  /* Timer11 IRQ im NVIC aktivieren */
45
  NVIC_SetPriority(TIM1_TRG_COM_TIM11_IRQn, 0);
46
  NVIC_ClearPendingIRQ(TIM1_TRG_COM_TIM11_IRQn);
47
  NVIC_EnableIRQ(TIM1_TRG_COM_TIM11_IRQn);
48
49
  /* globale IRQ Freigabe */
50
  __enable_irq();
51
52
  TIM11->CR1 |= TIM_CR1_CEN;             /* Timer 11 starten */
53
}
54
55
void SysInit_setClkSrcXTAL(void)
56
{
57
    /* Enable HSE */
58
    RCC->CR |= RCC_CR_HSEON;
59
60
    /* Wait till HSE is ready and if Time out is reached exit */
61
    while(0 == (RCC->CR & RCC_CR_HSERDY)){;}
62
63
  /* Disable HSI */
64
    RCC->CR &= ~RCC_CR_HSION;
65
66
    /* HSE as PLL src*/
67
    RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSE;
68
69
    /* divide PLL input by 4 -> 2 MHz */
70
    RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM_4;
71
    RCC->PLLCFGR |= RCC_PLLCFGR_PLLM_2;
72
73
    /* multiple with 50 -> 100MHz */
74
    RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN;
75
    RCC->PLLCFGR |= (50<<6);
76
77
    /* Enable PLL */
78
    RCC->CR |= RCC_CR_PLLON;
79
80
    /* Wait till PLL is ready */
81
    while(0 == (RCC_CR_PLLRDY & RCC->CR)) {;}
82
83
    /* set flash wait states to 3 (see ...) */
84
    FLASH->ACR |= FLASH_ACR_LATENCY_3WS;
85
86
    /* Select PLL as system clock source */
87
    RCC->CFGR &= ~RCC_CFGR_SW;
88
    RCC->CFGR |= RCC_CFGR_SW_PLL;
89
90
    /* Wait till PLL is used as system clock source */
91
    while (RCC_CFGR_SWS_PLL != (RCC_CFGR_SWS & RCC->CFGR)) {;}
92
93
    /* PLLCK to MCO1 */
94
    //RCC->CFGR     |= (RCC_CFGR_MCO1_1 | RCC_CFGR_MCO1_0);
95
    //RCC->AHB1ENR  |= RCC_AHB1ENR_GPIOAEN;
96
    //GPIOA->AFR[1] |= 0;
97
    //GPIOA->MODER  |= GPIO_MODER_MODER8_1;
98
}
99
100
void SystemInit(void)
101
{
102
  /* FPU settings ------------------------------------------------------------*/
103
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
104
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
105
  #endif
106
  /* Reset the RCC clock configuration to the default reset state ------------*/
107
  /* Set HSION bit */
108
  RCC->CR |= (uint32_t)0x00000001;
109
110
  /* Reset CFGR register */
111
  RCC->CFGR = 0x00000000;
112
113
  /* Reset HSEON, CSSON and PLLON bits */
114
  RCC->CR &= (uint32_t)0xFEF6FFFF;
115
116
  /* Reset PLLCFGR register */
117
  RCC->PLLCFGR = 0x24003010;
118
119
  /* Reset HSEBYP bit */
120
  RCC->CR &= (uint32_t)0xFFFBFFFF;
121
122
  /* Disable all interrupts */
123
  RCC->CIR = 0x00000000;
124
125
  SysInit_setClkSrcXTAL();
126
127
#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
128
  SystemInit_ExtMemCtl(); 
129
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
130
131
  /* Configure the Vector Table location add offset address ------------------*/
132
#ifdef VECT_TAB_SRAM
133
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
134
#else
135
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
136
#endif
137
}

Angeschlossen an HSO ist ein 8MHz Quarz - die 8MHz sehe ich auch 
wunderbar, wenn ich sie mir an MCO1 ausgeben lassen.

Ich sehe PD13 alle 500us togglen - nicht wie eigentlich gedacht alle 
250us. Was übersehe ich?

Danke und Gruß
Tom

edit: hab das Problem gefunden: der PLL-Clk wird anschließend nochmal 
durch "P" (vgl. Manual) heruntergeteilt. P hat zwar bei mir den Wert 00 
- dies entspricht jedoch nicht wie von mir angenommen keiner Teilung, 
sondern einer Teilung durch 2...

von Johnny B. (johnnyb)


Lesenswert?

Als erstes würde ich mal in "int main(void)" am Schluss eine 
Endlosschleife einfügen, denn ohne ist meines Wissens nicht definiert 
was der uC genau macht, weil es unzulässig ist.

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.