Forum: Mikrocontroller und Digitale Elektronik STM32f4 Timer Overflow Problem


von Marco (Gast)


Lesenswert?

Guten Tag zusammen

Ich schreibe gerade ein Lüfter Modul und brauche etwas Hilfe. Ich 
verwende TIM 1 als Aufwärtszähler um die fallende Flanke des Lüfter 
Tachosignals auszuwerten und somit die Drehzahl/Minute auszurechnen.

Die Init Funktion
/*---------------------------------------------------------------------- 
-------
 *        FAN 1-3, Timer 1, input capture initialization
 *----------------------------------------------------------------------- 
-----*/

void FAN_tachoTimInit(FAN_t * pThis)
{
    TIM_ClockConfigTypeDef sClockSourceConfig;
    TIM_MasterConfigTypeDef sMasterConfig;
    TIM_IC_InitTypeDef sConfigIC;

    pThis->hICtim.Init.Prescaler = 167;
    pThis->hICtim.Init.CounterMode = TIM_COUNTERMODE_UP;
    pThis->hICtim.Init.Period = 0xFFFF;
    pThis->hICtim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    pThis->hICtim.Init.RepetitionCounter = 0;
    HAL_TIM_Base_Init(&pThis->hICtim);

    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    HAL_TIM_ConfigClockSource(&pThis->hICtim, &sClockSourceConfig);

    HAL_TIM_IC_Init(&pThis->hICtim);

    sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    HAL_TIMEx_MasterConfigSynchronization(&pThis->hICtim, 
&sMasterConfig);

    sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
    sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
    sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
    sConfigIC.ICFilter = 0;
    HAL_TIM_IC_ConfigChannel(&pThis->hICtim, &sConfigIC, 
pThis->icChannel);
}

Der Regler Funktioniert soweit, das Problem ist, dass der Timer bei 
Überlauf folgende Funktion aufruft und eben nicht nur bei einer 
fallenden Flanke:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{

    if(htim->Instance==TIM1) {

        if(htim->Channel== HAL_TIM_ACTIVE_CHANNEL_1) {

            FAN_tacho_ISR(&fan1);
        }

        if(htim->Channel== HAL_TIM_ACTIVE_CHANNEL_2) {

            FAN_tacho_ISR(&fan2);
        }

        if(htim->Channel== HAL_TIM_ACTIVE_CHANNEL_3) {

            FAN_tacho_ISR(&fan3);
        }
    }
}

und mir somit den Timer in folgender Funktion resetet, ich also kein 
Timeout bei stehendem Lüfter bekomme:

void FAN_tacho_ISR(FAN_t *pThis)
{
    uint16_t icVal;

    icVal= __HAL_TIM_GetCompare(&pThis->hICtim, pThis->icChannel);
    if (icVal > pThis->lastICVal) {
        pThis->actualSteps=icVal-pThis->lastICVal;
    }  else if (icVal < pThis->lastICVal) {
        pThis->actualSteps  = ((0xFFFF - pThis->lastICVal) + icVal); // 
overflow protection
    }
    pThis->lastICVal=icVal;
    pThis->timer=FAN_TIMEOUT; // reset timer
}

TIM1 kann ich nicht rücksetzten, weil ich parallel die Geschwindigkeit 
der anderen Lüfter messe.

Gibt es einen rein event gesteuerten Interrupt, der also nicht bei 
overflow auslösst?

von W.S. (Gast)


Lesenswert?

Marco schrieb:
> HAL_TIM_Base_Init(&pThis->hICtim);

Solange du mit sowas herumprogrammierst, mußt du dich eben nach ST 
richten und was die nicht vorgesehen haben, eben auch nicht tun wollen.

Würdest du auf den ganzen Kram verzichten und deinen Code selber nach 
Maßgabe des RefManuals schreiben, dann hättest du solche Probleme auch 
nicht.

Immerhin kann man bei den Timern ganz ordentlich einstellen, was für 
Interrupts man haben will und was nicht. Die Timer-ISR schreibt man sich 
selber und irgend einen sinnvollen Platz für eine "generöse" ISR nebst 
ladbaren Callbacks sehe ich nirgendwo.

W.S.

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Kann w.s. nur zustimmen. Egal ob spl oder hal, beide libs eignen sich 
nur für gängige Problemstellungen.

Nachdem ich das gerafft hatte, habe ich angefangen eine eigene lib zu 
schreiben. Bei jeder neuen Aufgabenstellung muss man da zwar u.U. wieder 
handanlegen aber nach und nach entsteht so eine lib die "alles" kann was 
die Hardware hergibt.

von Marco (Gast)


Lesenswert?

Habe das Problem erkannt, nach dem anhängen des Oszi ist mir 
aufgefallen, dass das Tachosignal einen kurzen Peak beim Versuch wieder 
anzulaufen erzeugt hat.

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.