STM32 Timer6 - nervt

#5792912
Lesenswert?

Hallo Gemeinde,

ich möchte einen "einfachen" 16-bitTimer (TIM6) in Betrieb nehmen.
Target ist STM32L496.
Er soll einen 4kHz-Interrupt erzeugen.

Das Teil läuft ein nicht los.

Weder mit HAL-Gedöns:
  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 11999;0,25ms
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 1;
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  HAL_TIM_Base_Init(&htim6)

noch mit Schhreiben in die Register ()

  TIM6->PSC = 47999;
  TIM6->ARR = ms;
  TIM6->CR1 |= TIM_CR1_CEN;
  while (!(TIM6->SR & TIM_SR_UIF));

Ich frage im SysTick mit "__HAL_TIM_GET_COUNTER(&htim6);"
den Counterwert ab. Leider immer = 0.

Habe ich im Clocck-Tree noch irgendwas vergessen?
Wird der Timer-Clock von "HSI48 RC" hergenommen.
Arbeite jetzt mal die AN4776 von ST durch.

Der Timer 6 sollte für sowas Einfaches doch geeignet sein
oder müssen es "full-features"-Timer sein.

Grüße
Runout
Angehängte Dateien:
Gast #5792922
Lesenswert?

Was ist deine Clk Frequency für die Timer Perihperie? Vermeide Magic 
Numbers! Hast du den Clock im RCC Register aktiviert?
1
TIM6->PSC = F_CLK_VOM_TIMER / DEINEFREQUENZ - 1; 
2
TIM6->ARR = 0xffff;
3
TIM6->CR1 |= TIM_CR1_CEN;
4
//while (!(TIM6->SR & TIM_SR_UIF)); //Was soll das hier?

Hast du anschließend den NVIC parametriert? Und dran denken, im 
Interrupt das UIF per Software zurückzusetzen. Zusätzlich sehe keine 
Registeranweisung um den Überlaufinterrupt zu aktivieren!
Gast #5792925
Lesenswert?

Try this, ohne Gewähr dass es funktioniert:
1
voi initTIM6(){
2
  #define SET_ICPR(a) NVIC->ICPR[(a)/32] |= (1<<((a)%32));
3
  #define SET_ISER(a) NVIC->ISER[(a)/32] |= (1<<((a)%32));
4
  #define SET_IP(a,b) NVIC->IP[(a)/4] |= ((b<<4)<<(8*((a)%4)));
5
  TIM6->PSC = F_CPU / 4000 - 1;
6
  TIM6->ARR = 0xffff;  //Timer für Bildwiederholrate
7
  TIM6->DIER |= TIM_DIER_UIE;        //OVF Interrupt enable
8
  TIM6->CR1 |= TIM_CR1_CEN;        //Timer 3 aktivieren
9
  SET_ICPR(TIM6_IRQn);
10
  SET_ISER(TIM6_IRQn);
11
  SET_IP(TIM6_IRQn, 1);
12
}
13

14
void TIM6_IRQHandler(){
15
  TIM6->SR &= ~TIM_SR_UIF;
16
  //Geiler Scheiss hier
17
}
Gast #5792931
Lesenswert?

Korrektur:
1
#define SET_ICPR(a) NVIC->ICPR[(a)/32] |= (1<<((a)%32));
2
#define SET_ISER(a) NVIC->ISER[(a)/32] |= (1<<((a)%32));
3
#define SET_IP(a,b) NVIC->IP[(a)/4] |= ((b<<4)<<(8*((a)%4)));
4

5
void initTIM6(){
6
  //TIM6->PSC = F_CPU / 4000 - 1;
7
  TIM6->ARR = F_CPU / 4000 - 1;  
8
  TIM6->DIER |= TIM_DIER_UIE;        
9
  TIM6->CR1 |= TIM_CR1_CEN;       
10
  SET_ICPR(TIM6_IRQn);
11
  SET_ISER(TIM6_IRQn);
12
  SET_IP(TIM6_IRQn, 1);
13
}
14

15
void TIM6_IRQHandler(){
16
  TIM6->SR &= ~TIM_SR_UIF;
17
  //Geiler Scheiss hier
18
}
#5792988
Lesenswert?

mit HAL Gedöns sollte es klappen. Am einfachsten, wenn du cubeMX das 
machen lässt.

bei mir generiert CubeMX
static void MX_TIM6_Init(void)
{

  TIM_MasterConfigTypeDef sMasterConfig;

  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 0;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 200;
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
  {
    _Error_Handler(_FILE_, _LINE_);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != 
HAL_OK)
  {
    _Error_Handler(_FILE_, _LINE_);
  }

}
und im *it.c file auch gleich die IRQ routine.

Du setzt den Prescaler ziemlich hoch, so dass .25 ms Zählrate rate 
rauskommen, dann die Period auf 1. Das dürfte nicht zum gewünschten 
Ergebnis führen. Warum nicht umgedreht?

vielleicht brauchst Du auch noch 
HAL_TIMEx_MasterConfigSynchronization(), der Timer6 ist irgendwie mit 
dem DAC verheiratet.

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