2021-09-11 08:22 PM
I am using the Bluepill board. I want to generate PWM signal on Timer2 and set up a timer interrupt at 20ms interval on Timer3. I realized that the PWM signal cannot be generated if I set up the timer interrupt on Timer3. How do I solve this problem?
Solved! Go to Solution.
2021-09-12 07:08 AM
> left_pwm / 1000000
> right_pwm / 1000000
These always evaluate to 0. If you want to use float, cast them to float first instead.
TIM2->CCR1 = (int) ((((float) left_pwm / 1000000) / 0.02) * 65535);
TIM2->CCR2 = (int) ((((float) right_pwm / 1000000) / 0.02) * 65535);
2021-09-11 08:43 PM
You can have PWM generation on one timer and update interrupt on another timer at the same time. What issue are you running into? They are independent.
2021-09-11 08:47 PM
Yes. They should be independent. So I was having these 3 lines before my while loop:
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // start PWM signal
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
HAL_TIM_Base_Start_IT(&htim3);
I have set my PWM pulse width to 1ms. When I take a look at the output, the PWM output a single pulse of 1ms and it becomes zero after that (most probably after timer3 being started). If I remove HAL_TIM_Base_Start_IT(&htim3); from my code, the PWM signal can be generated without problem.
2021-09-11 10:16 PM
The PWM output is not affected if I start timer3 without interrupt.
2021-09-11 10:22 PM
2021-09-11 10:37 PM
Yes. I am doing something when timer interrupt fired.
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) {
float error;
static float past_error;
float roll_pid_p;
static float roll_pid_i = 0;
float roll_pid_d;
float roll_pid;
uint16_t left_pwm, right_pwm;
const uint16_t max_pwm = 1800;
const uint16_t thrust = 1200;
// GET ROLL ANGLE
mpu6050_read_data();
mpu6050_calc_angle();
// COMPUTE PID
error = comp_roll - 0; // setpoint = 0
roll_pid_p = pid_coef[0] * error;
roll_pid_i = roll_pid_i + pid_coef[1] * error;
roll_pid_d = pid_coef[2] * ((error - past_error) / 0.02);// 0.02 is update rate
roll_pid = roll_pid_p + roll_pid_i + roll_pid_d;
// if (roll_pid > max_pwm - thrust)
// roll_pid = max_pwm - thrust;
// else if (roll_pid < -1 * max_pwm - thrust)
// roll_pid = -1 * (max_pwm - thrust);
past_error = error;
// compute PWM pulse width
left_pwm = thrust - (int) roll_pid;
right_pwm = thrust + (int) roll_pid;
if (left_pwm > 1800)
left_pwm = 1800;
else if (left_pwm < 1200)
left_pwm = 1200;
if (right_pwm > 1800)
right_pwm = 1800;
else if (right_pwm < 1200)
right_pwm = 1200;
/*
update duty cycle
PA0 - TIM2 CH1 - Left motor
PA1 - TIM2 CH2 -Right motor
0.02 = PWM frequency | 65535 = ARR value
*/
TIM2->CCR1 = (int) (((left_pwm / 1000000) / 0.02) * 65535);
TIM2->CCR2 = (int) (((right_pwm / 1000000) / 0.02) * 65535);
}
Is there something wrong with this code?
2021-09-12 12:24 AM
The problem happens due to the CCR1 and CCR2 being updated. I did something similar in another code but don't encounter this problem. Why is that so?
2021-09-12 12:49 AM
> The problem happens due to the CCR1 and CCR2 being updated.
To what values?
JW
2021-09-12 01:46 AM
Don t do float calculation inside a callback.
2021-09-12 03:47 AM
@M7890.1 Your problem is simple left_pwm uint16 / 1000000 is always 0