2013-05-27 12:04 PM
Hello,
I'm trying to read rpm from a fan. At first I tried with EXTI and while it worked at fast speed, it started to get crazy when halted or at low speed, especially when the voltage was at undefined state ~1.5V. Is there a way interrupts trigger when actually going from <1V to >2V ? Now I'm trying with a timer in input capture mode ... looked at the reference manual (Interfacing with Hall sensors) and some googling to get this far ...void HALL_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_TimeBaseStructure.TIM_Prescaler = 840;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
//Enable hall sensor
TIM_SelectHallSensor(TIM2, ENABLE);
// HallSensor event is delivered with singnal TI1F_ED
// (this is XOR of the three hall sensor lines)
// Signal TI1F_ED: falling and rising edge of the inputs is used
TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED);
// On every TI1F_ED event the counter is resetted and update is tiggered
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
// Channel 1 in input capture mode
// on every TCR edge (build from TI1F_ED which is a HallSensor edge)
// the timervalue is copied into ccr register and a CCR1 Interrupt
// TIM_IT_CC1 is fired
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
//TIM_ITConfig(TIM2, TIM_IT_Trigger, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2, ENABLE);
}
... but the interrupt handler never triggers
any help appreciated
~Matt
#hall-effect-hall-timer #me-too
2013-05-27 12:56 PM
Is there a way interrupts trigger when actually going from <1V to >2V ?
check Vih min and Vil max in the datasheet inbetween what happen is anybodys guess without schmitt-trigger, you can find a place where a change of a few millivolts on the input will change the output I would not connect a Hall-effect sensor to a logical input without a schmitt trigger inbetween your micro may have a comparator with hysteresis, if so use it
2013-05-28 03:30 AM
Forgot to mention, I'm using the STM32F4 Discovery, and looking into GPIO schemes, there's a schmitt trigger on inputs.
2013-05-28 06:41 AM
Which Hall sensor are you using, and what is the signal source?
Cheers, Hal2013-05-28 07:52 AM
if you look at the signal from the Hall on a scope is it 'clean' with 'sloppy' rise and fall times or is it 'noisy'?
I know from encoders that a whole lot of noise at the transition is quite common. If you see noise a simple RC filter should alleviate the problem Erik2014-06-17 04:00 AM
Hi I have the same problem. Did you fix the problem and how?
Sascha2014-06-17 04:37 AM
Don't expect a poster with two posts from over a year ago to provide a useful response. State clearly YOUR situation and configuration.
2014-06-17 07:34 AM
Hi, ok I will try my best:
I want to configuere Timer2 as a hall sensor interface for a bldc motor, but my initialization of the timer doesn't work correctly. I can't get the timer interrupt to work. I can see the hall signals with a logic analyzer and they are correct. Here's my init code: void Init(void){ GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); // enable clock for GPIOA RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // inputs for hall sensors GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2); // enable clock for timer2 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // update event every ca. 4295sec // resolution: 1usec TIM_InitStructure.TIM_Prescaler = 42; TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_InitStructure.TIM_Period = 0xFFFFFFFF; TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2, &TIM_InitStructure); // connect three channels to XOR in timer TIM_SelectHallSensor(TIM2, ENABLE); TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED); TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset); // initialize the cature compare function of timer2 TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICFilter = 0; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC; TIM_ICInit(TIM2, &TIM_ICInitStructure); // enable the interrupt for timer2 TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // enable timer2 TIM_Cmd(TIM2, ENABLE); } Hope someone can help me, thanks in advance for your replies !!! Sascha2014-06-17 08:13 AM
The pins need to be in AF mode in an F4 device, not IN mode
The timer on a 168 MHz F4, on APB1 (DIV4), is running at (DIV2) 84 MHz ie Prescaler = 84 - 1; What tool chain? Are you using C++? Can you generate update or other interrupts on TIM2 in other situations?2014-06-18 02:42 AM
Hi,
thanks for your reply. Wrong Pin configuration was the mistake. By the way I'm using IAR embedded workbench with the c compiler. The update interrupt worked well as I tried it before. Thanks again !!! Sascha