Skip to main content
Visitor II
March 17, 2010
Question

PWM input capture

  • March 17, 2010
  • 11 replies
  • 4288 views
Posted on March 17, 2010 at 08:23

Hello,

I'm attempting to design a stabilization system for a hobby level RC-UAV, using stm8s Discovery dev board.

Right Now I'm just trying to get the mcu to:

1)Capture the input signals on-time and off-time, and store them in respective variables.

2)Output a PWM signal that identical to the input, as well as adjust the on-time and off-time to match.

So far I haven't had any success, if anybody has any suggestions or advice it would be much appreciated. The code that I have gotten the closest to working is the TIM1 or 2 Input capture example included with the firmware. Here's a copy of the portion I use.

/**

  ******************************************************************************

  * @file TIM2_Input_Capture\main.c

  * @brief This file contains the main function for TIM2 Input Capture example.

  * @author STMicroelectronics - MCD Application Team

  * @version V1.1.1

  * @date 06/05/2009

  ******************************************************************************

  *

  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS

  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE

  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY

  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING

  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE

  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.

  *

  * <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>

  * @image html logo.bmp

  ******************************************************************************

  */

/* Includes ------------------------------------------------------------------*/

#include ''stm8s.h''

/**

  * @addtogroup TIM2_Input_Capture

  * @{

  */

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

#define TIM2ClockFreq  ((u32)2000000)

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

u32 LSIClockFreq = 0;

u16 ICValue1 =0, ICValue2 =0;

void main(void)

