2015-01-14 11:51 AM
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);
}
2015-01-14 01:05 PM
Please help me understand why.
Review the Clock Tree diagram in the Reference Manual more carefully. The TIM CLK is typically 2* the APB clock in all but the DIV1 mode.2015-01-15 09:02 AM
2015-01-15 09:16 AM
Not sure I'm up for wading through all this.
You're going to have to do some more coding for TIM1, the timebase and channel structures have more fields which need to be filled in. TIM1 (and TIM8) have a Repetition Count, N-Outputs, and the PWM Outputs (and Inputs) need enabling. If pin connectivity is a problem check the AF Pin Source configurations.2015-01-15 01:22 PM
> TIM1 (and TIM8) [...] the PWM Outputs (and Inputs) need enabling.
Ah, the TIMx_BDTR.MOE gotcha... It's maybe time to start the STM32 Frequently Encountered Gotchas list. Both the ''(F2/F4) timer runs twice as fast as expected'' and ''TIM1/TIM8 output won't work'' are in there... JW