Skip to main content
niklascooke1
Associate II
November 8, 2009
Question

Tim1 Input Capture PPM from a RC controller

  • November 8, 2009
  • 5 replies
  • 1774 views
Posted on November 08, 2009 at 14:38

Tim1 Input Capture PPM from a RC controller

    This topic has been closed for replies.

    5 replies

    niklascooke1
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:15

    Hi!

    Im wondering if anyone have done this on the Cortex M3 controller.

    TIM1 Input capture of a PPM signal from a RC controller?

    Any ideas?

    the pulse look like this. --|__|---|_|---|___|---

    I want to mesure from the falling edge.

    How to get the timevalue for the gaps and the time inbetween?

    Regards Niklas

    [ This message was edited by: niklascooke on 24-06-2009 01:54 ]

    thorsten2
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:15

    I found 2 mistake:

    /* TIM1 clock enable */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    /* [0xAC] TIM1 Capture/Compare Interrupt */

    void TIM1_CC_IRQHandler(void)

    the interrupt works - but the length is always 0

    Regards,

    Thorsten

    [ This message was edited by: thorsten.raab on 08-11-2009 12:51 ]

    thorsten2
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:15

    Hi Niklas,

    have you the PPM decode running with Timer1?

    I tried it, but it does not work :-?

    I like to use PA8 with Timer 1.

    I have changed:

    /* Enable the TIM1 global Interrupt */

    NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQChannel;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    void TIM1_IRQHandler(void)

    {

    if(TIM1_GetITStatus(TIM1_IT_CC2) == SET)

    {

    /* Clear TIM1 Capture compare interrupt pending bit */

    TIM1_ClearITPendingBit(TIM1_IT_CC2);

    //TIM_ClearITPendingBit(TIM1, TIM_IT_Update);

    TIM1_ClearFlag(TIM1_FLAG_CC2);

    GPIO_ResetBits(GPIOA, GPIO_Pin_8);

    // /* Get the Input Capture value */

    IC2Value = TIM1_GetCapture2();

    ....

    /* Timer for PPM decode */

    TIM1_ICInitTypeDef TIM1_ICInitStructure;

    //TIM_ICInitStructure.TIM_ICMode = TIM_ICMode_ICAP;

    TIM1_ICInitStructure.TIM1_Channel = TIM1_Channel_1; //Pin: PA8

    TIM1_ICInitStructure.TIM1_ICPolarity = TIM1_ICPolarity_Falling;

    TIM1_ICInitStructure.TIM1_ICSelection = TIM1_ICSelection_DirectTI;

    TIM1_ICInitStructure.TIM1_ICPrescaler = TIM1_ICPSC_DIV1;

    TIM1_ICInitStructure.TIM1_ICFilter = 0x0;

    TIM1_ICInit(&TIM1_ICInitStructure);

    TIM1_SelectInputTrigger(TIM1_TS_TI2FP2);

    TIM1_InternalClockConfig();

    TIM1_TimeBaseInitTypeDef TIM1_TimeBaseStructure;

    TIM1_TimeBaseStructure.TIM1_Period = 0xFFFF;

    TIM1_TimeBaseStructure.TIM1_Prescaler = 17; // fCK_PSC / (17 + 1) 1ms = 4000

    TIM1_TimeBaseStructure.TIM1_ClockDivision = TIM1_CKD_DIV1;

    TIM1_TimeBaseStructure.TIM1_CounterMode = TIM1_CounterMode_Up;

    TIM1_TimeBaseInit(& TIM1_TimeBaseStructure);

    /* TIM enable counter */

    TIM1_Cmd(ENABLE);

    /* Enable the CC2 Interrupt Request */

    TIM1_ITConfig(TIM_IT_CC2, ENABLE);

    /* Enable for PPM decode ---------*/

    /* TIM1 clock enable */

    RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    /* GPIOA clock enable */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    Many thanks for yout help!

    Best Regards,

    Thorsten

    [ This message was edited by: thorsten.raab on 08-11-2009 13:00 ]

    kounst
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:15

    Hi Niklas,

    maybe this program helps you. I think it does just what you want using Timer2.

    Regards,

    kounst

    void TIM2_Configuration(void)

    {

    TIM_ICInitTypeDef TIM_ICInitStructure;

    //TIM_ICInitStructure.TIM_ICMode = TIM_ICMode_ICAP;

    TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;

    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

    TIM_ICInitStructure.TIM_ICFilter = 0x0;

    TIM_ICInit(TIM2, &TIM_ICInitStructure);

    TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);

    TIM_InternalClockConfig(TIM2);

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    TIM_TimeBaseStructure.TIM_Period = 0xFFFF;

    TIM_TimeBaseStructure.TIM_Prescaler = 17; // fCK_PSC / (17 + 1) 1ms = 4000

    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM2, & TIM_TimeBaseStructure);

    /* TIM enable counter */

    TIM_Cmd(TIM2, ENABLE);

    /* Enable the CC2 Interrupt Request */

    TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);

    }

    void RCC_Configuration(void)

    {

    /* RCC system reset(for debug purpose) */

    RCC_DeInit();

    /* Enable HSE */

    RCC_HSEConfig(RCC_HSE_ON);

    /* Wait till HSE is ready */

    HSEStartUpStatus = RCC_WaitForHSEStartUp();

    if(HSEStartUpStatus == SUCCESS)

    {

    /* Enable Prefetch Buffer */

    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* Flash 2 wait state */

    FLASH_SetLatency(FLASH_Latency_2);

    /* HCLK = SYSCLK */

    RCC_HCLKConfig(RCC_SYSCLK_Div1);

    /* PCLK2 = HCLK */

    RCC_PCLK2Config(RCC_HCLK_Div1);

    /* PCLK1 = HCLK/2 */

    RCC_PCLK1Config(RCC_HCLK_Div2);

    /* PLLCLK = 12MHz * 6 = 72 MHz */

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_6);

    /* Enable PLL */

    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

    {

    }

    /* Select PLL as system clock source */

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */

    while(RCC_GetSYSCLKSource() != 0x08)

    {

    }

    }

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    }

    void NVIC_Configuration(void)

    {

    NVIC_InitTypeDef NVIC_InitStructure;

    #ifdef VECT_TAB_RAM

    /* Set the Vector Table base location at 0x20000000 */

    NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

    #else /* VECT_TAB_FLASH */

    /* Set the Vector Table base location at 0x08000000 */

    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

    #endif

    /* Enable the TIM2 global Interrupt */

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    }

    /*******************************************************************************

    * Function Name : TIM2_IRQHandler

    * Description : This function handles TIM2 global interrupt request.

    * Input : None

    * Output : None

    * Return : None

    *******************************************************************************/

    void TIM2_IRQHandler(void)

    {

    if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)

    {

    /* Clear TIM2 Capture compare interrupt pending bit */

    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

    //TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

    TIM_ClearFlag(TIM2, TIM_FLAG_CC2);

    GPIO_ResetBits(GPIOA, GPIO_Pin_0);

    // /* Get the Input Capture value */

    IC2Value = TIM_GetCapture2(TIM2);

    vu16 length = IC2Value - lastIC2Value;

    if(length > 20000)

    channel = 0;

    switch(channel)

    {

    case 1:

    pulswidth.pw1 = length;

    break;

    case 2:

    pulswidth.pw2 = length;

    break;

    case 3:

    pulswidth.pw3 = length;

    break;

    case 4:

    pulswidth.pw4 = length;

    break;

    case 5:

    pulswidth.pw5 = length;

    break;

    case 6:

    pulswidth.pw6 = length;

    break;

    case 7:

    pulswidth.pw7 = length;

    break;

    // case 8:

    // pulswidth.pw8 = length;

    // break;

    // case 9:

    // pulswidth.pw9 = length;

    // break;

    default:

    channel = 0;

    break;

    }

    lastIC2Value = IC2Value;

    if(channel == 6) GPIO_SetBits(GPIOA, GPIO_Pin_0); else GPIO_ResetBits(GPIOA, GPIO_Pin_0);

    channel++;

    }

    }

    thorsten2
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:15

    Hi,

    ok, now it works :D

    I have to use TIM1_IT_CC1

    Here the complete codeparts:

    /* Enable for PPM decode -------------------------------------------*/

    /* TIM1 clock enable */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    /* GPIOA clock enable */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    /* Timer for PPM decode ---------------------------------------------------*/

    TIM1_ICInitTypeDef TIM1_ICInitStructure;

    //TIM_ICInitStructure.TIM_ICMode = TIM_ICMode_ICAP;

    TIM1_ICInitStructure.TIM1_Channel = TIM1_Channel_1; //Pin: PA8

    TIM1_ICInitStructure.TIM1_ICPolarity = TIM1_ICPolarity_Falling;

    TIM1_ICInitStructure.TIM1_ICSelection = TIM1_ICSelection_DirectTI;

    TIM1_ICInitStructure.TIM1_ICPrescaler = TIM1_ICPSC_DIV1;

    TIM1_ICInitStructure.TIM1_ICFilter = 0x0;

    TIM1_ICInit(&TIM1_ICInitStructure);

    TIM1_SelectInputTrigger(TIM1_TS_TI2FP2);

    TIM1_InternalClockConfig();

    TIM1_TimeBaseInitTypeDef TIM1_TimeBaseStructure;

    TIM1_TimeBaseStructure.TIM1_Period = 0xFFFF;

    TIM1_TimeBaseStructure.TIM1_Prescaler = 17; // fCK_PSC / (17 + 1) 1ms = 4000

    TIM1_TimeBaseStructure.TIM1_ClockDivision = TIM1_CKD_DIV1;

    TIM1_TimeBaseStructure.TIM1_CounterMode = TIM1_CounterMode_Up;

    TIM1_TimeBaseInit(& TIM1_TimeBaseStructure);

    /* TIM enable counter */

    TIM1_Cmd(ENABLE);

    /* Enable the CC1 Interrupt Request */

    TIM1_ITConfig(TIM_IT_CC1, ENABLE);

    /* Configure PA8 for PPM Dekode -----------------------------------------*/

    /* TIM1 channel 1 pin (PA.08) configuration */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Enable the TIM1 global Interrupt ------------------------------*/

    NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQChannel;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    /* [0xAC] TIM1 Capture/Compare Interrupt --------------------*/

    void TIM1_CC_IRQHandler(void)

    {

    if(TIM1_GetITStatus(TIM1_IT_CC1) == SET)

    {

    /* Clear TIM1 Capture compare interrupt pending bit */

    TIM1_ClearITPendingBit(TIM1_IT_CC1);

    //TIM_ClearITPendingBit(TIM1, TIM_IT_Update);

    TIM1_ClearFlag(TIM1_FLAG_CC1);

    GPIO_ResetBits(GPIOA, GPIO_Pin_8);

    // /* Get the Input Capture value */

    IC2Value = TIM1_GetCapture1();

    //vu16 length = IC2Value - lastIC2Value;

    vu16 length = IC2Value - lastIC2Value;

    ...

    ...

    lastIC2Value = IC2Value;

    if(channel == 6) GPIO_SetBits(GPIOA, GPIO_Pin_8); else GPIO_ResetBits(GPIOA, GPIO_Pin_8);

    channel++;

    ...

    Regards,

    Thorsten