2017-06-24 03:51 AM
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-accessSolved! Go to Solution.
2017-06-24 04:42 AM
round(value) *0.2
This is a double-precision floating point operation, resulting probably in library call and significant computing.
JW
2017-06-24 04:42 AM
round(value) *0.2
This is a double-precision floating point operation, resulting probably in library call and significant computing.
JW
2017-06-25 05:26 AM
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,
2017-06-25 09:59 AM
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.