cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with input capture on Nucleo152RE

marcogrossi89
Associate II
Posted on December 04, 2015 at 16:46

I am working on a Nucleo152RE using EmBitz. The code generates a PWM signal (200Hz 50% duty-cycle) on PB8 (TIM4 channel 3) (It works, I tested with an oscilloscope), then gives this signal as input to PC6 (TIM3 channel 1) and uses TIM3 in input capture mode to measure the frequency of the signal. The frequency is then displayed on a LCD (the code for the LCD works).

The code for input capture is copied from an ST example. However, the value displayed on the LCD is not correct.

Following is the code (the LCD code is omitted).

#include ''stm32l1xx_conf.h''

#include ''lcd_hd4478.h''

volatile uint8_t phase;

volatile uint16_t Capture1, Capture2;

volatile uint32_t Capture, freq_int, freq_int2;

uint8_t digit0,digit1,digit2,digit3;

char freq_str[4];

static void my_delay(__IO uint32_t nCount2);

void GPIO_initialization(void);

void Initialize_Timer_PWM_out(void);

void Initialize_Timer_IC(void);

int main(void)

{

  my_delay(5250);

  LCD_Initialize();

  LCD_Clear_Screen();

  LCD_Write_String('' FREQUENCY (HZ) '', 0, 0);

  phase=0;

  GPIO_initialization();

  Initialize_Timer_PWM_out();

  Initialize_Timer_IC();

  while(1)

  {

     my_delay(5250);

     freq_int = freq_int2;

     digit3 = (uint8_t)(freq_int/1000);

     if (digit3 == 0)

         freq_str[0]=' ';

     else

         freq_str[0]=digit3+48;

     digit2 = (uint8_t)(freq_int - 1000*digit3)/100;

     freq_str[1]=digit2+48;

     digit1 = (uint8_t)(freq_int - 1000*digit3 - 100*digit2)/10;

     freq_str[2]=digit1+48;

     freq_str[3]='.';

     digit0 = (uint8_t)(freq_int - 1000*digit3 - 100*digit2 - 10*digit1);

     freq_str[4]=digit0+48;

     LCD_Write_String(freq_str, 1, 5);

  }

}

static void my_delay(__IO uint32_t nCount2)

{

  __IO uint32_t index_new = 0;

  for(index_new = (0xFF * nCount2); index_new != 0; index_new--)

  {

  }

}

void GPIO_initialization(void)

{

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE);

GPIO_InitTypeDef gpioStructure;

     gpioStructure.GPIO_Pin = GPIO_Pin_8;

     gpioStructure.GPIO_Mode = GPIO_Mode_AF;

     gpioStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

     gpioStructure.GPIO_Speed = GPIO_Speed_2MHz;

     GPIO_Init(GPIOB, &gpioStructure);

     gpioStructure.GPIO_Pin = GPIO_Pin_6;

     gpioStructure.GPIO_Mode = GPIO_Mode_AF;

     gpioStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

     gpioStructure.GPIO_Speed = GPIO_Speed_2MHz;

     GPIO_Init(GPIOC, &gpioStructure);

     GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM4);

     GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);

}

void Initialize_Timer_PWM_out(void)

{

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

TIM_TimeBaseInitTypeDef timerInitStructure;

TIM_OCInitTypeDef  timer_OCInitStructure;

timerInitStructure.TIM_Prescaler = 1600-1; // 32MHz / 1600 = 20kHz

timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;

timerInitStructure.TIM_Period = 100-1;

timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM4, &timerInitStructure);

    timer_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

    timer_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

    timer_OCInitStructure.TIM_Pulse = 50;

    // TIM_OCPolarity_High -> Output High if TIM2 value < TIM_Pulse

    // TIM_OCPolarity_Low -> Output High if TIM2 value > TIM_Pulse

    timer_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OC3Init(TIM4, &timer_OCInitStructure);

TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);

TIM_Cmd(TIM4, ENABLE);

}

void Initialize_Timer_IC(void)

{

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

TIM_TimeBaseInitTypeDef timerInitStructure;

TIM_ICInitTypeDef  timer_ICInitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

timerInitStructure.TIM_Prescaler = 32-1; // 32MHz / 32 = 1MHz Tclk,timer = 1us

timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;

timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM3, &timerInitStructure);

    timer_ICInitStructure.TIM_Channel=TIM_Channel_1;

    timer_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;

    timer_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

    timer_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

    timer_ICInitStructure.TIM_ICFilter = 0x0;

    TIM_ICInit(TIM3, &timer_ICInitStructure);

TIM_Cmd(TIM3, ENABLE);

TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

void TIM3_IRQHandler(void)

{

  if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)

  {

    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);

    if(phase == 0)

    {

      Capture1 = TIM_GetCapture1(TIM3);

      phase = 1;

    }

    else if(phase == 1)

    {

      Capture2 = TIM_GetCapture1(TIM3);

      if (Capture2 > Capture1)

      {

        Capture = (Capture2 - Capture1) - 1;

      }

      else if (Capture2 < Capture1)

      {

        Capture = ((0xFFFF - Capture1) + Capture2) - 1;

      }

      else

      {

        Capture = 0;

      }

      freq_int2=(uint32_t)(100000/Capture);

      phase = 0;

    }

  }

}

4 REPLIES 4
Posted on December 04, 2015 at 23:09

So what happens when Capture is zero? The math in your measurement is horribly broken.

else if(phase == 1)
{
Capture2 = TIM_GetCapture1(TIM3);
Capture = (Capture2 - Capture1) ;
if (Capture)
freq_int2= 1000000 / (uint32_t)Capture; // It's 1 MHz, right?
else
freq_int2=0
phase = 0;
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
marcogrossi89
Associate II
Posted on December 05, 2015 at 11:18

Corrected the code for the case Capture=0.

In the case Capture!=0 however the code is

freq_int2= 100000 / (uint32_t)Capture;

freq_int2 is ten times the real frequency since I want to measure also the 0.1Hz

However it still does not work. The measured frequency is always 0Hz and sometimes 0.1Hz.

Posted on December 05, 2015 at 13:30

Make sure to properly initialize the timebase, currently random stack junk

timerInitStructure.TIM_Period = 0xFFFF; // 16-bit maximal

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on December 05, 2015 at 15:31

freq_int2 is ten times the real frequency since I want to measure also the 0.1Hz

Then surely you'd need to divide INTO 10 Million, not 100 Thousand?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..