Ändern Sie die PWM-Frequenz dynamisch mit Interrupt mit STM32

Ich verwende einen STM32F4, um einen Schrittmotor zu steuern.

Ich bin mir nicht sicher, ob ich den PWM-Modus oder den OC-Modus oder den OnePulse-Modus benötige. Ich kann eine PWM-Welle mit fester Frequenz erzeugen, aber da ich eine bestimmte Beschleunigung/Verzögerung benötige, muss ich die Frequenz der Welle mit einer Rampe variieren.

So etwas wie: ein Impuls bei 745 Hz; ein Impuls bei 1867 Hz; ein Impuls bei 2459 Hz; ein Impuls bei ...; ein Impuls bei ...; N Impulse bei ... (konstante Drehzahl)

HAL_TIM_PWM_PulseFinishedCallbackIm Moment gebe ich im Rückruf neue TIMx->ARRund TIMx->CCR1Werte basierend auf einer bestimmten Logik aus.

Hier ist mein Code:

void MX_TIM9_Init(void)
{
TIM_OC_InitTypeDef sConfigOC;

htim9.Instance = TIM9;
htim9.Init.Prescaler = PSC; // Get clock to <freq> Hz
htim9.Init.CounterMode = TIM_COUNTERMODE_UP;
htim9.Init.Period = 1582; // useless since it is varying
htim9.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim9);
HAL_TIM_PWM_Init(&htim9);

sConfigOC.OCMode = TIM_OCMODE_PWM2;
sConfigOC.Pulse = htim9.Init.Period / 2; //useless but always 50% of CCR1
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
HAL_TIM_PWM_ConfigChannel(&htim9, &sConfigOC, TIM_CHANNEL_1);

}

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef* htim){
if (htim->Instance == TIM9){
    // logic
    TIM9->ARR = v;
    TIM9->CCR1 = v/2;
}
}

int main(void) {
//other
MX_TIM9_Init();

//logic and if needed
HAL_TIM_PWM_Start_IT(&m->htim, TIM_CHANNEL_1);
}

Was mir auffällt, ist, dass der Wellenzug nicht perfekt geformt ist, als ob das Update-Ereignis, das das Schattenregister aktualisiert, sporadisch auftritt. Wenn ich einen Puls mit 500 Hz und einen zweiten mit 700 Hz erwarte, passiert das nicht. Eindeutig wird eine konstante Frequenzwelle bei 500 Hz und 700 Hz korrekt erzeugt. Ich habe versucht, einen Ausgang SET-RESET, um zu überprüfen, an welcher Stelle der Interrupt aufgerufen wird.

Wenn dies fehlschlägt, scheint ein Interrupt aufgerufen zu werden, wenn die PWM immer noch "hoch" ist.

Ist PWM der richtige Weg oder sollte ich den OC- oder OnePulse-Modus verwenden?

Vielleicht sollte @Community ein "Kopfgeld" starten, um die Person zu jagen, die ihre eigene Antwort am Tag nach der Beantwortung ihrer eigenen Frage nicht akzeptiert hat

Antworten (2)

Sie können die Frequenz mit TIMx->PSC im laufenden Betrieb ändern

Hallo, dies ist fast eine Antwort, sollte aber angeben, dass ein Wert in dieses Register geschrieben werden muss, und ein wenig erläutern, wie dies seinen Anforderungen entspricht. Das Ändern des Vorteilers (allein) erfüllt möglicherweise nicht die tatsächlichen Frequenzanforderungen. Auch die minimale Impulsbreite fehlt. Es kann also eine Mischung aus mehreren Einstellungen sein.
Hi, ich bin davon ausgegangen, dass andere Sachen schon geschrieben sind. Benötigen Sie auf jeden Fall eine Variable für TIMx-> PSC = nnn und einen Arbeitszyklus.

Das Problem hing mit den Preload-Registern zusammen. Wie in en.DM00236305.pdf erwähnt, werden sie benötigt, um ein perfektes Timing zwischen UEV und korrekter Registerladung zu haben

Ich schlage vor, dass Sie Ihr korrigiertes Programm in der Antwort korrigieren, damit es anderen Benutzern wirklich helfen kann.