cancel
Showing results for 
Search instead for 
Did you mean: 

How to generate PWM and use timer interrupt at the same time?

M7890.1
Associate III

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?

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

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

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

11 REPLIES 11
TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".
M7890.1
Associate III

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.

M7890.1
Associate III

The PWM output is not affected if I start timer3 without interrupt.

Shouldn’t be affected either way. I suspect you’re doing something in the period elapsed callback.l that stops the PWM. Regardless, you can debug and examine the registers to see why PWM stopped. Has the be a reason.
If you feel a post has answered your question, please click "Accept as Solution".

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?

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?

> The problem happens due to the CCR1 and CCR2 being updated.

To what values?

JW

S.Ma
Principal

Don t do float calculation inside a callback.

@M7890.1​  Your problem is simple left_pwm uint16 / 1000000 is always 0