I am using a MC9S12DT256 with an E-clock of 8MHz, 8bit PWM.
the servo motor requires a period of 20ms with a minimum pulse of 0.7ms and a max pulse of 2.5ms.
The problem is that when I hook it up to the motor it just rotate left a little. (same rotation at 0.7ms and 2.5ms)
I can't seem to see where my code or calculations went wrong.
I divided the 8Mhz clock by 10 to get 0.8MHz(Scaled A), then divided that by 64 to get 12500HZ.
I want a 20ms period for the motor so my period register will be:
0.020=(1/12500)*PWMPERx which gives PWMPERx=250
Then for the duty register I want 0.8ms out of 20 ms period which is a duty of 4%
so 0.04=(250-PWMDTY0)/250
PWMDTY=240
Any help is much appreciated.
Here is my code:
================================================
#include <hidef.h>
#include "derivative.h"
#include <mc9s12dt256.h>
void main(void) {
PWMCTL=0x00; // 8bit pwm
PWMSCLA=0x05; // A/(2*5) =SA
PWMSCLB=0x05; // B/(2*5) =SB
PWMCLK=0xff; // select scaled clock
PWMPOL=0x00; // start low
PWMPRCLK=0x06; // SA/64 = clock
PWMCAE=0x00; // left aligned
PWME=0xff; // PWM enabled
PWMPER0=0xfa; // 20ms=250/12500
PWMDTY0=0xf0;
EnableInterrupts;
_FEED_COP();
}
}
================================================
Hello, and welcome to the forum.
My understanding of the servo device that you are using is that the pulse repetition interval is non-critical, but the rotation position of the servo is determined by the absolute period of the each pulse (between the limits 700 - 2500 microseconds). This means that the PWM duty cycle will fall within the range 3.5 - 12.5 percent. If using the PWM module in 8-bit mode this will severely limit the servo position resolution to about 23 steps. To achieve reasonable resolution will require that pairs of PWM channels will need to be configured to operate in 16-bit mode.
Aternatively, you might consider using the ECT module to generate the accurately timed pulses, with the pulse repetition rate perhaps determined by a periodic counter overflow condition.
Regards,
Mac
Thanks for your help.
This time, I make another source by using 16-bit PWM. But still doesn't working.
This is my new code. I can't find any wrong part.
=========================
PWMCTL=0x10; // 16-bit (ch0 & ch1)
PWMCLK=0x00; // select clk A
PWMPOL=0x02; // Polarity
PWMPRCLK=0x06; // 8MHz / 64 = 125000Hz
PWMCAE=0x00;
PWMSCLA=0x00;
PWME=0x02; // PWM Enabled
PWMPER0=0x09; // PWM period = 2500
PWMPER1=0xc3;
PWMDTY0=0x00; // PWM duty=63 ( for 2.5% duty cycle)
PWMDTY1=0x3f;
========================
Hello,
Do you have any output pulses at all? If so, I suggest that you check the pulse timing using an oscilloscope. This may better reveal why the servo is not operating correctly. Also is the output pulse of the correct polarity required by the servo?
I notice that you have setup a pulse width of 500 microseconds. This is somewhat below the lower limit of the servo that you previously stated. I might suggest that you start off with a mid-range value, such as 1500 microseconds.
It may also be useful to increase the clock frequency, by reducing the prescale divider. This would further increase the resolution. Perhaps a clock frequency of 1 MHz so that all period values are expressed directly in microseconds.
Regards,
Mac
The problem get solved.
I certainly appreciate your helping me out. : )