AnsweredAssumed Answered

[STM32f4discovery]Some clarification about PWM

Question asked by fante.lesto on Apr 11, 2013
Latest reply on Jan 28, 2014 by ti.teo
hello,
reading around the forum i comed up with the following code. my question are in the code comments, if someone can point me in the right direction i'll be glad.

This code will be used to move 4 ESC, so the generated pulse should be similar to analogic servo, PWM @50Hz, duty cicle high from 1 to 2ms with ~10us precision


{code}
volatile uint16_t position[] = { 1000, 1000, 1000, 1000 }; //from 1000 to 2000


void TIM3_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);


    // minimum high of 600 us for -90 degrees, with +90 degrees at 2400 us, 10 us per degree
    //  timer timebase set to us units to simplify the configuration/math


    TIM3->CCR1 = position[0]; //PB0
    TIM3->CCR2 = position[1]; //PB1
    TIM3->CCR3 = position[2]; //PB4
    TIM3->CCR4 = position[3]; //PB5
  }
}


void startPWM(){


     /*
      * BASED ON https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32VLDiscovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32VLDiscovery/Servo%20control%20using%20STM32VLDiscovery&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000491D59B8574F8049B5DFA3E8B21CBA51&TopicsView=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32VLDiscovery/AllItems.aspx&currentviews=397
      * THANKS to Clive1
      * */


     // clock for GPIO and AFIO (Remap) - WHY THIS?
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
     // clock for TIM3 - HERE DO WE ENABLE TIM3 HW?
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);


     // PIN SETUP
     GPIO_InitTypeDef GPIO_InitStructure;
     GPIO_StructInit(&GPIO_InitStructure); //Reset init structure
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOB, &GPIO_InitStructure);


     //THIS?
     GPIO_PinRemapConfig( GPIO_FullRemap_TIM3, ENABLE );        // Map TIM3_CH3 to GPIOB.Pin0, GPIOB.Pin1, GPIOB.Pin4, GPIOB.Pin5


     //OR THIS?
     //GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3);
     //GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM3);
     //GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_TIM3);
     //GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_TIM3);




     //TIMER INTERRUPT SETUP
     NVIC_InitTypeDef NVIC_InitStructure;


     // Configure the NVIC Preemption Priority Bits
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);


     // Enable the TIM3 Interrupt
     NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);




     //TIMER SETUP
     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
     TIM_TimeBaseStructInit( &TIM_TimeBaseStructure ); // Reset init structure


     // Simplify the math here so TIM_Pulse has 1 us units
     // PWMFreq = SystemCoreClock / ((TIM_Prescaler + 1) * (TIM_Period + 1));
     
     // NOT VERY SURE THE TIM3 RUN AT 24MHz....
     
     TIM_TimeBaseStructure.TIM_Prescaler = 24 - 1;  // 24 MHz / 24 = 1 MHz
     TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20 ms)
     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);


     TIM_OCInitTypeDef TIM_OCInitStructure;
     TIM_OCStructInit( &TIM_OCInitStructure );


     // PWM1: Channel1, PB0
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
     TIM_OCInitStructure.TIM_Pulse = position[0];
     TIM_OC1Init(TIM3, &TIM_OCInitStructure);


     // PWM1: Channel2, PB1
     TIM_OCInitStructure.TIM_Pulse = position[1];
     TIM_OC2Init(TIM3, &TIM_OCInitStructure);


     // PWM1: Channel3, PB4
     TIM_OCInitStructure.TIM_Pulse = position[2];
     TIM_OC3Init(TIM3, &TIM_OCInitStructure);


     // PWM1: Channel4, PB5
     TIM_OCInitStructure.TIM_Pulse = position[3];
     TIM_OC4Init(TIM3, &TIM_OCInitStructure);




     // ENABLE TIMER
     TIM_Cmd( TIM3, ENABLE );


    TIM_CtrlPWMOutputs(TIM3, ENABLE);


    // TIM IT enable
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
}
{/code}

ps. this is my very first code for this chip family, please be kind

Outcomes