STM32F413 Registernamen

Gast #5562199
Lesenswert?

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
#5562248
Lesenswert?

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
Gast #5562669
Lesenswert?

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.
Gast #5563074
Lesenswert?

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.
Gast #5563083
Lesenswert?

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
Gast #5563162
Lesenswert?

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.



•
1
#include "main.h"
2

3
//Timer Register
4
#define TIM2_CR1       (*((volatile uint32_t *) 0x40000000u))   
5
#define TIM2_PSC       (*((volatile uint32_t *) 0x40000028u))
6
#define TIM2_ARR       (*((volatile uint32_t *) 0x4000002Cu))
7
#define TIM2_DIER      (*((volatile uint32_t *) 0x4000000Cu))
8

9
//Interrupt Register
10
#define NVIC_ISER0     (*((volatile uint32_t *) 0xE000E100u))
11

12
//Peripherie Register
13
#define RCC_APB1ENR    (*((volatile uint32_t *) 0x40000040u))
14

15

16

17
int main(void)
18
{
19
  HAL_Init();
20

21
  RCC_APB1ENR |= 1;         //Enabler peripherial timer for timer 2
22
  
23
  NVIC_ISER0 |= 0x10000000; //Enable Interrupt Timer 2
24
  
25
  TIM2_CR1 |= 0x0080;       //Bit 7 ARPE: Auto-reload preload enable
26
  TIM2_PSC = 499;           //Prescaler 499
27
  TIM2_ARR = 15999;         //Auto Reload Register ARR is the value to be loaded in the actual auto-reload register.
28
  TIM2_CR1 |= 1;             //Enable Timer 2
29
  TIM2_DIER |= 1;           //Enable Timer 2 update interrupt enable
30
  TIM2_DIER |= (1 << 6 );   //Enable Timer 2 trigger interrupt enable
31

32
  while(1)
33
  {
34
  }
35
  return 0;
36
}
37

38

39

40
 void TIM2_IRQHandler(void)
41
{
42
  TM2_CR1 |= 1;
43
  //Toggle Pin o.ä
44
}
Gast #5563169
Lesenswert?

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.
#5563244
Lesenswert?

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:
1
__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
2
{
3
  /* Prevent unused argument(s) compilation warning */
4
  UNUSED(htim);
5

6
  /* NOTE : This function Should not be modified, when the callback is needed,
7
            the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file
8
   */
9
  
10
}
Gast #5563423
Lesenswert?

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
3
  
4
    NVIC_ISER0 |= 0x10000000; //Enable Interrupt Timer 2
5
  
6
    TIM2_CR1 |= 0x0080;       //Bit 7 ARPE: Auto-reload preload enable
7
    TIM2_PSC = 499;           //Prescaler 499
8
    TIM2_ARR = 15999;         //Auto Reload Register ARR is the value to be loaded in the actual auto-reload register.
9
    
10
    TIM2_DIER |= 1;           //Enable Timer 2 update interrupt enable
11
    TIM2_DIER |= (1 << 6 );   //Enable Timer 2 trigger interrupt enable
12
    //TIM2_EGR  |= (1 << 6 );   // manuelles Update Event
13

14
    TIM2_CR1 |= 1;             //Enable Timer 2

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