Forum: Mikrocontroller und Digitale Elektronik Timer CaptureCompare oder PWM beim Start alte Frequenz


von Mach F. (machfax)


Angehängte Dateien:

Lesenswert?

Hallo
Arbeite auf einem STM32G474, Timer20 auf PB2

Ich habe einen Timer, den ich als CaptureCompare mit toggle on match 
einsetzen möchte. Das Problem ist, dass nach jedem Stop und 
anschlissenden Start die alte Frequenz für eine Periode ausgeführt wird, 
sowohl wenn ich den Timer als PWM oder Capture Compare einsetze. Jemand 
eine Idee?

Der Code ist nur zu Testzwecken, darum ist er nicht sauber formatiert 
usw...
1
static bool btoggle = false;
2
            static uint16_t nTimerCounter = 0;
3
4
            if (btoggle) {
5
                HAL_TIM_OC_Stop_IT(&htim20, TIM_CHANNEL_1);
6
            } else {
7
                if (nTimerCounter == 50000)
8
                    nTimerCounter = 5000;
9
                else
10
                    nTimerCounter = 50000;
11
                
12
                __HAL_TIM_SetAutoreload(&htim20, nTimerCounter);
13
                __HAL_TIM_SET_COMPARE(&htim20, TIM_CHANNEL_1, nTimerCounter);
14
15
                __HAL_TIM_SetCounter (&htim20, 0);
16
                HAL_TIM_OC_Start_IT(&htim20, TIM_CHANNEL_1);
17
            }
18
            
19
            btoggle = !btoggle;

oder PWM
1
if (btoggle) {
2
                HAL_TIM_PWM_Stop_IT(&htim20, TIM_CHANNEL_1);
3
            } else {
4
                if (nTimerCounter == 50000)
5
                    nTimerCounter = 5000;
6
                else
7
                    nTimerCounter = 50000;
8
9
                __HAL_TIM_SetAutoreload(&htim20, nTimerCounter);
10
                __HAL_TIM_SET_COMPARE(&htim20, TIM_CHANNEL_1, nTimerCounter/2);
11
12
                __HAL_TIM_SetCounter (&htim20, 0);
13
                HAL_TIM_PWM_Start_IT(&htim20, TIM_CHANNEL_1);
14
            }
15
16
            btoggle = !btoggle;
17
18
            IN_ReleaseUnit.Event_RemoteMode(Event_RemoteMode_LidSeatTrigger);
19
            //TODO eud
20
            //IN_ReleaseUnit.Event_ControllerHardware(Event_ControllerHardware_ButtonOn);
21
        }

: Bearbeitet durch User
von Mach F. (machfax)


Angehängte Dateien:

Lesenswert?

Ich glaube es sieht danach aus, dass der Timer erst beim Erreichen des 
ursprünglichen Wertes auf den neu gesetzen Wert schaut und darauf 
reagiert. Muss der wirklich neu initialisiert werden dafür?
Im Anhnag der KO Plot der dieses Verhalten aufzeigt.

von Mach F. (machfax)


Lesenswert?

It's running now like expected, but I had to set the TIM_EGR_UG before 
starting. The problem now I face is when I turn off the timer with 
HAL_TIM_OC_Stop_IT(&htim20, TIM_CHANNEL_1);then the output Pin goes to 
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; and when in this moment 
the Ouput was high, it goes to the low state which I don't like, it 
should stay on the actual level on Stop.

I tried to reconfig the Timer in the IRQ but this is not working. Is 
this possible to do with the OutputCompare?
1
void setStepper_Timer(const uint16_t TimerCounter) {
2
3
    __HAL_TIM_SetAutoreload(&htim20, TimerCounter);
4
    __HAL_TIM_SetCompare(&htim20, TIM_CHANNEL_1, TimerCounter);
5
6
    //check if the timer is stopped
7
    if (TIM_CHANNEL_STATE_GET(&htim20, TIM_CHANNEL_1) == HAL_TIM_CHANNEL_STATE_READY) {
8
        __HAL_TIM_SetCounter(&htim20, 0);
9
10
        /* Generate an update event to reload the Prescaler
11
        and the repetition counter (only for advanced timer) value immediately */
12
        TIM20->EGR = TIM_EGR_UG;
13
14
        //start the timer
15
        HAL_TIM_OC_Start_IT(&htim20, TIM_CHANNEL_1);
16
    }
17
}
1
in the Timer IRQ:
2
void stopStepper_Timer(const bool bStop, const bool bSetState) {
3
    static bool bStopPending = false;
4
    static bool bPinLevel = false;
5
6
    TIM_OC_InitTypeDef sConfigOC = {0};
7
8
    //invert the PinLevelState
9
    bPinLevel = !bPinLevel;
10
11
    if (bSetState) {
12
        bStopPending = bStop;
13
    } else {
14
        if (bStopPending) {
15
/*
16
            //set the idle state according to the actual Output State on the PIN
17
            if (bPinLevel) {
18
                sConfigOC.OCIdleState = TIM_OCIDLESTATE_SET;
19
            } else {
20
                sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
21
            }
22
            sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
23
            sConfigOC.Pulse = 0;
24
            sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
25
            sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
26
            sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
27
            //sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
28
            sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
29
            if (HAL_TIM_OC_ConfigChannel(&htim20, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
30
                Error_Handler();
31
            }
32
*/
33
            HAL_TIM_OC_Stop_IT(&htim20, TIM_CHANNEL_1);
34
            bStopPending = false;
35
        }
36
    }
37
}
Danke

von Peter D. (peda)


Lesenswert?

Der Comparewert wird mit voller Absicht gelatcht. Würde man das nicht 
machen und einen kleineren Wert laden, müßte der Timer die ganz große 
Runde drehen, ehe er wieder durch 0 geht, d.h. es passiert erstmal 
gaaanz lange Zeit nichts.

von Mach F. (machfax)


Lesenswert?

Ok, danke. Funktioniert jetzt auch, aber ich habe jetzt das Problem, 
dass bei HAL_TIM_OC_Stop_IT der Pin auf TriState wechselt und nicht 
aktiv Low oder High entsprechend dem Init vom Timer bleibt. Ich habe 
versucht den Timer mit HAL_TIM_Base_Stop zu stoppen und den 
OutputCompare aktiv zu lassen, was aber auch nicht funktioniert. Geht 
dies überhaupt mit OutputCompare (aktiver Level bei Stop des Timers) und 
wenn ja, mit welcher HAL Funktion?

von Guido K. (Firma: Code Mercenaries GmbH) (thebug)


Lesenswert?

Schmeiß die HAL weg, das spart nicht nur eine Menge Speicher, sondern 
führt auch dazu, dass man sich damit auseinander setzt, wie die Teile 
wirklich funktionieren.
Die verschiedenen Timer haben teilweise recht unterscheidliche 
EIgenschaften, sind aber aufwärtskompatibel. Es gibt abhängig von der 
Timertype verschiedene Preload-Optionen, inklusive solcher für den 
Pinstatus.
Also HAL löschen, Reference Manual aufschlagen.

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.