Skip to main content
ataberktopcuuu
Associate II
October 6, 2016
Question

Not true pwm signal as in code which ı write in stm32f4vg

  • October 6, 2016
  • 5 replies
  • 1005 views
Posted on October 06, 2016 at 15:27

Hİ GUYS, I trying to use sg90 servo motors.As following code,Systemclock is 168Mhz. I divided clock of timer4 by 4 and then calculate pwm as 50 hz. But logic analyzer show 99hz. So my servo dont work. Can any one help me about that?

/**
* * * * * * * * * * * * * SERVO PROJECT * * * * * * * * * * * * * * * * *
*@brief use servo motor SG90 with pwm to turn 90 and 180 degree *
*@author ATABERK TOPÇU *
* *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
#include ''stm32f4xx.h'' // Device header
int main()
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
SystemInit();
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
/** @brief MAKE GPIO CONFIGURATION FOR SETTING OUTPUTS PINS */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4);
GPIO_Init(GPIOB,&GPIO_InitStructure);
/** @brief MAKE TIMER CONFIGURATION FOR USE PWM */
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV4;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 19999;
TIM_TimeBaseInitStructure.TIM_Prescaler = 42-1;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
TIM_Cmd(TIM4,ENABLE);
/** @brief TIMER OUTPUT COMPARE FOR FREQUENCY AND PERIPOD OF PWM*/
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState =TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_Pulse = 1999;
TIM_OC1Init(TIM4,&TIM_OCInitStructure);
TIM_CtrlPWMOutputs(TIM4,ENABLE);
TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);
while(1);
}

    This topic has been closed for replies.

    5 replies

    Nesrine M_O
    Associate
    October 6, 2016
    Posted on October 06, 2016 at 16:03

    Hi Ataberk,

    I recommend you to have a look to the TIM example under the

    http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-libraries/stsw-stm32065.html

    it may be helpful.

    STM32F4xx_DSP_StdPeriph_Lib_V1.7.1\Project\STM32F4xx_StdPeriph_Examples\TIM\TIM_7PWMOutputThis example shows how to configure the TIM1 peripheral to generate 7 PWM signals with 4 different duty cycles (50%, 37.5%, 25% and 12.5%).

    TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock (SystemCoreClock is set to 168 MHz for STM32F4xx devices).

    -Syrine-

    Walid FTITI_O
    Visitor II
    October 6, 2016
    Posted on October 06, 2016 at 17:14

    Hi Ataberk, 

    You should pay attention to the system clock configuration and the Timer clock configuration. As first step , you should well configure the system clock by putting the right prescaler of each bus (AHB, APB1 and ABP2) . In you case , Timer4 is on ABP1 which clock should be : APB1_clock = PCLK1= HCLK /4 = 42 MHz

    The Timer clock input is by default TIM3CLK = PCLK1 = 42MHz

    Then to get the 50 Hz Timer output , you should focus on both period and prescaler formulas:

    Periode= ARR = (TIM3 counter clock / TIM3 output clock) - 1

    Prescaler = PSC = (TIM3CLK / TIM3 counter clock) - 1

    So let's take a possible configuration example :

    To get TIM3 counter clock = 30000 Hz

    We need ARR= (TIM3 counter clock / 30000) - 1

                   For PSC= 0 -> TIM3 counter clock = TIM3CLK = 42 MHz

                        -> ARR= (42000000 / 30000) -1 = 1400 -1

    In your code you can replace TIM3 counter clock with SystemCoreClock 

    So we have in code:

    Period = (SystemCoreClock / 30000) - 1;

    Prescaler= 0;

    ClockDivision=0;

    You may refer to the Timer examples on standard peripheral library or STM32Cube library.

    There are helpful application note line

    http://www.st.com/content/ccc/resource/technical/document/application_note/group0/91/01/84/3f/7c/67/41/3f/DM00236305/files/DM00236305.pdf/jcr:content/translations/en.DM00236305.pdf

    describes many features on Timers and shows different configuration. And of course, the reference manual still always first source of information.

    -Hannibal-

    Tesla DeLorean
    Guru
    October 6, 2016
    Posted on October 06, 2016 at 17:28

    TIM_TimeBaseInitStructure.TIM_ClockDivision     =  TIM_CKD_DIV4; // This doesn't do what you seem to think it does.

    Only Prescaler and Period define what the output frequency are.

    I can't get to 31.99 Hz from the math, so it suggests the part isn't actually running at 168 MHz. Suggest you revisit the PLL settings, and output the actual clock via MCO (PA8)

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    ataberktopcuuu
    Associate II
    October 7, 2016
    Posted on October 07, 2016 at 08:33

    Well what do clock divison timer do? Does it divide clock which come to timer?

    ataberktopcuuu
    Associate II
    October 7, 2016
    Posted on October 07, 2016 at 08:35

    Well what do clock divison timer do? Does it divide clock which come to timer?