cancel
Showing results for 
Search instead for 
Did you mean: 

Hall-effect sensor

thewizzard
Associate
Posted on May 27, 2013 at 21:04

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
12 REPLIES 12
vimukthi_0123
Associate II
Posted on April 03, 2015 at 16:24

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 inputs

RCC_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);

}

}

}

}

interrobang
Associate
Posted on December 12, 2015 at 17:19

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 STM32F10x

For 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
raptorhal2
Lead
Posted on December 12, 2015 at 18:45

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