Hallo zusammen,
ich habe ein Problem, die Registeradressen des STM32F413 zu verstehen:
Wenn ich zum Beispiel die Clock für den Timer2 freigeben möchte, muss
ich
das erste Bit im RCC_APB1ENR Register setzen.
Verfolge ich nun den ganzen Rattenschwanz der Adressen der HAL-
"__HAL_RCC_TIM2_CLK_ENABLE()", komme ich auf folgende Adresse:
__HAL_RCC_TIM2_CLK_ENABLE()---> SET_BIT(RCC->APB1ENR,
RCC_APB1ENR_TIM2EN)
wobei RCC = RCC_BASE = AHB1PERIPH_BASE + 0x3800U
und AHB1PERIPH_BASE =
PERIPH_BASE + 0x00020000U
und PERIPH_BASE =
0x40000000U
--> 0x40023840 |= 1;
Laut Reference:
Basis: 0x4000 0000 - 0x4000 03FF
Address offset: 0x40
--> 0x4000 0040 |= 1
Das liegt einfach daran, dass das RCC nicht zum Timer gehört.
RCC -> 0x4002 3800 - 0x4002 3BFF
TIM2 -> 0x4000 0000 - 0x4000 03FF
Das eine ist für die Clocks (und den Reset) zuständig, wärend das andere
für den Timer ist.
S. 117 -> Reset and clock control (RCC) for STM32F413/423
Die Cortex sind generell auf stromsparen eingestellt. Du musst alles,
was du brauchst, erst aktivieren. Und der Weg zum Timer führt über den
BUS, den AHB. Also BUS und Timer konfigurieren. So einfach ist das.
Hallo,
besten Dank für die Info.
Dann hätte ich noch eine Frage:
Wo versteckt ich beim STM32F413 das NVIC Register, um die Timer
Interrupts zuzulassen ? Auf Seite 252 im Reference habe ich ja die
Tabelle, aber wie soll das weitergehen ?
Das Register fehlt ja in der Beschreibung.
Heint schrieb:> Wo versteckt ich beim STM32F413 das NVIC Register, um die Timer> Interrupts zuzulassen ? Auf Seite 252 im Reference habe ich ja die> Tabelle, aber wie soll das weitergehen ?
Der NVIC ist nicht spezifisch für den STM32, sondern bei allen
Prozessoren der ARMv7-M Architektur vorhanden. Daher ist er im ARMv7M
Architecture Reference Manual dokumentiert, inkl. der Register. Das ist
übrigens sowieso ein sehr sinnvolles Dokument, das kann man mal
querlesen, insb. die Kapitel über Exceptions und eben NVIC.
https://developer.arm.com/products/architecture/cpu-architecture/m-profile/docs/ddi0403/latest
Besten Dank für die Antwort. Jetzt bin ich etwas weitergekommen.
Ich will hier keinen auf die Nerven gehen, aber würde mich freuen, wenn
sich jmd. mal den Code unten anschauen könnte.
Der TIM2_IRQHandler Aufruf geschieht übrigens in der stm32f4xx_it.c.
Dort musste ich den allerdings noch vorwärts deklarieren. Eigentlich
sollte der Aufruf doch von selbst bekannt sein ???
Stecke ich den TIM2_IRQHandler in der main.c wie jetzt unten gibt es
einen Compiler Fehler.
Leider funktioniert es egal wie nicht, so dass ich davon ausgehe, noch
etwas vergessen zu haben ?
Das direkte Ansprechen von GPIO Registern --> Pins funktioniert.
Habe ich der Übersichtlichkeit halber mal weggelassen.
•
Heint schrieb:> Stecke ich den TIM2_IRQHandler in der main.c wie jetzt unten gibt es> einen Compiler Fehler.
Welchen? Die Compiler geben nicht umsonst eine detaillierte Meldung aus.
Heint schrieb:> TM2_CR1 |= 1;
Wo ist das definiert?
Heint schrieb:> Leider funktioniert es egal wie nicht, so dass ich davon ausgehe, noch> etwas vergessen zu haben ?
Du musst die Interrupts überhaupt erstmal freigeben: __enable_irq ();
Du musst über das EGR noch manuell ein Update Event auslösen um den
Prescaler zu übernehmen. Im Debugger kann man übrigens sehen, ob der
Timer läuft.
Wenn ich das richtig sehe, verwendest Du die HAL; hier sind viele
Funktionen in der HAL als __weak deklariert. Das heisst, Du kannst die
dann einfach bei Dir in den eigenen Code tun und dann werden diese
anstelle des Leerkonstrukts aufgerufen.
Beispielsweise stm32fxxx_hal_tim.c:
Besten Dank, der Aufruf der TIM2 Interrupt Routine funktioniert nun.
Allerdings nur, wenn ich manuell ein Event auslöse.
Dann die ganze Zeit.
Der Counter läuft ansonsten immer über den TIM2_ARR Register drüber und
logischerweise wird kein IR ausgelöst.
Siehe Bild.
•
1
__TIM2_CLK_ENABLE();
2
RCC_APB1ENR|=1;//Enabler peripherial timer for timer 2