cancel
Showing results for 
Search instead for 
Did you mean: 

How to avoid extra delay induced by the UPDATE interrupt when the value of RCR is changed?

RMiha
Associate II

Hi,

I am developing a motor control application for a servo that is controlled in impulses. So, in my case, the number of impulses represents the number of steps.

For that, I am using the TIM1 in PWM mode using One-Pulse. To account for the number of steps/impulses I use the RCR. To change the RCR val I set the corresponding bit of EGR to generate an update of the TIM1 registers.

The problem arises when I want to generate a small PWM period (4 us in the figure above) I have created a small trial application to test the functionality of my approach. So, I am generating 3 sequences of impulses using 3 different values (0, 1 and 2) for RCR. Because the RCR val corresponds to RCR+1 pulses, the result has to be 6 impulses, which is achieved. However this result is not good because when the RCR value is updated, a delay is introduced. See the picture below.

0690X000006CXTiQAO.pngTo accomplish this task I used interrupts for update events, namely:

  1. When the RCR value is updated, do nothing in interrupt. Only needed to update TIM1 registers.
  2. When the RCR value overflows, that means the present sequence of impulses finished, so I change the value of RCR and I update the EGR register (which generates the above event).

The hardware is a prototype board designed around the microcontroller STM32F103C8T. Other things important to mention:

  • CPU freq : 72 MHz
  • The file main.c is not relevant because contains only the initialization and configuration of peripherals, which are well done. The �?while()�? loop inside �?int main(void)�? is empty. The only 2 important code lines to highlight, are executed in �?int main(void)�? , before �?while�? and are used to activate update event interrupts and to start the first sequence of impulses
	__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);
	HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
	
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

Finally, I somehow would like to update the RCR and TIM1 registers without treat the first update interrupt from above. I belive, there I lose time...

Thank you for your attention and I look forward for some advises. Se the code from interrupt service routine below:

/**
* @brief This function handles TIM1 update interrupt.
*/
void TIM1_UP_IRQHandler(void)
{
  /* USER CODE BEGIN TIM1_UP_IRQn 0 */
	
  /* USER CODE END TIM1_UP_IRQn 0 */
	
	// I commented the line below because I do not want to evaluate all the possible events that generated this interrupt. In my case it is clear that only the update event
	// will generate interrupts
	
  //HAL_TIM_IRQHandler(&htim1);
	__HAL_TIM_CLEAR_IT(&htim1, TIM_IT_UPDATE);
	if(flag_update_event)
	{
		// Make this flag FLASE, because next time this interrupt will be enterred, will be because the RCR value overflowed
		flag_update_event = FALSE;
	}
	else
	{
		user_seq_of_ordered_steps++;		// This variable is needed because I want to generate only theree sequences of impulses 
		if(user_seq_of_ordered_steps < 3)
			{
				htim1.Instance->RCR = ++user_no_of_steps;		// This value is initially 0
				htim1.Instance->EGR = TIM_EGR_UG;
				// Make this flag TRUE to enter again the interrupt to update the TIM1 registers
				flag_update_event = TRUE;
				/* Enable the Peripheral */
				__HAL_TIM_ENABLE(&htim1);
			}
	}
  /* USER CODE BEGIN TIM1_UP_IRQn 1 */
 
  /* USER CODE END TIM1_UP_IRQn 1 */
}

0 REPLIES 0