### Archive

Posts Tagged ‘PIC18’

## Programming PIC 18 using XC8 (MPLAB X) : PWM (using pwm.h)

Pulse Width Modulation (PWM) is used everywhere from motors to communication! It uses timer as its foundation to toggle the pins high-low at a defined period (1/frequency) and duty cycle (10 bit resolution – 210 = 1024 steps). If you use high frequency, then you won’t get the 10 bit resolution. Read the document bellow to find more information.

So in previous tutorial we saw about using a timer. Now my task is to make a LED do the heart beat effect (gradually increase/decrease the brightness of an LED using PWM).

To set a PWM:

• Setup the timer (to the frequency/period)
• Set the duty cycle (you will be using the functions from pwm.h)

So I am going to set the PWM frequency to 2KHz (since using 8MHz as clock source and prescale of 16, getting less than 2KHz is difficult), so the formula according to the datasheet will be  (we are going to find PR2)

PWM period = [(PR2) + 1] • 4 • TOSC • (TMR2 prescale value)

where PWM period = 1/ Frequency (that will be 1/2000 = .0005)

.0005 = [PR2 + 1] • [1 / 8000000] • 16

PR2 + 1 = [.0005 • 8000000] / 16

PR2 + 1 =  250

PR2 = 249

PR2 = 0xF9 ( 249 in hex)

Note : Read the datasheet and peripheral library document. PWM1 uses Timer 2. You can use other timers as source for your PWM, but read and make sure if you can or can’t in the datasheet of the device you are using.

To set timer2 for PWM, we just need to set the presale value

```unsigned char Timer2Config = T2_PS_1_16;
OpenTimer2(Timer2Config);```

And then open the PWM

`OpenPWM1(0xF9); //2KHz`

So here is the whole sample PWM program and the video below it

```#define _XTAL_FREQ 8000000 //The speed of your internal(or)external oscillator

#include <xc.h>
#include "config.h"
#include <plib/timers.h>
#include <plib/pwm.h>

int i = 0;
int countup = 1; //our flag to set up/down dutycycle
int DutyCycle = 0;
unsigned char Timer2Config; //PWM clock source
void SetupClock(void);

void main(int argc, char** argv) {

SetupClock(); // Internal Clock to 8MHz

TRISCbits.RC2 = 0; //PWM pin set as output

Timer2Config = T2_PS_1_16; //prescale 16
OpenTimer2(Timer2Config);

OpenPWM1(0xF9); //Open pwm at 2KHz

while(1) //infinite loop
{
if(countup == 1)
{
SetDCPWM1(DutyCycle); //Change duty cycle
DutyCycle++;
if(DutyCycle == 1024)
countup = 0;
}
else
{
SetDCPWM1(DutyCycle); //Change duty cycle
DutyCycle--;
if(DutyCycle == 0)
countup = 1;
}
__delay_ms(1);
}
}

void SetupClock()
{
OSCCONbits.IRCF0 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF2 = 1;
}```

And here is the video

Categories: Electronics Tags: