Skip to main content
svarog995
Associate
July 29, 2013
Question

TIM4 CH3, CH2, CH1 now working

  • July 29, 2013
  • 8 replies
  • 1898 views
Posted on July 29, 2013 at 15:49

help again, I work with a four-timer but it does not work the channels one, two and three. I initialize them but they do not give a PWM.

CH4 working very good!

My code:

void init_pwm( void)

{

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure2;

    TIM_OCInitTypeDef       TIM_OCInitStructure;

    GPIO_InitTypeDef   GPIO_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);

    GPIO_InitStructure. GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;

    GPIO_InitStructure. GPIO_Mode = GPIO_Mode_AF ;

    GPIO_InitStructure. GPIO_Speed = GPIO_Speed_50MHz ;

    GPIO_InitStructure. GPIO_OType = GPIO_OType_PP ;

    GPIO_InitStructure. GPIO_PuPd = GPIO_PuPd_UP ;

    GPIO_Init(GPIOD, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_2);

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_2);

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_2);

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_2);

    TIM_TimeBaseStructure2. TIM_Period = 19999;

    TIM_TimeBaseStructure2. TIM_Prescaler = 72-1;

    TIM_TimeBaseStructure2. TIM_ClockDivision = 0;

    TIM_TimeBaseStructure2. TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure2);

    TIM_OCInitStructure. TIM_OCMode = TIM_OCMode_PWM1;

    TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure. TIM_Pulse = START;

    TIM_OCInitStructure. TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OC1Init(TIM4, &TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Disable);

    TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure. TIM_Pulse = START;

    TIM_OC2Init(TIM4, &TIM_OCInitStructure);

    TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Disable);

    TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure. TIM_Pulse = START;

    TIM_OC3Init(TIM4, &TIM_OCInitStructure);

    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Disable);

    TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure. TIM_Pulse = START;

    TIM_OC4Init(TIM4, &TIM_OCInitStructure);

    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Disable);

    TIM_Cmd(TIM4, ENABLE);

}

