PIC16F877A - Servo Control

Here's the code that drives the TowerPro SG90 Micro Servo motor:

TowerPro Project Code

#include <htc.h>

#define _XTAL_FREQ 16000000

void tsDelay(int d)

{

int delay = d/5;

while(delay-->0)

__delay_us(1);

}

void tsSetPulse(int p1, int p2, int freq)

{

while(freq-->0)

{

RD1 = 1;

tsDelay(p1);

RD1 = 0;

tsDelay(p2);

}

}

void tsCenterize()

{

for(int f=0; f<60; f++)

{

RD1 = 1;

__delay_us(1500);

RD1 = 0;

__delay_us(18500);

}

}

void tsSetPosPercent(int percent, int freq)

{

int delay1 = percent * 12 + 1000;

int delay2 = 20000 - delay1;

tsSetPulse(delay1, delay2, freq);

}

void main()

{

TRISD = 0b00000000;

tsCenterize();

while(1)

{

for(int p=1; p<=100; p+=50)

{

tsSetPosPercent(p, 10);

//__delay_ms(300);

}

for(int p=100; p>0; p-=50)

{

tsSetPosPercent(p, 10);

//__delay_ms(300);

}

/*

tsSetPulse(1000, 19000, 60);

__delay_ms(1000);

tsSetPulse(1500, 18500, 60);

__delay_ms(1000);

tsSetPulse(2000, 18000, 60);

__delay_ms(1000);

*/

}

}

Here's some explanation of the code:

First, notice at line 4: #define _XTAL_FREQ 16000000

I connected a 16Mhz crystal resonator to the PIC for a reason - It allows me to debug the application while running via MPLAB and PicKit2 Debug Express device.

In this line, I define a macro that tells the compiler that _XTAL_FREQ represent 16000000 - This macro is used in HITECH header files where the delay methods use this macro to calculate the delay which is dependant on the PIC oscilator frequency.

Ok, lets skip to line 42 - there's our program entry-point