PWM for PIC18F2550

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
in the documentation of the compiler C18 we can find

Rich (BB code):
/******************************************************************
* NOTES:
* Code uses the Peripheral library support available with MCC18 Compiler
* Code Tested on:
* PicDem2+ demo board with PIC18F4685 controller
* PWM output is obtained on CCP1 pin. duty cycle is gievn by
*
*Formula for Period and Duty cycle calculatio
*
*        PWM period =   [(period  ) + 1] x 4 x Tosc x TMR2 prescaler
*
*        PWM x Duty cycle = (DCx<9:0>) x Tosc
*
*        Resolution (bits) = log(Fosc/Fpwm) / log(2)
**********************************************************************/

#define USE_OR_MASKS
#include <p18cxxx.h>
#include "pwm.h"

void main(void)
{
  char period=0x00;
  unsigned char outputconfig=0,outputmode=0,config=0;
  unsigned int duty_cycle=0;

//----Configure pwm ----
    period = 0xFF;
    OpenPWM1( period);            //Configure PWM module and initialize PWM period

//-----set duty cycle----
        duty_cycle = 0x0F00;
        SetDCPWM1(duty_cycle);        //set the duty cycle

//----set pwm output----
    outputconfig = FULL_OUT_FWD ;
    outputmode = PWM_MODE_1;
    SetOutputPWM1( outputconfig, outputmode);    //output PWM in respective modes

    while(1);                    //observe output on CCP1 pin

//-----close pwm----
  ClosePWM1();

}
Now... I am unexperienced on PWM, so I have a hard time understanding this.

For example, lets see the duty cycle

Rich (BB code):
duty_cycle = 0x0F00;
        SetDCPWM1(duty_cycle);

Isn't it supposed that the duty cycle is 10 bits??
but 0x0F00= 1111 0000 0000 right? so 12 bits....
in this example, how much percentage (%) are we putting...?




(as an aside note, I tried to compile it for my PIC18F2550 and it didnt work. It didnt recognize the macros FULL_OUT_FWD and PWM_MODE_1)

Can anybody help me on this???
 

Vaughanabe13

Joined May 4, 2009
102
Sorry, but the reason you haven't gotten any responses is because your question is confusing. Please explain what you want to do and what you don't understand.

The duty cycle controls the percentage of a PWM period that is "ON" (logic high). So if your duty cycle is 50%, you will have a square wave with equal-width positive and negative pulses, and if it is 75%, it will be "ON" for 75% of a period and "OFF" for 25%. The duty cycle is a 10-bit value, but if you give it more than 10 bits it will take the lower 10 bits as the duty cycle. 0x0F00 is actually = 1100000000 = 768.

According to the C18 compiler libraries PDF:
The value of dutycycle can be any 10-bit number. Only the lower
10-bits of dutycycle are written into the duty cycle registers. The duty
cycle, or more specifically the high time of the PWM waveform, can be
calculated from the following formula:
PWM x Duty cycle = (DCx<9:0>) x TOSC
where DCx<9:0> is the 10-bit value specified in the call to this function.
 

AlexR

Joined Jan 16, 2008
732
Take a look at the C18 library documentation.

The SetDCPWM1() function takes an int (16 bit) value as an argument to set the duty cycle but only used the the 10 least significant bits to configure the duty cycle. The 6 most significant bits are simply ignored.

So the statement:
Rich (BB code):
//-----set duty cycle----
        duty_cycle = 0x0F00;
        SetDCPWM1(duty_cycle);
will have the same effect as far as duty cycle is concerned as:
Rich (BB code):
//-----set duty cycle----
        duty_cycle = 0x0300;
        SetDCPWM1(duty_cycle);
 

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
Sorry, but the reason you haven't gotten any responses is because your question is confusing. Please explain what you want to do and what you don't understand.

The duty cycle controls the percentage of a PWM period that is "ON" (logic high). So if your duty cycle is 50%, you will have a square wave with equal-width positive and negative pulses, and if it is 75%, it will be "ON" for 75% of a period and "OFF" for 25%. The duty cycle is a 10-bit value, but if you give it more than 10 bits it will take the lower 10 bits as the duty cycle. 0x0F00 is actually = 1100000000 = 768.

According to the C18 compiler libraries PDF:
I am sorry for my confusing post... maybe it was because I am confused.
In theory I know what you are saying. If we could just program in percentages like

dutycycle=50; // meaning 50%

that would be wonderful, but instead we have to make some transformation to an hexadecimal and I cant figure it out how...

in the example above for instance. how can I put a dutycicle of 100%?
and how can I put it to 10%
or 20%
 

AlexR

Joined Jan 16, 2008
732
Part of the problem is Microchip's use of the term "duty cycle" when what they really mean is "on period". You have to manually calculate the on period of your PWM waveform and plug that value into the formula as the "PWM duty cycle".

Alternately you can just plug the relevant values into the on-line PWM calculator at
http://www.micro-examples.com/public/microex-navig/doc/097-pwm-calculator.html
and let it do all the hard work for you.
 

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
Thanks for all the help.

One more question. i notice that in the microchip example, there is no

Rich (BB code):
#pragma config FOSC = INTOSCIO_EC //Internal oscillator, port function on RA6, EC used by USB 
#pragma config WDT = OFF //Disable watchdog timer
and things like that. In other programs if you dont set the oscillator the micro doesnt do anything,

How come the example doesnt have these settings?
 

AlexR

Joined Jan 16, 2008
732
If you are referring to the example snippets of code on the micro-examples web site then obviously all they give you is the code needed to set the various registers needed for PWM operation. Anything else is up to you and they assume that you will add all the code that is needed to make the PIC work.
 

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
thanks for the reply.

it seems to be working now but I got still questions..

please take a look at the new thread I am posting in a few minutes

kansai
 
Top