cancel
Showing results for 
Search instead for 
Did you mean: 

ARR and CCR update time

Massimiliano Gilli
Associate II
Posted on June 24, 2017 at 12:51

I need to vary the frequency and duty cycle of a pwm using stm32f Inside the 'pulse finished' pwm callback i've tried the following code

HAL_GPIO_WritePin(LED5_PORT, LED5_PIN, GPIO_PIN_RESET); //tentative 1 //TIM9->ARR = round(value); //TIM9->CCR1 = round(value) * 0.2; //tentative 2 //htim9.Instance->ARR = round(value); //htim9.Instance->CCR1 = round(value) * 0.2; //tentative 3 int *point = (int *) (TIM9_BASE + 0x2C); *point = round(value); int *point1 = (int *) (TIM9_BASE + 0x34); *point1 = round(value) *0.2; HAL_GPIO_WritePin(LED5_PORT, LED5_PIN, GPIO_PIN_SET); 

In all the 3 cases if i measure with an oscilloscope the amount of time that passes between the ON/OFF state of the LED5 the value is 6us. The ON/OFF state alone is 500ns.

I get the Update event thing and it is not a problem but this means that i'm waiting 5.5us for my function to return just for assigning those two register and so i'm limited in term of performance.

It is clear that i have a problem which im not seeing.

Any ideas?

Regards

#pwm #stm32f4 #register #register-access
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on June 24, 2017 at 13:42

round(value) *0.2

This is a double-precision floating point operation, resulting probably in library call and significant computing.

JW

View solution in original post

3 REPLIES 3
Posted on June 24, 2017 at 13:42

round(value) *0.2

This is a double-precision floating point operation, resulting probably in library call and significant computing.

JW

Massimiliano Gilli
Associate II
Posted on June 25, 2017 at 14:26

Your answer was indeed the case.

Now i have a second problem which is related.

i'm using an stm32f4 to control a stepper motor.

I'm not sure if i need PWM mode or OC Mode or OnePulse Mode.

I can generate a fixed frequency PWM wave but since i need a particular acceleration/deceleration i need to vary the frequency of the wave with a ramp.

Something like: - 1 pulse at 745hz - 1 pulse at 1867hz - 1 pulse at 2459hz - 1 pulse at ... - 1 pulse at ... - N pulses at ... (constant speed)

Right now in the callback HAL_TIM_PWM_PulseFinishedCallback i'm issuing new TIMx->ARR and TIMx->CCR1 values based on a given logic.

Here is my init

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

What i'm noticing is that the wave train is not correctly generated.

I the first pulse should be 600hz long for example and the second 900hz that is not case.

Clearly a single wave and a constant wave at 600hz is generated correctly

Is the PWM the right way to do it or should i use OC or OnePulse mode?

Regards,

AVI-crak
Senior
Posted on June 25, 2017 at 18:59

It does not matter.

To control the stepper motor there are two variants of the algorithm: wave synthesis and frequency.

For frequency synthesis, it is sufficient to generate a cyclic sequence of voltage changes on the motor windings. This can be done with a timer in literally a million ways (including exotic ones). But the engine will rotate at a constant same speed, and most importantly you will not know its current position. This application is suitable for the mechanism of wall clocks.

For wave synthesis, a timer with a deliberately low operating time is required, but a stable time. For example: if there is a desire to change the poles on an engine with a frequency of 499 Hz - the timer should be at 1KHz.

In wave synthesis, you need an external software counter that will read out the exact time before the pole change event. In this case, controlled acceleration and braking is available, controlled rotation is available for the required number of steps.

The time before the pole change event can be fractional, that is, it is calculated with a margin of accuracy, before being sent for execution - rounding up to the possibility of physics. This will make it possible to control the movement of mechanics as smoothly as possible. Use a floating point is not desirable without physical support from the processor.

More precisely, 'uint32_t' - you have enough for all occasions.