View previous topic :: View next topic |
Author |
Message |
GREGORYG Guest
|
5 pwm with 18f4331 pic |
Posted: Tue Dec 30, 2008 9:23 am |
|
|
hello,
I need to produce 5 independent pwm to control 5 servo motors.
I am working with 18f4331 pic and from what i understand it has 4 pairs of pwm so i can make only 4 independent signals.
my question is if i can use also the ccp output for my fifth pwm?
tnx |
|
|
Guest
|
|
Posted: Tue Dec 30, 2008 2:42 pm |
|
|
Are these RC model type servos? If so then you can mimic the action of a normal RC receiver - these do not use PWM but sequentially scan each servo in a 50 or 60 Hz scan rate. On each scan the pulse position is changed to each servo as required. 50 or 60 Hz is fast enough to make the action look continuous. This is called Pulse Position Modulation and I know you can find more information on Google. Search: PIC RC Servo
HTH - Steve H. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 30, 2008 6:51 pm |
|
|
Here is a demo program that shows how to do 6 ordinary PWM channels
with the 18F4431. It's in the same family as the 18F4331, except it has
more memory. This was tested with compiler vs. 4.084.
The output signals are as follows (on the 40-pin DIP package):
Code: |
Pin Signal Duty Frequency
16 CCP2 50% 500 Hz
17 CCP1 25% 500 Hz
34 PWM1 10% 1000 Hz
36 PWM3 40% 1000 Hz
37 PWM5 60% 1000 Hz
30 PWM7 75% 1000 Hz |
Code: | #include<18F4431.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOLVP
#use delay(clock=8000000)
#define POWER_PWM_PERIOD 1999 // 1 KHz pwm freq with 8 MHz osc.
//=======================================
void main()
{
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_ccp2(CCP_PWM); // Configure CCP2 as a PWM
setup_timer_2(T2_DIV_BY_16, 249, 1); // 500 Hz PWM freq with 8 MHz osc
set_pwm1_duty(63); // 25% duty cycle on pin C2 (CCP1)
set_pwm2_duty(125); // 50% duty cycle on pin C1 (CCP2)
// Setup the 4 Power PWM channels as ordinary pwm channels.
setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON);
// Mode = Free Run
// Postscale = 1 (1-16) Timebase output postscaler
// TimeBase = 0 (0-65355) Initial value of PWM Timebase
// Period = 2000 (0-4095) Max value of PWM TimeBase
// Compare = 0 (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time
setup_power_pwm(PWM_FREE_RUN, 1, 0, POWER_PWM_PERIOD, 0, 1,0);
set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .1)); // 10%
set_power_pwm2_duty((int16)((POWER_PWM_PERIOD *4) * .4)); // 40%
set_power_pwm4_duty((int16)((POWER_PWM_PERIOD *4) * .6)); // 60%
set_power_pwm6_duty((int16)((POWER_PWM_PERIOD *4) * .75)); // 75%
while(1);
} |
|
|
|
gregoryg Guest
|
|
Posted: Thu Jan 01, 2009 9:23 pm |
|
|
Thanks alot PCM programmer, it was most useful.
But as I know servo motors need freq of 50hz, any way to make it with this pic?
thanks again for the help |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Thu Jan 01, 2009 11:00 pm |
|
|
If it was me, I would have written the #define POWER_PWM_PERIOD part of the code as: Code: | #define POWER_PWM_FREQ 1000
#define POWER_PWM_PERIOD (getenv("CLOCK")/4/POWER_PWM_FREQ-1) | That better shows how the PWM values are calculated and it should be easy for you to figure out how to get 50Hz. _________________ Andrew |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jan 01, 2009 11:48 pm |
|
|
There is a table in the PIC data sheet that shows the lowest possible
PWM frequency with a 4 MHz crystal is 244 Hz. See this table:
Quote: | TABLE 17-2: EXAMPLE PWM FREQUENCIES AND RESOLUTIONS |
He will need to use software PWM. |
|
|
gregoryg Guest
|
|
Posted: Fri Jan 02, 2009 8:04 am |
|
|
So there is no way to make more than 2 pwm with 50hz freq?
Sorry for asking so much questions. I am studying mechanical engineering so I have very few knowledge about programming except basic C, unfortunately I am stuck with this project.
tnx |
|
|
Guest
|
|
Posted: Fri Jan 02, 2009 1:23 pm |
|
|
Quote: | But as i know servo motors need freq of 50hz,any way to make it on this pic? |
Yes - forget the PWM (now you know it won't work), write a 'big loop' that executes every 50 Hz.
The 'big loop' can be triggered by a timer overflow or in many ways depending on what else the PIC needs to do.
On each pass through the loop set the new 'pulse position' of each servo.
There are many projects out there in the world that do this - they are easy to find on Google. I even found CCS C code examples from Google.
HTH - Steve H. |
|
|
Herger
Joined: 10 Mar 2010 Posts: 2
|
|
Posted: Fri Mar 12, 2010 12:04 pm |
|
|
Hello!
I use the 18F4331 in the same application as Gregory. Each PWM output drives a MOSFET.
When I load my hex file in the uC, the IDE displays an error message. It doesn't recognize the fuses (LVP...)
I update my compiler and the ICDU40 driver and I disconnect the gate of the MOSFETs.
I load again my hex file and... it's working... I don't understand.
Can someone help me?
Bye
Herger
PS: Please! Excuse me for the english mistake. I'm from Switzerland. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 12, 2010 12:45 pm |
|
|
Quote: | I update my compiler and the ICDU40 driver and I disconnect the gate of the MOSFETs.
I load again my hex file and... it's working... I don't understand.
|
According to your statement above, you have fixed the problem.
That's good. |
|
|
Hicham
Joined: 09 Feb 2010 Posts: 17
|
|
Posted: Wed Mar 17, 2010 3:48 pm |
|
|
Thanks PCM programmer, this example helps a lot, but i have lots questions:
1) If you put time_base = 1000 ? will this make the pwm timer count from 1000 to 2000, or from 1000 to 3000 ??, If its the second case, what's the difference between time_base=0 or 1000 ? or this will have effect just in the up/down modes ?
2) What's the difference between compare and compare_postscale ? Lets say you put compare=500, will this generate interrupts each time the time_base reach 500 ?
3) What about dead time (1 to 63) ? It has also a post scale, where is it ?
and the formula to calculate the dead time is
Dead Time = Dead Time Value/(FOSC/Prescaler) (notice they didn't add the famous 4)
Lots questions, I know.
But as you know, I'm new in pic programming and I got the pic18f4331 after long time waiting something new (this pic doesn't exist in Algeria).
Thanks PCM programmer for all your help here. |
|
|
Hicham
Joined: 09 Feb 2010 Posts: 17
|
|
Posted: Fri Mar 19, 2010 4:38 am |
|
|
Quote: | 3) What about dead time (1 to 63) ? It has also a post scale, where is it ?
and the formula to calculate the dead time is
Dead Time = Dead Time Value/(FOSC/Prescaler) (notice they didn't add the famous 4) |
actually there's a dead clock_clock_div..
my mistake |
|
|
mufiza
Joined: 29 Mar 2010 Posts: 3
|
|
Posted: Mon Mar 29, 2010 8:02 pm |
|
|
Quote: |
34 PWM1 10% 1000 Hz
36 PWM3 40% 1000 Hz
37 PWM5 60% 1000 Hz
30 PWM7 75% 1000 Hz |
Hi everybody. I would like to ask about pwm using pic18f4431. Can we set the different frequency for PWM1, PWM3, PWM5 and PWM7. For example like this:
34 PWM1 10% 500 Hz
36 PWM3 40% 1000 Hz
37 PWM5 60% 1500 Hz
30 PWM7 75% 2000 Hz
If can how to make it?
Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 29, 2010 8:16 pm |
|
|
Quote: |
Can we set the different frequency for PWM1, PWM3, PWM5 and PWM7. |
You can't do it. They all use the same PWM time base registers,
PTMR and PTPER. They all must have the same PWM frequency. |
|
|
mufiza
Joined: 29 Mar 2010 Posts: 3
|
|
Posted: Mon Mar 29, 2010 11:16 pm |
|
|
Thanks PCM programmer for the information.. |
|
|
|