cancel
Showing results for 
Search instead for 
Did you mean: 

Servo Motor Frequency and Duty Cycle Problems stm32f407

guray
Associate II
Posted on October 14, 2013 at 12:47

Hi,

I am trying to drive a servo motor(for this case, TowerPro MG90S), so I want to get 50 hz frequency and duty cycle between %5 and %10.

My board is STM32F407 Discovery.

I tried to change Peripheral Lib example a little bit. It says that APB1 frequency has prescaler other than 1, so it will be multiplied by 2. As I calculated, timer3 frequency has to be 84 Mhz in this case. Afterwards, I am setting prescaler value as 42-1=41 and ARR = 4000-1=3999.

The result is, servo is not driven. When I change prescaler as 84-1=83, it is working. So, Is Timer3clk 168Mhz? How can it be possible?

  TIM_TimeBaseStructure.TIM_Period = 3999;

  TIM_TimeBaseStructure.TIM_Prescaler = 83;

In the statuation that prescaler is 83 and ARR is 3999, the motor is driven. I assigned CCR values from 200 to 400. Here is another problem due to motor is turning about 90 degrees. When I changed it from about 150 to about 500, it is turning about 180 degrees. Firstly I am tried to arrange duty cycle between %5 and %10, secondly I found this numbers after a lot of attemptions.

I couldn't understand how it is working, can you help me to understand these?

Thanks for your time.

#stm32 #timer #pwm #discovery #output
6 REPLIES 6
Posted on October 14, 2013 at 13:21

So basic math issues here

With 42,4000 for a 84 MHz clock we have

84000000 / (42 * 4000) = 500 Hz?

What you really probably want is

84000000/ (84 * 20000) = 50 Hz

So a Prescaler of 84-1 to get your TIM clocking at 1 MHz (1 us ticks) and a Period of 20000-1 to get a TIM period at 50 Hz (20 ms ticks)

The value then written to Pulse (CCRx) then relects the ON TIME in microseconds, presumably something between 600 us (3%) and 2400 us (12%)? Right?

https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/%5bSTM32f4discovery%5dSome%20clarification%20about%20PWM&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&...

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
guray
Associate II
Posted on October 14, 2013 at 13:42

Hi,

Thanks for the correction, I changed my values with yours. I want to drive them using hardware pwm without interrupts, so I ported the codes in link:

  TIM_TimeBaseStructure.TIM_Period = 20000-1;

  TIM_TimeBaseStructure.TIM_Prescaler = 84-1;

I assigned CCR values in the range of 1000 and 2000. But now the servo is not running.

I found a code running with this values:

    TIM_TimeBaseStructure.TIM_Period=400;

    TIM_TimeBaseStructure.TIM_Prescaler=839;

In this code, 84000000/840 gives 100000 and 100000/400 gives 250 Hz. I cant understand why servo is working with this.

Posted on October 14, 2013 at 14:01

I cant understand why servo is working with this.

Yes, well then you'll need to put a scope on the pin and see what signal you're actually generating. It could be you are not clocking the STM32F4 at the speed you think you are. I don't have a spec sheet for the servo.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
guray
Associate II
Posted on October 14, 2013 at 14:07

Thanks, this week is holiday on my country, I dont have a scope or logic analyzer with me for now. In a couple of days I will check the output with a scope and write the results.

Posted on October 14, 2013 at 14:32

You could benchmark the clock using the RTC, or blinking an LED at 1 Hz.

Check also HSE_VALUE reflects the 8 MHz used by the STM32F4-Discovery boards, and the PLL/clock settings in system32_stm32f4xx.c
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
guray
Associate II
Posted on October 14, 2013 at 15:51

Hi, I spend some time debugging and realized that the system uses HSI as clock source. So it explains why it is working at 16Mhz instead of 84 Mhz.

I called SystemCoreClockUpdate() function in the system_stm32f4xx.c file, afterwards see that tmp variable is set as ''0''.

I dont know why it is not starting with external osilator and not using pll, so I will learn how to change it to use HSE at 168Mhz.

Thank you for your time.