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
2015-04-03 07:24 AM
I'm trying to get the position value written on USART from 3 hall sensors and i get zero always. can u please look at my cord. thank you in advance. after i get this i can get the speed calculated.
#include ''stm32f4xx.h''#include ''stm32f4xx_rcc.h''#include ''stm32f4xx_gpio.h''#include ''stm32f4xx_tim.h''#include ''stm32f4xx_exti.h''#include ''tm_stm32f4_delay.h''#include ''tm_stm32f4_usart.h''#include ''math.h''#include <stdio.h>void configHallSensorTimer(void) { TIM_ICInitTypeDef TIM_ICInitStructure; GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; // enable port pins for hall inputsRCC_APB2PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_Init(GPIOD, &GPIO_InitStructure); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // timer base configuration // 126 => 3,5s till overflow ; 285,714kHz TimerClock [36MHz/Prescaler] TIM_TimeBaseStructure.TIM_Prescaler = 126; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); // enable hall sensor // T1F_ED will be connected to HallSensoren Imputs // TIM4_CH1,TIM4_CH2,TIM4_CH3 TIM_SelectHallSensor(TIM4, ENABLE); // HallSensor event is delivered with singnal TI1F_ED // (this is XOR of the three hall sensor lines) // Signal TI1F_ED: falling and rising ddge of the inputs is used TIM_SelectInputTrigger(TIM4, TIM_TS_TI1F_ED); // On every TI1F_ED event the counter is resetted and update is tiggered TIM_SelectSlaveMode(TIM4, 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; // listen to T1, the HallSensorEvent TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC; // Div:1, every edge TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // noise filter: 1111 => 72000kHz / factor (==1) / 32 / 8 -> 281kHz // input noise filter (reference manual page 322) TIM_ICInitStructure.TIM_ICFilter = 0xF; TIM_ICInit(TIM4, &TIM_ICInitStructure); // channel 2 can be use for commution delay between hallsensor edge // and switching the FET into the next step. if this delay time is // over the channel 2 generates the commutation signal to the motor timer TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = 1; // 1 is no delay; 2000 = 7ms TIM_OC2Init(TIM4, &TIM_OCInitStructure); // clear interrupt flag TIM_ClearFlag(TIM4, TIM_FLAG_CC2); //TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable); // TIM_SelectOutputTrigger(TIM4, TIM_TRGOSource_OC1); // timer2 output compate signal is connected to TRIGO TIM_SelectOutputTrigger(TIM4, TIM_TRGOSource_OC2Ref); // Enable channel 2 compate interrupt request // TIM_IT_CC1 | TIM_IT_CC2 TIM_ITConfig(TIM4, TIM_IT_CC1 | TIM_IT_CC2, ENABLE); // we use preemption interrupts here, BLDC Bridge switching and // Hall has highest priority NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // ------------------- // HallSensor is now configured TIM_Cmd(TIM4, ENABLE); }int main(){ int possition; char str[120]; uint8_t sensor = 0; SystemInit(); TM_DELAY_Init(); /* Initialize USART, TX: PB6 */ TM_USART_Init(USART1, TM_USART_PinsPack_2, 9600); /* Display message to user */ TM_USART_Puts(USART1, ''Hall sensor is ready to use!\n''); /* Sensor K */ sensor = 1; while(1){ /* Every 500ms */ if (TM_DELAY_Time() >= 500) { /* Reset time */ TM_DELAY_SetTime(0); if (sensor) { possition = TIM_GetCounter(TIM4); sprintf(str, ''Possition\n- %d\r\n'', possition); TM_USART_Puts(USART1, str); } } }}2015-12-12 08:19 AM
Maybe its also depents on the chip do you use!
The frequency of PC fans are 20-140Hz, you cant measure that with an input capture on a STM32F10xFor Low-density, Medium-density, High-density and Connectivity line devices,
the minimum frequency value to measure is 1100 Hz.
For Low-Density Value line, Medium-Density and High-Density Value line devices,
the minimum frequency value to measure is 366 Hz.
Found in:
\STM32\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\TIM\InputCapture
eadme.txt
2015-12-12 09:45 AM
you cant measure that with an input capture on a STM32F10x
That's only true for the example code. If you account for timer counter overflows or use a 32 bit timer, and do double precision arithmetic, lower frequencies can be measured. Cheers, Hal