Forum: Mikrocontroller und Digitale Elektronik STM32: Timer als Funktionsparameter übergeben


von Mitch (Gast)


Lesenswert?

Hallo Freunde,

ich versuche mit Hilfe von CMSIS einen Timer als Funktionsparameter zu 
übergeben. Der Aufruf sollte also wie folgt aussehen:

timer_einstellen(TIM17);

Kann mir bitte jemand auf die Sprünge helfen, wie man dazu die Funktion 
deklariert?

In dieser Form funktioniert es leider nicht:

void timer_einstellen((TIM_TypeDef *) timer)
{

  ...Code

}

von Dr. Sommer (Gast)


Lesenswert?

Mitch schrieb:
> void timer_einstellen((TIM_TypeDef *) timer)
Die Klammern müssen natürlich weg:
1
void timer_einstellen(TIM_TypeDef* timer) {

Aber ingesamt ist das mit der SPL/CMSIS leider sehr kompliziert, denn du 
musst ja zur Initialisierung auch den Bus kennen (APB1/APB2), den Index 
des Bits im RCC_APB*ENR, die Interrupt-Nummer (IRQn), ... und die kannst 
du nicht aus deinem "timer" Parameter berechnen, sondern musst alle 
seperat übergeben.

von Mitch (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Die Klammern müssen natürlich weg:
> void timer_einstellen(TIM_TypeDef* timer) {

aaaaaaa, Danke!!!

Dr. Sommer schrieb:
> Aber ingesamt ist das mit der SPL/CMSIS leider sehr kompliziert, denn du
> musst ja zur Initialisierung auch den Bus kennen (APB1/APB2), den Index
> des Bits im RCC_APB*ENR, die Interrupt-Nummer (IRQn), ... und die kannst
> du nicht aus deinem "timer" Parameter berechnen, sondern musst alle
> seperat übergeben.

Ich verwende den STM32F051, dieser hat zum Glück nicht so viele 
Möglichkeiten. Somit kann ich die UNterscheidungen in der Funktion 
unterbringen.

von Jim M. (turboj)


Lesenswert?

Dr. Sommer schrieb:
> und die kannst
> du nicht aus deinem "timer" Parameter berechnen

Doch das geht, ist aber nicht grade schön:
1
void timer_einstellen(TIM_TypeDef* timer) {
2
3
uint32_t timerBase=(uint32_t timer);
4
5
switch(timerBase){
6
  case TIMER_1_BASE: ; 
7
//...
8
9
  case TIMER_7_BASE:  ;
10
  }
11
}

Die TIMER_X_Base Konstanten kann man sich aus den entsprechenden Headern 
rauspfriemeln.

von Gerd E. (robberknight)


Lesenswert?

Das ist doch ziemlich unschön: die Funktionsdeklaration suggeriert daß 
sie unabhängig vom konkret verwendeten Timer funktioniert. Das 
switch/case hinterher macht aber ziemlich das Gegenteil davon.

Da sollte mindestens eine kleine Abstraktionsschicht dazwischen. Du 
könntest z.B. ein enum für die Timer definieren und diesen enum dann an 
die Funktion übergeben. Da wird dem Leser des Codes wenigstens sofort 
klar daß da in der Funktion irgendwo ne Unterscheidung anhand der enums 
gemacht wird und man das für einen anderen µC das evtl. etwas anpassen 
muss.

von Stefan K. (stefan64)


Lesenswert?

Ich habe für jede Hardware-Ressource ein struct definiert, in dem alle 
Parameter enthalten sind, die die entsprechende Ressource benötigt. Die 
wird dann der Init-Routine übergeben.

Als Beispiel mal ein Uart. In dem struct werden nicht nur die 
zugehörigen IO-Pins definiert, sondern auch die verwendeten DMA Kanäle:
1
typedef struct{
2
    USART_TypeDef*          Uart;               // a.e. UART4  or USART1
3
4
    int                     DmaRxStreamNr;      // a.e. 2
5
    DMA_Stream_TypeDef*     DmaRxStream;        // a.e. DMA1_Stream2
6
    uint32_t                DmaRxChannel;       // a.e. DMA_CHANNEL_4
7
8
    int                     DmaTxStreamNr;      // a.e. 2
9
    DMA_Stream_TypeDef*     DmaTxStream;        // a.e. DMA1_Stream4
10
    uint32_t                DmaTxChannel;       // a.e. DMA_CHANNEL_4
11
12
    IRQn_Type               IRQnRx;             // a.e. DMA1_Stream2_IRQn
13
    uint32_t                IRQnRxPrio;         // a.e. 0..15   0 = high
14
    uint32_t                IRQnRxSubPrio;      // a.e. 0..15   0 = high
15
16
    IRQn_Type               IRQnTx;             // a.e. DMA1_Stream4_IRQn
17
    uint32_t                IRQnTxPrio;         // a.e. 0..15   0 = high
18
    uint32_t                IRQnTxSubPrio;      // a.e. 0..15   0 = high
19
20
    IRQn_Type               IRQnTcTx;           // a.e. Uart TC IRQ
21
    uint32_t                IRQnTcTxPrio;       // a.e. 0..15   0 = high
22
    uint32_t                IRQnTcTxSubPrio;    // a.e. 0..15   0 = high
23
24
    GPIO_TypeDef*           GpioRxPort;         // a.e. GPIOA
25
    uint32_t                GpioRxAfPinMapping; // a.e. GPIO_AF_UART4
26
    uint32_t                GpioRxPin;          // a.e. 1
27
28
    GPIO_TypeDef*           GpioTxPort;         // a.e. GPIOA
29
    uint32_t                GpioTxAfPinMapping; // a.e. GPIO_AF_UART4
30
    uint32_t                GpioTxPin;          // a.e. 0
31
32
} USART_ConfigurationTypeDef;

Diese struct lege ich für jede Hardware Komonente einmal konstant an.

Gruß, Stefan

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.