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
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!
Ruf doch einfach mal die HAL-Funktion zum Starten des Timers auf, statt das über Register zu machen. Vielleicht geht es dann oder du kriegst einen Fehler mit dem du was anfangen kannst
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 | }
|
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 | }
|
Das wichtigste dürfte das sein: "Hast du den Clock im RCC Register aktiviert?" Ist ein beliebter Fehler. Ist erstmal ungewohnt dass man wirklich jedes Stück Peripherie wirklich explizit erst einmal einschalten muss beim STM32.
Markus M. schrieb: > Ist ein beliebter Fehler. Ist erstmal ungewohnt dass man wirklich jedes > Stück Peripherie wirklich explizit erst einmal einschalten muss beim > STM32. Finde ich ein gutes Feature. Also noch folgende Zeile einfügen (ungefähr):
1 | RCC->AHBIRGENDWAS |= RCC_AHBIRGENDWAS _TIM6EN; |
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.
Hallo Gemeinde, danke für die Tipps. Ja richtig, das Starten hat fehlt. HAL_TIM_Base_Start_IT(&htim6); - fehlte HAL_TIM_PeriodElapsedCallback() wird jetzt aufgerufen. Werde aber auch "Bimbo. (Gast)" seine "gestraffte" Variante ausprobieren. Danke Runout
Thomas T. schrieb: > Werde aber auch "Bimbo. (Gast)" seine "gestraffte" Variante > ausprobieren. Diese habe ich wie gesagt nicht geprüft. Sollte aber funktionieren, nur folgende Zeile musst du selber anpassen:
1 | RCC->AHBIRGENDWAS |= RCC_AHBIRGENDWAS_TIM6EN; |
Wobei F_CPU = Taktfrequenz der Timers.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.
