AnsweredAssumed Answered

Can't produce 20 ms PWM for servo

Question asked by nyan on Oct 25, 2016
Latest reply on Oct 26, 2016 by Clive One
Hi. I am quite new to STM32. 
I would like to produce 20ms square PWM with adjustable duty cycle for controlling 2 servo position. 

MCU = stm32f103ret6      Using GNU ARM toolchain on Eclipse cdt. 
Use Timer5 Ch1,2 (PA0, PA1 for servo signal). 

Here is the code I write so far. 


//     For GPIO Initialization
void GPIO_Init_Mode_50MHz(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIOMode_TypeDef mode) {
      GPIO_InitTypeDef GPIO_InitStructure;
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
     GPIO_InitStructure.GPIO_Mode = mode;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOx, &GPIO_InitStructure);
}


void InitTimer5_servoPWM(bool bCH1, bool bCH2){
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;ss


     /* TIM5 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);


     /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = 63;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = 20000;          // period in usec


    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;


    TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);


    /* Output Compare Active Mode configuration: Channel1 */
    TIM_OCStructInit(&TIM_OCInitStructure);
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;




    RCC_AHBPeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
     //Timer5_CH1(PA0) Timer5_CH2(PA1)
    if (bCH1) {


         GPIO_Init_Mode_50MHz(GPIOA, GPIO_Pin_0, GPIO_Mode_AF_PP);
         /* Output Compare Timing Mode configuration: Channel1 */
         TIM_OC1Init(TIM5, &TIM_OCInitStructure);
         TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);
         TIM5->CCR1 = 0;
    }


    if (bCH2) {
         GPIO_Init_Mode_50MHz(GPIOA, GPIO_Pin_1, GPIO_Mode_AF_PP);
            /* Output Compare Timing Mode configuration: Channel1 */
         TIM_OC2Init(TIM5, &TIM_OCInitStructure);
         TIM_OC2PreloadConfig(TIM5, TIM_OCPreload_Enable);
         TIM5->CCR2 = 0;
    }


    TIM_ARRPreloadConfig(TIM5, ENABLE);


    // output enable for TIM5 only
    TIM_CtrlPWMOutputs(TIM5, ENABLE);
    TIM_Cmd(TIM5, ENABLE);
 }
 
 // For changing dutycycle
 void SetTimer5PWM(int16_t ch, int16_t pwm) {
     switch(ch) {
     case 1 : TIM5->CCR1 = pwm; break;
     case 2 : TIM5->CCR2 = pwm; break;
     }
}


Attachments

Outcomes