{

 

    /* Capture only every 8 events!!! */

  /* Enable capture of TI1 */

    TIM2_ICInit(TIM2_CHANNEL_1, TIM2_ICPOLARITY_FALLING, TIM2_ICSELECTION_DIRECTTI, TIM2_ICPSC_DIV8, 0x00);

 

    /* Enable CC1 interrupt */

    TIM2_ITConfig(TIM2_IT_CC1, ENABLE);

   

    /* Enable TIM2 */

  TIM2_Cmd(ENABLE);

       

    /* Clear CC1 Flag*/

  TIM2_ClearFlag(TIM2_FLAG_CC1);

 

    /* Connect LSI to COO pin*/

  GPIO_Init(GPIOE, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);

    CLK_CCOConfig(CLK_OUTPUT_LSI);

    CLK_CCOCmd(ENABLE);

   

   

    /* wait a capture on CC1 */

  while((TIM2->SR1 & TIM2_FLAG_CC1) != TIM2_FLAG_CC1);

  /* Get CCR1 value*/

    ICValue1 = TIM2_GetCapture1();

    TIM2_ClearFlag(TIM2_FLAG_CC1);

 

    /* wait a capture on cc1 */

  while((TIM2->SR1 & TIM2_FLAG_CC1) != TIM2_FLAG_CC1);

  /* Get CCR1 value*/

    ICValue2 = TIM2_GetCapture1();

    TIM2_ClearFlag(TIM2_FLAG_CC1);

  /* Compute LSI clock frequency */

  LSIClockFreq = (8 * TIM2ClockFreq) / (ICValue2 - ICValue1);

 

    /* Insert a break point here */

  while (1);  

}

    This topic has been closed for replies.

    11 replies

    Visitor II
    March 26, 2010
    Posted on March 26, 2010 at 18:05

    Well I finally got the the code to work just the way I wanted to with a few minor issues but they are hardware related, and just in case someone wants to use the Discovery board for use in a remote control application, to capture the receivers pulses and then output them to servos or motor controls here is the code to date.

    #include ''stm8s.h''

    u16 CH1on =0, CH2on =0, CH3on = 0, CH4on = 0;

    u16 Throttle3 = 0, Rudder4 = 0, Rightmotor = 0, Leftmotor = 0, Frontmotor =0, Rearmotor = 0;

    u16 periodcount = 40100;

    void main(void){

       

        TIM1_DeInit();

           

        /* Enable capture*/

        TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0);

        TIM1_ICInit(TIM1_CHANNEL_2, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0);

        TIM1_ICInit(TIM1_CHANNEL_3, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0);

        TIM1_ICInit(TIM1_CHANNEL_4, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0);

           

        /*Set TIM1 SMCR register to trigger counter reset on Ch1 Rising Edge and falling edge*/

        TIM1->SMCR = 0x44;

           

        /* Enable TIM1 */

      TIM1_Cmd(ENABLE);

       

        /* Enable CC1, 2, 3, 4 interrupt */

        TIM1_ITConfig(TIM1_IT_CC1, ENABLE);

        TIM1_ITConfig(TIM1_IT_CC2, ENABLE);

        TIM1_ITConfig(TIM1_IT_CC3, ENABLE);

        TIM1_ITConfig(TIM1_IT_CC4, ENABLE);

           

        /* Clear CC1, 2, 3, 4 Flag*/

      TIM1_ClearFlag(TIM1_FLAG_CC1);

        TIM1_ClearFlag(TIM1_FLAG_CC2);

        TIM1_ClearFlag(TIM1_FLAG_CC3);

        TIM1_ClearFlag(TIM1_FLAG_CC4);

           

        /*Clear all of TIM2 and TIM3's bits*/

        TIM2_DeInit();

        TIM3_DeInit();

               

        for (;;){   

       

        while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);

      /* Get CCR1 value*/

        CH1on = TIM1_GetCapture1();

        TIM1_ClearFlag(TIM1_FLAG_CC1);

       

        while((TIM1->SR1 & TIM1_FLAG_CC2) != TIM1_FLAG_CC2);

      /* Get CCR2 value*/

        CH2on = TIM1_GetCapture2();

        TIM1_ClearFlag(TIM1_FLAG_CC2);

       

        while((TIM1->SR1 & TIM1_FLAG_CC3) != TIM1_FLAG_CC3);

      /* Get CCR3 value*/

        CH3on = TIM1_GetCapture3();

        TIM1_ClearFlag(TIM1_FLAG_CC3);

       

        while((TIM1->SR1 & TIM1_FLAG_CC4) != TIM1_FLAG_CC4);

      /* Get CCR4 value*/

        CH4on = TIM1_GetCapture4();

        TIM1_ClearFlag(TIM1_FLAG_CC4);

       

        /*Subtract CH2 on time from CH3 ontime to get CH3 correct ontime*/

        Throttle3 = (CH3on - CH2on);

       

        /*Subtract CH3 ontime from CH4 ontime to get CH4 true ontime*/

        Rudder4 = (CH4on - CH3on);

       

        /*Set Throttle3 to control all 4 motors throttle initially*/

        Rearmotor = Throttle3;

        Leftmotor = Throttle3;

        Rightmotor = Throttle3;

        Frontmotor = Throttle3;

       

        if ((CH2on < 2950) & (Throttle3 > 2180)){

            Rearmotor = (Throttle3 - (3000 - CH2on));

        } else if ((CH2on >3050) & (Throttle3 > 2180)){

            Frontmotor = (Throttle3 - (CH2on -3000));

        }

           

        if ((CH1on < 2950) & (Throttle3 > 2180)) {

            Leftmotor = (Throttle3 -(3000 - CH1on));

        }else if ((CH1on >3050) & (Throttle3 > 2180)) {

            Rightmotor = (Throttle3 - (CH1on -3000));

        }

       

        if ((Rudder4 < 2950) & (Throttle3 > 2180)){

            Leftmotor = (Throttle3 -(3000 - Rudder4));

            Rightmotor = (Throttle3 -(3000 - Rudder4));

        } else if ((Rudder4 > 3050) & (Throttle3 > 2180)){

            Rearmotor = (Throttle3 - (3000 - Rudder4));

            Frontmotor = (Throttle3 - (3000 - Rudder4));

        }

       

           

        /*Set TIM2 and TIM3 to run at 50Hz with a 2MHz clock pulse*/

         TIM2_TimeBaseInit(TIM2_PRESCALER_1, periodcount);   

        TIM3_TimeBaseInit(TIM3_PRESCALER_1, periodcount);

       

        // Initialise output channel 1 and 3 of TIM2 to control the left and right motors.

      TIM2_OC3Init(TIM2_OCMODE_PWM2, TIM2_OUTPUTSTATE_ENABLE, Frontmotor, TIM2_OCPOLARITY_LOW);

      TIM2_OC1Init(TIM2_OCMODE_PWM2, TIM2_OUTPUTSTATE_ENABLE, Leftmotor, TIM2_OCPOLARITY_LOW);   

     

        // Enable TIM2.

      TIM2_Cmd(ENABLE);

               

        // Initialise output channel 1 and 2 of TIM3 to control the front and rear motors.

      TIM3_OC1Init(TIM3_OCMODE_PWM2, TIM3_OUTPUTSTATE_ENABLE, Rightmotor, TIM3_OCPOLARITY_LOW);

      TIM3_OC2Init(TIM3_OCMODE_PWM2, TIM3_OUTPUTSTATE_ENABLE, Rearmotor, TIM3_OCPOLARITY_LOW);   

     

        // Enable TIM3.

      TIM3_Cmd(ENABLE);

        }

    }