2013-10-05 06:28 PM
I'm using a DIY development board for STM32F405RGT6, with an 8MHz HSE. I've used the clock configuration tool from ST to generate the system_stm32f4xx.c file such that the clock is configured to 168MHz using the HSE. I've checked that the HSE value in the stm32f4xx.h file is correct.
Now I've configured TIM6 to generate an interrupt every (what I expected to be) 1 millisecond. TIM6 uses APB1, which has a prescaler of 4. Considering the clock tree, I expect the timer clock to be 84MHz. So I set my prescaler to 83, and period to 9 By incrementing a volatile integer in the interrupt and blinking an LED based on that (no oscilloscope at home), I find the frequency to be twice of what I expected. Here's the code I used to set up TIM6.void base_timer_init(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
//TIM_TimeBaseInitStructure.TIM_Prescaler = 167;
//TIM_TimeBaseInitStructure.TIM_Prescaler = (uint16_t)((SystemCoreClock/2)/1000000)-1;
TIM_TimeBaseInitStructure.TIM_Prescaler = 83;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 999;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseInitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM6_DAC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM6, ENABLE);
}
And here's the code for blinking the LED:
#include <
stdio.h
>
#include ''stm32f4xx.h''
#include ''gpio.h''
#include ''timer.h''
__IO uint32_t millis = 0;
int main(void) {
RCC_HSEConfig(RCC_HSE_ON);
while(!RCC_WaitForHSEStartUp());
gpio_init();
base_timer_init();
while(1) {
if (millis >= 1000) {
millis = 0;
GPIO_ToggleBits(GPIOC, GPIO_Pin_9);
}
}
return 0;
}
void TIM6_DAC_IRQHandler(void) {
millis++;
TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
}
I've spent quite a few hours on this but made no progress, so I'll really appreciate any help!
Thank you in advance.
#stm32f4-timer-clock-frequency
2013-10-05 06:57 PM
void TIM6_DAC_IRQHandler(void) {
TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
millis++;
}
2013-10-05 07:07 PM
Thanks for the fast response as usual!
Why does the order matter? I just left my workbench (it's 3am now), so I'll only test it later.2013-10-05 07:26 PM
There is a pipelining/write-buffer hazard with the tail-chaining, your interrupt handler re-enters once immediately after it leaves. You should clear interrupt sources early, and ideally qualify the source.
'Basically the pipeline in the processor decides what interrupt to service next before the clearing of the interrupt propagates back from external peripherals on the APB/AHB buses, and back into the NVIC. The latency will depend on the speed disparity of those buses, futher impacted by the write buffer on the processor. The effect will be that the processor will re-enter an interrupt service routine almost immediately with what looks like a spurious interrupt which will not be signalled in the status register as that read will have fenced the pending write, which may also have already completed. It's a classic race condition, the pipeline gives the appearance of single cycle execution (throughput), but the latency is much higher.
So you either need to dwell for a couple of cycles to accommodated the pipeline/write buffer, or fence the write with some other reads/writes to enforce in-order completion.'
https://community.st.com/message/55698
Edit: Fixed DEAD LINK, original post from Oct 5, 2013
2013-10-06 05:07 AM
I'm glad I asked. Thank you!
2013-10-12 11:21 AM
automatically set by hardware. There are two cases:
1. If the APB prescaler is 1, the timer clock frequencies are set to the same frequency as
that of the APB domain to which the timers are connected.
2. Otherwise, they are set to twice (×2) the frequency of the APB domain to which the
timers are connected.Since you are running a prescaler of 4 for the APB1 bus, the timer clock will 2x the bus speed.
2013-10-12 01:09 PM
He's not talking about the clock tree, as the title clearly states.