Cambie dinámicamente la frecuencia PWM con interrupción con STM32

Estoy usando un STM32F4 para controlar un motor paso a paso.

No estoy seguro si necesito el modo PWM, el modo OC o el modo OnePulse. Puedo generar una onda PWM de frecuencia fija pero como necesito una aceleración/desaceleración particular, necesito variar la frecuencia de la onda con una rampa.

Algo así como: un pulso a 745 Hz; un pulso a 1867 Hz; un pulso a 2459 Hz; un pulso en ...; un pulso en ...; N pulsos a ... (velocidad constante)

En este momento, en la devolución de llamada HAL_TIM_PWM_PulseFinishedCallback, estoy emitiendo valores nuevos TIMx->ARRy TIMx->CCR1basados ​​en una lógica dada.

Aquí está mi código:

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);
}

Lo que estoy notando es que el tren de ondas no tiene una forma perfecta, como si el evento de actualización que actualiza el registro de sombra ocurriera esporádicamente. Si estoy esperando un pulso con 500 Hz y un segundo de 700 Hz, eso no sucede. Claramente, una onda de frecuencia constante a 500 Hz y 700 Hz se genera correctamente. Traté de SET-RESET una salida para verificar en qué punto se llama a la interrupción.

Cuando falla, parece que se llama a una interrupción cuando el PWM todavía está "alto".

¿Es el PWM la forma correcta de hacerlo o debo usar el modo OC o OnePulse?

tal vez @Community debería iniciar una "recompensa" para cazar a la persona que no aceptó su propia respuesta el día después de que respondió a su propia pregunta

Respuestas (2)

Puede cambiar la frecuencia sobre la marcha con TIMx->PSC

Hola, esto es casi una respuesta, pero debería indicar que se debe escribir un valor en este registro y explicar un poco cómo satisface sus necesidades. Es posible que cambiar el prescaler (solo) no cumpla con los requisitos de frecuencia reales. También falta el ancho de pulso mínimo. Así que puede ser una mezcla entre varias configuraciones.
Hola, supuse que otras cosas ya están escritas. Absolutamente, necesita una variable para TIMx->PSC=nnn y ciclo de trabajo.

El problema estaba relacionado con los registros de precarga. Como se menciona en en.DM00236305.pdf, son necesarios para tener una sincronización perfecta entre UEV y registrar la carga correcta

Le sugiero que corrija su programa corregido en la respuesta para que realmente pueda ayudar a otros usuarios.