cancel
Showing results for 
Search instead for 
Did you mean: 

1Hz interrupt from TIM3 ?

antonius
Senior

Dear Members,

How can I get exactly 1Hz interrupt from TIM3 ?

I use STM32F4 Discovery and looking at TIM_TimeBase Example, but I can not get exactly 1Hz yet...

Thanks

Code :

TIM_OCInitTypeDef  TIM_OCInitStructure;
__IO uint16_t CCR1_Val = 54618;
__IO uint16_t CCR2_Val = 27309;
__IO uint16_t CCR3_Val = 13654;
__IO uint16_t CCR4_Val = 6826;
 
 
/* -----------------------------------------------------------------------
    TIM3 Configuration: Output Compare Timing Mode:
    
    In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1), 
    since APB1 prescaler is different from 1.   
      TIM3CLK = 2 * PCLK1  
      PCLK1 = HCLK / 4 
      => TIM3CLK = HCLK / 2 = SystemCoreClock /2
          
    To get TIM3 counter clock at 50 MHz, the prescaler is computed as follows:
       Prescaler = (TIM3CLK / TIM3 counter clock) - 1
       Prescaler = ((SystemCoreClock /2) /50 MHz) - 1
                                              
    CC1 update rate = TIM3 counter clock / CCR1_Val = 9.154 Hz
    ==> Toggling frequency = 4.57 Hz
    
    C2 update rate = TIM3 counter clock / CCR2_Val = 18.31 Hz
    ==> Toggling frequency = 9.15 Hz
    
    CC3 update rate = TIM3 counter clock / CCR3_Val = 36.62 Hz
    ==> Toggling frequency = 18.31 Hz
    
    CC4 update rate = TIM3 counter clock / CCR4_Val = 73.25 Hz
    ==> Toggling frequency = 36.62 Hz
 
/* Compute the prescaler value */
  //PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 500000) - 1;
	PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 6826) - 1;  //TIM3 counter clock at 6826Hz
 
  /* 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(TIM3, &TIM_TimeBaseStructure);
 
  /* Prescaler configuration */
  TIM_PrescalerConfig(TIM3, 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 = CCR1_Val;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
 
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);
 
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);
 
  /* Output Compare Timing Mode configuration: Channel2 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
 
  TIM_OC2Init(TIM3, &TIM_OCInitStructure);
 
  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);
 
  /* Output Compare Timing Mode configuration: Channel3 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
 
  TIM_OC3Init(TIM3, &TIM_OCInitStructure);
 
  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable);
 
  /* Output Compare Timing Mode configuration: Channel4 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
 
  TIM_OC4Init(TIM3, &TIM_OCInitStructure);
 
  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable);
   
  /* TIM Interrupts enable */
  TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
This example shows how to configure the TIM peripheral in Output Compare Timing 
mode with the corresponding Interrupt requests for each channel in order to generate
4 different time bases.
 
The TIM3CLK frequency is set to SystemCoreClock / 2 (Hz), to get TIM3 counter 
clock at 500 KHz so the Prescaler is computed as following:
   - Prescaler = (TIM3CLK / TIM3 counter clock) - 1
 
SystemCoreClock is set to 168 MHz for STM32F4xx Devices Revision A.
 
The TIM3 CC1 register value is equal to 54618, 
CC1 update rate = TIM3 counter clock / CCR1_Val = 9.154 Hz,
so the TIM3 Channel 1 generates an interrupt each 109.2ms
 
The TIM3 CC2 register is equal to 27309, 
CC2 update rate = TIM3 counter clock / CCR2_Val = 18.31 Hz
so the TIM3 Channel 2 generates an interrupt each 54.6ms
 
The TIM3 CC3 register is equal to 13654, 
CC3 update rate = TIM3 counter clock / CCR3_Val = 36.62 Hz
so the TIM3 Channel 3 generates an interrupt each 27.3ms
 
The TIM3 CC4 register is equal to 6826, 
CC4 update rate = TIM3 counter clock / CCR4_Val =  73.25 Hz
so the TIM3 Channel 4 generates an interrupt each 13.65ms.
 
When the counter value reaches the Output compare registers values, the Output 
Compare interrupts are generated and, in the handler routine, 4 pins(PD.12, PD.13,
PD.14 and PD.15) are toggled with the following frequencies: 
 
- PD.12:  4.57 Hz (CC1)
- PD.13:  9.15 Hz (CC2)
- PD.14: 18.31 Hz (CC3) 
- PD.15: 36.62 Hz (CC4)

24 REPLIES 24

Like this :

__IO uint16_t CCR1_Val = 3000;
__IO uint16_t CCR2_Val = 6000;
__IO uint16_t CCR3_Val = 12000;
__IO uint16_t CCR4_Val = 60000;
 
.
.
.
PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 3000) - 1;  //TIM3 counter clock at 3000Hz
 
.
.
/* 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;
 
.
.
.
void TIM3_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
 
    /* LED4 toggling with frequency = 4.57 Hz */
    STM_EVAL_LEDToggle(LED4);
	capture = TIM_GetCapture1(TIM3);
    TIM_SetCompare1(TIM3, capture + CCR1_Val);
  }
  else if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
 
    /* LED3 toggling with frequency = 9.15 Hz */
    STM_EVAL_LEDToggle(LED3);
    capture = TIM_GetCapture2(TIM3);
    TIM_SetCompare2(TIM3, capture + CCR2_Val);
  }
  else if (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
 
    /* LED5 toggling with frequency = 18.31 Hz */
    STM_EVAL_LEDToggle(LED5);
    capture = TIM_GetCapture3(TIM3);
    TIM_SetCompare3(TIM3, capture + CCR3_Val);
  }
  else
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);
 
    /* LED6 toggling with frequency = 36.62 Hz */
    STM_EVAL_LEDToggle(LED6);
    capture = TIM_GetCapture4(TIM3);
    TIM_SetCompare4(TIM3, capture + CCR4_Val);
  }
}

Piranha
Chief II

You still have set prescaler to 65'536. That's why you are getting 65'536 / 28'000 = 2,34 Hz instead of 1 Hz and some other x2 factor which turns it into 4,68 Hz.

CCR3_Val is not set to 0,1 Hz. Compare value = timer_clock (Hz) / compare_frequency (Hz).

do you mean :

TIM_TimeBaseStructure.TIM_Period = 65535;

?

Timer clock = 3000 Hz and compare frequency = 0.5 Hz

CCR3_Val is a variable on TIM3_IRQHandler

Compare Value = 3000 Hz / 0.5 Hz

antonius
Senior

__IO uint16_t CCR1_Val = 3000/1;

__IO uint16_t CCR2_Val = 3000/0.25;

__IO uint16_t CCR3_Val = 3000/0.125;

__IO uint16_t CCR4_Val = 3000/0.062;

?

Is it possible that I have 1s interrupt then for getting 60 seconds, I loop that 1s , 60 times ?

Where can I put that loop ?

if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
 
    /* LED4 toggling with frequency = 4.57 Hz */
    STM_EVAL_LEDToggle(LED4);
	capture = TIM_GetCapture1(TIM3);
    TIM_SetCompare1(TIM3, capture + CCR1_Val);
  }
 
Call the loop function here ?

Thanks