cancel
Showing results for 
Search instead for 
Did you mean: 

About the output compare mode hunting

otcagon
Associate II
Posted on September 10, 2014 at 18:26

Hello Person who knows the solution.

I am Yang and I try to make cluster for the rpm output but I met the rpm hunting problem.

I need frequency modulation for the cluster.

The below are the code than I use.

STM32F407VG  with 8HMz external clock and 168Mhz is system clock after PLL.

I assign the PortC 4 for the output.

When I check the output with oscilloscope, some times it shows very short pulse and it makes the rpm gauage jupm up.

Is there something wrong in the STM32F407?

I use ''STM32F4xx_StdPeriph_Driver''.

I try to find the solution in the forum and I have a question about the ''stm32f4xx_tim.c''.

void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)

{

  /* Check the parameters */

  assert_param(IS_TIM_ALL_PERIPH(TIMx));

  /* Clear the IT pending Bit */

  TIMx->SR = (uint16_t)~TIM_IT;

} Is the command ''TIMx->SR = (uint16_t)~TIM_IT;'' correct?

If I want to clear the TIM_IT position, ''TIMx->SR $= (uint16_t)~TIM_IT;'' looks correct.

void timer5_set(void)

{

 PrescalerValue = (uint16_t) ((168000000 / 2) / 500000) - 1;

 // Time base configuration //

 TIM_TimeBaseStructure.TIM_Period = 65535;

 TIM_TimeBaseStructure.TIM_Prescaler = 0;

 TIM_TimeBaseStructure.TIM_ClockDivision = 0;

 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

 TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);

 // Prescaler configuration //

 TIM_PrescalerConfig(TIM5, PrescalerValue, TIM_PSCReloadMode_Immediate);

 // Output Compare Timing Mode configuration: Channel1 //

 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;

 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

 TIM_OCInitStructure.TIM_Pulse = T3CCR1_Val;

 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

 TIM_OC1Init(TIM5, &TIM_OCInitStructure);

 TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Disable);

 // Output Compare Timing Mode configuration: Channel4 //

 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

 TIM_OCInitStructure.TIM_Pulse = T3CCR2_Val;

 TIM_OC2Init(TIM5, &TIM_OCInitStructure);

 TIM_OC2PreloadConfig(TIM5, TIM_OCPreload_Disable);

 

 // Output Compare Timing Mode configuration: Channel4 //

 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

 TIM_OCInitStructure.TIM_Pulse = T3CCR2_Val;

 TIM_OC3Init(TIM5, &TIM_OCInitStructure);

 TIM_OC3PreloadConfig(TIM5, TIM_OCPreload_Disable);

 // Output Compare Timing Mode configuration: Channel4 //

 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

 TIM_OCInitStructure.TIM_Pulse = T3CCR2_Val;

 TIM_OC4Init(TIM5, &TIM_OCInitStructure);

 TIM_OC4PreloadConfig(TIM5, TIM_OCPreload_Disable);

 //TIM Interrupts enable //

 TIM_ITConfig(TIM5, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);

 // TIM5 enable counter //

 TIM_Cmd(TIM5, ENABLE);

}

void TIM5_IRQHandler(void)

{

 if(TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)

 {

  TIM_ClearITPendingBit(TIM5, TIM_IT_CC1);

  if(B_ig_on)          GPIO_ToggleBits(GPIOD, GPIO_Pin_3);

  else             GPIO_SetBits(GPIOD, GPIO_Pin_3);

  capture1 = TIM_GetCapture1(TIM5);

  TIM_SetCompare1(TIM5, (u16)(capture1+cc1_val));  

 }

 else if(TIM_GetITStatus(TIM5, TIM_IT_CC2) != RESET)

 {

  TIM_ClearITPendingBit(TIM5, TIM_IT_CC2);

  if(B_ig_on)          GPIO_ToggleBits(GPIOE, GPIO_Pin_1);

  else             GPIO_SetBits(GPIOE, GPIO_Pin_1);

  capture2 = TIM_GetCapture2(TIM5);

  TIM_SetCompare2(TIM5, (u16)(capture2 + cc2_val));

 }

 else if(TIM_GetITStatus(TIM5, TIM_IT_CC3) != RESET)

 {

  TIM_ClearITPendingBit(TIM5, TIM_IT_CC3);

  if(B_ig_on)          GPIO_ToggleBits(GPIOE, GPIO_Pin_3);

  else             GPIO_SetBits(GPIOE, GPIO_Pin_3);

  

  capture3 = TIM_GetCapture3(TIM5);

  TIM_SetCompare3(TIM5, (u16)(capture3 + cc3_val));  

 }

 else if(TIM_GetITStatus(TIM5, TIM_IT_CC4) != RESET)

 {

  TIM_ClearITPendingBit(TIM5, TIM_IT_CC4);

  if(B_rpm)            GPIO_ToggleBits(GPIOC, GPIO_Pin_4); // && B_ig_on

  else              GPIO_SetBits(GPIOC, GPIO_Pin_4);

  

  capture4 = TIM_GetCapture4(TIM5);

  TIM_SetCompare4(TIM5, (u16)(capture4 + cc4_val));

 } 

}

Thank you.

#stm32f
2 REPLIES 2
Posted on September 10, 2014 at 19:37

The behaviour of TIMx->SR is documented in the Reference Manual

If you use TIMx->SR &= ~TIM_IT; you would cause a race hazard, remember AND'ing something you want to preserve with ZERO is always a bad plan.

Consider if the amount you are advancing by is too tight. You don't mention a frequency and the code is insufficiently complete to infer one.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
otcagon
Associate II
Posted on September 11, 2014 at 10:17

Thank you for your concerns.

I tried to start with original commands. TIMx->SR = ~TIM_IT;

The frequency range is from 50Hz(1200rpm)~300Hz(7200rpm).

cc4_val varis from 723 to 10551.

Thank you