#understand-your-tools
    This topic has been closed for replies.

    8 replies

    Tesla DeLorean
    Guru
    July 29, 2013
    Posted on July 29, 2013 at 17:44

    May be you have other issues.

    This works on all 4 channels for me

    // STM32 4-channel Servo Demo for 72 MHz STM32F3 Discovery - sourcer32@gmail.com
    #include ''stm32f3_discovery.h''
    /**************************************************************************************/
    // Integers, or scaled integers (*10) will be more efficient here
    volatile float servo_angle[4] = { 0.0, 0.0, 0.0, 0.0 }; // +/- 0 degrees
    void TIM4_IRQHandler(void)
    {
    if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
    {
    TIM_ClearITPendingBit(TIM4, 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
    TIM_SetCompare1(TIM4, 1500 + (int)(servo_angle[0] * 0f) ); // PD.12
    TIM_SetCompare2(TIM4, 1500 + (int)(servo_angle[1] * 0f) ); // PD.13
    TIM_SetCompare3(TIM4, 1500 + (int)(servo_angle[2] * 0f) ); // PD.14
    TIM_SetCompare4(TIM4, 1500 + (int)(servo_angle[3] * 0f) ); // PD.15
    }
    }
    /**************************************************************************************/
    void RCC_Configuration(void)
    {
    /* --------------------------- System Clocks Configuration -----------------*/
    /* TIM4 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    /* GPIOD clock enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
    }
    /**************************************************************************************/
    void NVIC_Configuration(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Enable the TIM4 gloabal Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    }
    /**************************************************************************************/
    void GPIO_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    /*-------------------------- GPIO Configuration ----------------------------*/
    /* GPIOD Configuration: Pins 12, 13, 14 and 15 in output push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    /* Connect TIM4 pins to AF2 */
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_2);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_2);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_2);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_2);
    }
    /**************************************************************************************/
    void TIM4_Configuration(void)
    {
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    /* Time base configuration - SystemCoreClock = 72000000 for 72 MHz board */
    TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock / 1000000) - 1); // Shooting for 1 MHz, (1us)
    TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20ms)
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
    /* Enable TIM4 Preload register on ARR */
    TIM_ARRPreloadConfig(TIM4, ENABLE);
    /* TIM PWM1 Mode configuration: Channel */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 1500; // Servo Top-Center
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    /* Output Compare PWM1 Mode configuration: Channel1 PD.12 */
    TIM_OC1Init(TIM4, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
    /* Output Compare PWM1 Mode configuration: Channel2 PD.13 */
    TIM_OC2Init(TIM4, &TIM_OCInitStructure);
    TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
    /* Output Compare PWM1 Mode configuration: Channel3 PD.14 */
    TIM_OC3Init(TIM4, &TIM_OCInitStructure);
    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
    /* Output Compare PWM1 Mode configuration: Channel4 PD.15 */
    TIM_OC4Init(TIM4, &TIM_OCInitStructure);
    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
    /* TIM Interrupts enable */
    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
    /* TIM4 enable counter */
    TIM_Cmd(TIM4, ENABLE);
    }
    /**************************************************************************************/
    int main(void)
    {
    RCC_Configuration();
    GPIO_Configuration();
    NVIC_Configuration();
    TIM4_Configuration();
    while(1)
    {
    // Add code to stroke servos here
    }
    }

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Tesla DeLorean
    Guru
    October 4, 2013
    Posted on October 04, 2013 at 21:42

    Add code to demo motion

    // STM32 4-channel Servo Demo for 72 MHz STM32F3 Discovery - sourcer32@gmail.com
    #include ''stm32f3_discovery.h''
    /**************************************************************************************/
    // Integers, or scaled integers (*10) will be more efficient here
    volatile float servo_angle[4] = { -0, -0, 0, 0 }; // +/- 0 degrees
    #define SLEWRATE (1.0 / 0) // slew 1 degree per second, 50 Hz update
    volatile float angle_delta[4] = { -SLEWRATE, -SLEWRATE, SLEWRATE, SLEWRATE };
    void TIM4_IRQHandler(void)
    {
    if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
    {
    int i;
    TIM_ClearITPendingBit(TIM4, 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
    TIM_SetCompare1(TIM4, 1500 + (int)(servo_angle[0] * 0f) ); // PD.12
    TIM_SetCompare2(TIM4, 1500 + (int)(servo_angle[1] * 0f) ); // PD.13
    TIM_SetCompare3(TIM4, 1500 + (int)(servo_angle[2] * 0f) ); // PD.14
    TIM_SetCompare4(TIM4, 1500 + (int)(servo_angle[3] * 0f) ); // PD.15
    // a quick hack to get the servo to stroke back and forth
    for(i=0; i<
    4
    ; i++)
    {
    servo_angle[i] += angle_delta[i];
    if ((servo_angle[i] >= 0f) || (servo_angle[i] <= -0f))
    {
    angle_delta[i] = -angle_delta[i]; // reverse
    servo_angle[i] += angle_delta[i];
    }
    }
    }
    }
    /**************************************************************************************/
    void RCC_Configuration(void)
    {
    /* --------------------------- System Clocks Configuration -----------------*/
    /* TIM4 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    /* GPIOD clock enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
    }
    /**************************************************************************************/
    void NVIC_Configuration(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Enable the TIM4 gloabal Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    }
    /**************************************************************************************/
    void GPIO_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    /*-------------------------- GPIO Configuration ----------------------------*/
    /* GPIOD Configuration: Pins 12, 13, 14 and 15 in output push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    /* Connect TIM4 pins to AF2 */
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_2);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_2);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_2);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_2);
    }
    /**************************************************************************************/
    void TIM4_Configuration(void)
    {
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_OCStructInit(&TIM_OCInitStructure);
    /* Time base configuration - SystemCoreClock = 72000000 for 72 MHz board */
    TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock / 1000000) - 1); // Shooting for 1 MHz, (1us)
    TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20ms)
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
    /* Enable TIM4 Preload register on ARR */
    TIM_ARRPreloadConfig(TIM4, ENABLE);
    /* TIM PWM1 Mode configuration: Channel */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 1500; // Servo Top-Center
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    /* Output Compare PWM1 Mode configuration: Channel1 PD.12 */
    TIM_OC1Init(TIM4, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
    /* Output Compare PWM1 Mode configuration: Channel2 PD.13 */
    TIM_OC2Init(TIM4, &TIM_OCInitStructure);
    TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
    /* Output Compare PWM1 Mode configuration: Channel3 PD.14 */
    TIM_OC3Init(TIM4, &TIM_OCInitStructure);
    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
    /* Output Compare PWM1 Mode configuration: Channel4 PD.15 */
    TIM_OC4Init(TIM4, &TIM_OCInitStructure);
    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
    /* TIM Interrupts enable */
    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
    /* TIM4 enable counter */
    TIM_Cmd(TIM4, DISABLE /*ENABLE*/);
    }
    /**************************************************************************************/
    int main(void)
    {
    RCC_Configuration();
    GPIO_Configuration();
    NVIC_Configuration();
    TIM4_Configuration();
    while(1); // Infinite Loop, work done under interrupt
    }

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    mubinyousuf
    Visitor II
    October 5, 2013
    Posted on October 05, 2013 at 03:13

    Thanks but i am getting this error

    Error[Li005]: no definition for ''SystemCoreClock'' [referenced from C:\Users\Mubin\Downloads\fromScratch\IAR\Debug\Obj\main.o]

    Tesla DeLorean
    Guru
    October 5, 2013
    Posted on October 05, 2013 at 03:26

    I'm not an IAR user, you will need to review the Template projects within the STM32F3-Discovery firmware library. Clone one of those and paste the example code into the ''main.c''component.

    If you build a project from scratch you're going to have to specify the include paths for the libraries, the defines used for the board, and drop/add the library source files into the project.

    SystemCoreClock should be exported from system_stm32f3xx.c
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    mubinyousuf
    Visitor II
    October 5, 2013
    Posted on October 05, 2013 at 03:31

    i fixed the systemcoreclock problem, but i am still at a dead end, still cant run my motor, thats what have been happening with my previous programs, i thought there must be something wrong with my code but i think its the hardware problem.

    Any suggestions tho?
    Tesla DeLorean
    Guru
    October 5, 2013
    Posted on October 05, 2013 at 03:59

    I would start by evaluating the signal with a scope. Then using a common ground with the servo, and the control signal from the appropriate GPIO pin.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    mubinyousuf
    Visitor II
    October 5, 2013
    Posted on October 05, 2013 at 04:08

    i am currently using the above program you wrote and using pin D14 i am driving the motor's pwm, the ground for the both motor and the board is common and the output at the programmed pins is a constant 2.94V.

    I erased the program from the chip, took voltage readings and found that the pins used for the output are giving constant 2.94 V when programmed and a 1.5 V when there is no program in the memory.
    Tesla DeLorean
    Guru
    October 5, 2013
    Posted on October 05, 2013 at 04:25

    I'd probably use the debugger, and confirm the code is actually running. Perhaps you could also toggle an LED, or otherwise indicate that initialization has completed.

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