2020-08-02 08:06 PM
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)
2020-08-02 08:06 PM
The file : STM32F4-Discovery_FW_V1.1.0\Project\Peripheral_Examples\TIM_TimeBase\readme.txt
2020-08-02 08:39 PM
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;
2020-08-02 08:49 PM
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.
2020-08-02 08:52 PM
> PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 1000) - 1;
At a clock of 168 MHz, this will overflow 16 bits.
2020-08-02 10:35 PM
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.
2020-08-03 06:55 AM
How to avoid overflow ? I want to get 1Hz, 0.5Hz, 0.1Hz and 0.05Hz Thanks
2020-08-03 07:00 AM
Read my answer below.
2020-08-03 04:03 PM
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,
2020-08-03 04:48 PM
> 49999*2
This overflows. What did you have to do before to prevent it from overflowing?