2014-01-04 04:06 PM
Hello,
I am new with STM. Iam working on racing car ECU project and wants to get maximum out of the mcu. I got stuck and couldnt get going. I would be grateful if someone could show me the way to go around my problems ProjectUsing STMF429 and measuring frequency of 8 input signals independently. Frequency is 10-2000Hz. These input signals are actually car wheels (each wheel 2 sensors). Doesnt need to know direction. Iam using these 2 sensors on wheel for better precision. What I have doneConfigured timers for input capture mode. After each rising edge I get counter slave reset. Then I read period of CCR register. This works fine. What is the problemOverflowAs I am looking for specific frequency I need to get rid of possible timer overflows. I found overcapture which is different event (between reading 1<captures happened). Then I found update event flag which is generated when counter overflows but it is also generated by slave. Is there way to know that the counter have overflowed in the particular capture Iam reading? Input prescalerI need to improve measurement quality by increasing input prescaler as vehicle speed is increasing.Problem is that Iam prescaling input signals but the period I read is only from last capture not the period of all divided captures together. Initialisation of TIM2 and GPIO inputvoid
TIM2_Init(
void
)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_AHB1PeriphClockCmd(USER_BUTTON_GPIO_CLK, ENABLE);
// GPIO-port clock enable
GPIO_InitStructure.GPIO_Pin = USER_BUTTON_PIN;
// TIM2 chennel2 configuration : PB.07
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(USER_BUTTON_GPIO_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(USER_BUTTON_GPIO_PORT, GPIO_PinSource0, GPIO_AF_TIM2);
// Connect TIM pin to AF2
TIM_TimeBaseStructure.TIM_Period = 0xFFFFF;
//Time base configuration
TIM_TimeBaseStructure.TIM_Prescaler = ODO_F_PRESCALE;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_PrescalerConfig(TIM2, ODO_F_PRESCALE, TIM_PSCReloadMode_Immediate);
//Prescaler configuration
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV8;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1);
// Select the TIM2 Input Trigger: TI2FP2
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
// Select the slave Mode: Reset Mode
TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);
TIM_Cmd(TIM2, ENABLE);
// TIM enable counter
}
Is it even possible to get the same effect without using slave mode? Currently Iam having all 8 input on different timers but if it is possible I would like to have more sensors on the same timer. From my previous experience with timer slave reset I thought this isnt possible.
Thank you for help
Marek
#input-capture-overlow-prescaler
2014-01-04 04:42 PM
I'd certainly recommend using the maximum extent of the 32-bit timebase, and instead of resetting the counter, simply delta the CCR readings.
ie don't use PWM Input mode unless the period and duty are critical to you, better to use straight Input Capture. This should give you a huge count time frame, and you could easily flag if things where below 10 Hz by tracking what channels have fired in a 1 Hz task. Roll-over for 32-bit counter clocking at 90 MHz would be 47.7 seconds.2014-01-05 03:39 AM
Thank you. I understood partially.
But for the simple input capture I need interrupt request where I simply delta the readings and prescale them? Or atleast I get number of rising edges for the channel between readings which I can divide in calculation and get the most accurate period between readings?Or is there any other way to go around?Actually I cant find how to get capture interrupt as TIM2-TIM5 which are 32 bit dont have CC handler.BTW: I need to read data assynchronously.2014-01-05 05:36 AM
I'll observe that you could use all four channels of a single timer in this mode.
Most TIM units have a single IRQHandler, but you can recognize CCx interrupts, others break out Update,CC,etc Your CCx interrupts will track CCRx from current/previous readings, and store the delta in a volatile structure, which you can read asynchronously elsewhere in your app. For a current measurement, you could read CNT and compare to last CCRx measurement. You divide the delta into the 90 MHz (or whatever) timebase to compute frequency. You can invalidate/manage these measurements on a slower task. For example counting off seconds since last measurement.2014-01-05 10:32 AM
Thank you for help. I tried it and it works well.
With little optimalisation I get overflow every hour.I found out that this method might be good at precise calculation without using any fixed prescaler (CCRx_now-CCRx_last)/ n_CAPTURES which I know from interrupt routine.What I couldnt test on my 429 board as there arent free pins is more channels on the timer generating capture interrupt.2014-01-05 12:55 PM
The STM32F429I-Discovery has a primary focus on the SDRAM and LCD, these take up the majority of the available pins. This is a very poor board choice if additional functionality is desired. Problems supporting SDIO, Ethernet and DCMI