if-Anweisung vermeiden



  • Hallo zusammen

    Ich bin neu hier und bin gerade dabei C zu lernen.
    Ich arbeite mich auch gleichzeitig in den uc stm32 ein.
    Ich würde gerne einen Parameter einer Fkt. übergeben, zB uint32t led1.
    Dabei ist zu erwähnen, dass für
    led1 der Kanal 2 des Timer 1 eingeschaltet werden muss und für led2 der Kanal 1, sprich:

    void Enable_led_x(uint32_t led_x)
    {
      if (led_x == 1)
      { 
       TIM1->CCER |= TIM_CCER_CC2E;                             /* Enable the Compare output channel 2 */  
      }
    
      if (led_x == 2)
      { 
       TIM1->CCER |= TIM_CCER_CC1E;                             /* Enable the Compare output channel 1 */
      }
    }
    

    Geht das auch ohne if's? Am schönsten wäre, wenn ich irgendwie die "Variablen" TIM_CCER_CC1E in die Funktion übergeben könnte, aber die versteht ja kein Mensch.. 🙄

    Ich wäre für Hilfe sehr dankbar



  • buell schrieb:

    Am schönsten wäre, wenn ich irgendwie die "Variablen" TIM_CCER_CC1E in die Funktion übergeben könnte, aber die versteht ja kein Mensch..

    Wie sind die denn definiert?

    Geht

    void Enable_led_x(uint32_t led)
    {
        TIM1->CCER |= led;                            
    } 
    
    .....
    
     Enable_led_x(TIM_CCER_CC2E);
    

    ?



  • Hallo Dirk

    Vielen Dank für deine Hilfe.

    DirkB schrieb:

    Wie sind die denn definiert?

    Das sind irgendwelche Defines von ST in einem header-file, die ich gerne nutzen würde.

    #define TIM_CCER_CC2E_Pos         (4U)                                         
    #define TIM_CCER_CC2E_Msk         (0x1U << TIM_CCER_CC2E_Pos)                  /*!< 0x00000010 */
    #define TIM_CCER_CC2E             TIM_CCER_CC2E_Msk                            /*!<Capture/Compare 2 output enable */
    

    Geht

    void Enable_led_x(uint32_t led)
    {
        TIM1->CCER |= led;                            
    } 
    
    .....
    
     Enable_led_x(TIM_CCER_CC2E);
    

    ?

    Das müsste gehen, aber das Problem ist, dass der User nicht weiss, was er da eingibt, weil der Name nicht aussagekräftig ist.
    Ich hätte irgendwie gerne, dass ich led1 eingebe und die Funktion automatisch

    TIM1->CCER |= TIM_CCER_CC2E;

    ausführt.

    Geht das irgendwie?
    Mein Problem ist, dass das eben Defines sind.

    Am liebsten wäre mir sowas wie ein Pointer zu übergeben (TIM1, TIM2 etc.), aber das geht ja nicht aufgrund der Defines.

    inline void Enable_Timerx_Counter(TIM_TypeDef* TIM_x)
    {
       TIM_x->CR1 |= TIM_CR1_CEN;
    }
    


  • Definiere dir ein Array:

    static uint32_t LedMasks[] = { 0, TIM_CCER_CC2E, TIM_CCER_CC1E };
    
    void Enable_led_x(uint32_t led_x)
    {
        TIM1->CCER |= LedMasks[led_x];
    }
    

    (und zusätzlich noch die Arraygrenzen überprüfen)



  • Du weisst schon, was

    TIM1->CCER |= TIM_CCER_CC2E;
    

    macht?

    Erkläre es mir einfach in weniger als drei Sätzen.



  • Th69 schrieb:

    Definiere dir ein Array:

    static uint32_t LedMasks[] = { 0, TIM_CCER_CC2E, TIM_CCER_CC1E };
    
    void Enable_led_x(uint32_t led_x)
    {
        TIM1->CCER |= LedMasks[led_x];
    }
    

    (und zusätzlich noch die Arraygrenzen überprüfen)

    Hallo

    Vielen Dank nochmals an alle

    Ich habe es nun folgend gelöst, finde ich eleganter.

    #define led1                                    TIM_CCER_CC2E
    #define led2                                    TIM_CCER_CC1E
    #define led3                                    TIM_CCER_CC3E
    #define led4                                    TIM_CCER_CC4E
    #define Trigger                                 TIM_CCER_CC5E
    
    inline void Enable_Read_Epc_x(uint32_t ledx)
    {   
       TIM1->CCER |= ledx;
    }
    


  • EOP schrieb:

    Du weisst schon, was

    TIM1->CCER |= TIM_CCER_CC2E;
    

    macht?

    Erkläre es mir einfach in weniger als drei Sätzen.

    Wen meinst du genau?



  • buell schrieb:

    EOP schrieb:

    Du weisst schon, was

    TIM1->CCER |= TIM_CCER_CC2E;
    

    macht?

    Erkläre es mir einfach in weniger als drei Sätzen.

    Wen meinst du genau?

    Du hast nur noch weniger als zwei Sätze übrig.



  • buell schrieb:

    EOP schrieb:

    Du weisst schon, was

    TIM1->CCER |= TIM_CCER_CC2E;
    

    macht?

    Erkläre es mir einfach in weniger als drei Sätzen.

    Wen meinst du genau?

    vergiss es - der Typ glänzt ständig mit besonders "lustigen" Kommentaren.
    Selten noch was sinnvolles von ihm gelesen.



  • buell schrieb:

    Ich habe es nun folgend gelöst, finde ich eleganter.

    Dein Code ignoriert jetzt komplett die Defines und macht etwas anderes -> das kann so nicht funktionieren!



  • vergiss es - der Typ glänzt ständig mit besonders "lustigen" Kommentaren.
    Selten noch was sinnvolles von ihm gelesen.

    Naja, er deutet aber auf ein Problem hin.

    Wenn man ein Bit setzt, so muss es auch ggf. wieder löschen.



  • fsdfsdfdsfd schrieb:

    vergiss es - der Typ glänzt ständig mit besonders "lustigen" Kommentaren.
    Selten noch was sinnvolles von ihm gelesen.

    Zum Glück gibt es auf der Welt noch so mutige, tapfere Männer, die zu feige sind ihre posts mit Klarnamen zu versehen. Shame on you.



  • Bitte ein Bit schrieb:

    ]Naja, er deutet aber auf ein Problem hin.

    Wenn man ein Bit setzt, so muss es auch ggf. wieder löschen.

    Danke für die Unterstützung. Meine Kommentare mögen nicht immer die Besten sein, aber einen Grund haben sie nach über 40 Jahren Programmiererfahrung schon.

    EDIT:
    Hab ich jetzt etwas daneben gelegen - es sind nur ca. 35 Jahre.



  • Die Funktion heißt doch Enable_led_x, also warum sollte man da ein Bit löschen wollen (dafür gibt es dann wahrscheinlich Disable_led_x oder so ähnlich)?

    Aber schade, daß buell sich hier nicht mehr meldet (denn, wie ich schon schrieb, kann sein zuletzt geposteter Code gar nicht richtig funktionieren).



  • Th69 schrieb:

    [...] (denn, wie ich schon schrieb, kann sein zuletzt geposteter Code gar nicht richtig funktionieren).

    Erklär bitte mal, warum.

    Ich seh es nicht. 😞



  • Sorry, jetzt verstehe ich seinen Code.
    Ich war noch davon ausgegangen, daß er 1 oder 2 als Parameter übergibt (wie in seinem Original-Code).
    Aber jetzt soll wohl der Aufruf so aussehen:

    Enable_Read_Epc_x(led1);
    

    Ich dachte er geht davon aus, daß wenn er z.B. 1 oder 2 als Parameter übergibt, dann einfach das passende Define genommen wird.



  • Puh...

    War schon überzeugt, dass ich komplett keine Ahnung habe und besser Gärtner werde... 😉



  • Die Funktion heißt doch Enable_led_x, also warum sollte man da ein Bit löschen wollen (dafür gibt es dann wahrscheinlich Disable_led_x oder so ähnlich)?

    Naja, wir befinden uns hier im Mikrocontroller Bereich und setzen das Timer Register. Und ein falsches Bit führt da manchmal gerne zu undefiniertem Verhalten oder Neustart.

    Wenn nun die erste Led eingeschaltet ist und ich aktiviere die zweite Led, so ist zumindestens für einige Takte der Timer auf "Compare output channel 1" und "Compare output channel 2" programmiert. Und ich frage mich ob sich das verträgt.

    Da hilft nur eins: Ein Blick ins die Prozessordokumentation.



  • Th69 schrieb:

    buell schrieb:

    Ich habe es nun folgend gelöst, finde ich eleganter.

    Dein Code ignoriert jetzt komplett die Defines und macht etwas anderes -> das kann so nicht funktionieren!

    Warum funktioniert das so nicht?
    Ich gebe nun einfach led1 ein, bei der Funktion und es ersetzt mir die Variable ledx mit led1, was dem define entspricht.
    Oder was meinst du genau?



  • Ja, ich hatte deinen Code falsch interpretiert, s. meinen letzten Beitrag.
    Schön ist dein Code trotzdem nicht (du solltest die Defines ersetzen durch Konstanten oder Enums).


Log in to reply