PWM servo control example for the PIC18F14K50

This is my first program for the PIC18F14K50 20-pin microcontroller. I haven’t used this chip before, but it seems to have some useful features including USB connectivity, so I intend to investigate it further.

This program is a simple PWM example which moves a servo motor to one of two possible angles (0 degrees or 90 degrees) depending on the state of a digital input pin (RC4, pin 6). The PWM output signal is produced on pin 5 (CCP1).

I’m using the internal RC oscillator. This has a default Fosc of 1MHz, but in order to achieve a PWM period of 20ms (for the servo), I had to slow the clock down to 500kHz, which gives an instruction cycle of 8us.

// PIC18F14K50 servo PWM example program
// Written by Ted Burke (
// Last updated 22-4-2013
// To compile with XC8:
//     xc8 --chip=18F14K50 main.c
#include <xc.h>
int main(void)
	// Set clock frequency to 500kHz, therefore Tcy = 8us
	OSCCONbits.IRCF = 0b010;
	// Set up PWM
	CCP1CON = 0b00001100;   // Enable PWM on CCP1
	TRISC = 0b11011111;		// Make CCP1 an output
	T2CON = 0b00000110;     // Enable TMR2 with prescaler = 16
	PR2 = 155;	// PWM period = (PR2+1) * prescaler * Tcy = 19.968ms
	CCPR1L = 8;	// pulse width = CCPR1L * prescaler * Tcy = 1.024ms
		if (PORTCbits.RC4) CCPR1L = 12;	// 1.536ms pulses, i.e. 90 degrees
		else CCPR1L = 8;				// 1.024ms pulses, i.e. 0 degrees
	return 0;

I don’t have an actual PIC18F14K50 to try my program on, so instead I ran it on the simulator in MPLAB v8.50. I captured the simulated PWM output using MPLAB’s logic analyzer tool, as shown below.


The blue waveform is the PWM output on CCP1 (pin 5). The red vertical lines are “cursors” provided in the logic analyzer for measuring the time difference between two points on the waveform. I positioned them to measure the period of the PWM waveform, which is 2511 instruction cycles. Since the clock oscillator frequency Fosc is set to 500kHz, the clock cycle Tosc is 2us. The PIC18F14K50 performs one machine instruction every 4 clock cycles, so the instruction cycle Tcy is 8us. So the PWM period is:

T_{pwm} = 2511 \times T_{cy} = 20.088ms
This entry was posted in Uncategorized. Bookmark the permalink.

4 Responses to PWM servo control example for the PIC18F14K50

  1. Mila says:

    I want to run a bldc motor using trapezoidal and field oriented controller commutation method. I am working on a microchip development kit with the dspic30F6010. I would be very grateful with you If you could help me with the code.
    Thanks in advance 🙂

  2. Thank you for sharing your code. I just read documentation and did setup that didn’t work. Your solution worked at first try. Thanks!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s