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
antonius
Senior

The file : STM32F4-Discovery_FW_V1.1.0\Project\Peripheral_Examples\TIM_TimeBase\readme.txt

prain
Senior III

Getting 1Hz is not possible with this prescaler value. Increase prescaler value. for example set timer clock to 1KHz:

PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 1000) - 1;

then set your desired CCx channel to 1000 :

__IO uint16_t CCR1_Val = 1000;

TDK
Guru

The CCR values for TIM1 are 16-bit (max of 65535), so you need to increase the prescaler if you want a 1Hz interrupt.

Use

PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 50000) - 1;

to set the timer clock to 50kHz and use TIM_Period = 49999 to have an update interrupt at 1 Hz.

That example is showing how to toggle LEDs multiple times within an update period. Doesn't seem like what you're asking for.

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

> PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 1000) - 1;

At a clock of 168 MHz, this will overflow 16 bits.

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

The precision also depends on clock tolerances, so don t use HSI internal oscillators. Ideally use 32.768khz LSE clock as RTC purpose is calendar and time clock. In some products like STM32L4 48MHz can be generated by MSI from LSE.

How​ to avoid overflow ? I want to get 1Hz, 0.5Hz, 0.1Hz and 0.05Hz Thanks

Read my answer below.

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

I don't understand, if I want to get 0.5 Hz ?

What's the value for

__IO uint16_t CCR1_Val = 49999; // 1Hz

__IO uint16_t CCR2_Val = 49999*2; // to get 0.5Hz ==> correct me ?

if

TIM_Period = 49999

and

TIM3 counter clock at 50 KHz, I'm thinking to reduce TIM3 counter clock to 1KHz, but I can't get a good result ?

Cheers,

> 49999*2

This overflows. What did you have to do before to prevent it from overflowing?

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