Question
STM32F407 captured value two times bigger than expected
Posted on January 14, 2015 at 20:51
Hi, I have the MCU run SysClk at 168MHz, and I setup the timer to capture mode, but the returned value is two times bigger than expected. I checked the waveform of the toggled LED, it is correct, just the Timer capture value is bigger. Please help me understand why.
* Supported STM32F40xxx/41xxx devices
*-----------------------------------------------------------------------------
* System Clock source | PLL (HSE)
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 4
*-----------------------------------------------------------------------------
* APB2 Prescaler | 2
static uint16_t *buf_tim1;
static uint16_t *buf_tim3;
void capture_init(TIM_TypeDef* TIMx, uint32_t *buf, int total_samples_per_channel)
{
/* TIM Update Frequency = TIM Clock / (P * Q)
*
* Where Prescaler = P - 1, and Period = Q - 1
*
* TIM1 input freq = 84MHz, it is in APB2
* TIM3 input freq = 42MHz, it is in APB1
*/
if ((TIMx != TIM1) && (TIMx != TIM3)) return;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = ~0; // 65536us update // 0..FFFF
if (TIMx == TIM1)
TIM_TimeBaseStructure.TIM_Prescaler = 84 - 1; // 0..FFFF
else
TIM_TimeBaseStructure.TIM_Prescaler = 42 - 1; // 0..FFFF
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //TIM_CKD_DIV1, TIM_CKD_DIV2, TIM_CKD_DIV4
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
TIM_ICInit(TIMx, &TIM_ICInitStructure);
TIM_ITConfig(TIMx, TIM_IT_CC3, ENABLE);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
TIM_ICInit(TIMx, &TIM_ICInitStructure);
TIM_ITConfig(TIMx, TIM_IT_CC4, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
if (TIMx == TIM1) {
/* Enable the TIM1 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
buf_tim1 = (uint16_t*)buf;
}
else {
/* Enable the TIM3 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
buf_tim3 = (uint16_t*)buf;
}
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* TIM enable counter */
TIM_Cmd(TIMx, ENABLE);
}
void TIM1_CC_IRQHandler(void)
{
static uint16 u00, u01, u10, u11;
if (TIM_GetITStatus(TIM1, TIM_IT_CC3)) {
u11 = TIM_GetCapture3(TIM1);
TIM_ClearITPendingBit(TIM1, TIM_IT_CC3);
buf_tim1[1] = u11 - u10;
u10 = u11;
gpio_toggle_pin(GPIOPortID_E, GPIOPinID_1);
}
if (TIM_GetITStatus(TIM1, TIM_IT_CC4)) {
u01 = TIM_GetCapture4(TIM1);
TIM_ClearITPendingBit(TIM1, TIM_IT_CC4);
buf_tim1[0] = u01 - u00;
u00 = u01;
gpio_toggle_pin(GPIOPortID_E, GPIOPinID_0);
}
}
void TIM3_IRQHandler(void)
{
static uint16 u00, u01, u10, u11;
if (TIM_GetITStatus(TIM3, TIM_IT_CC3)) {
u11 = TIM_GetCapture3(TIM3);
TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
buf_tim3[1] = u11 - u10;
u10 = u11;
gpio_toggle_pin(GPIOPortID_E, GPIOPinID_3);
}
if (TIM_GetITStatus(TIM3, TIM_IT_CC4)) {
u01 = TIM_GetCapture4(TIM3);
TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);
buf_tim3[0] = u01 - u00;
u00 = u01;
gpio_toggle_pin(GPIOPortID_E, GPIOPinID_2);
}
}
void main(void)
{
uint16 capture[4];
//initializations
.....
capture_init(TIM3, (uint32_t *)&capture[0], 1);
capture_init(TIM1, (uint32_t *)&capture[2], 1);
while(1);
}