#include <p18f1320.h>
#pragma config WDT = OFF, LVP = OFF, OSC = INTIO2
#define ServoPin LATBbits.LATB3
#define ServoTris TRISBbits.TRISB3
void ccp1_isr();
volatile int ServoPos; //used to hold the servo position
#pragma code low_vector=0x18 //setup the ISR vector
void low_interrupt (){
_asm GOTO ccp1_isr _endasm //jump to interrupt handler
}
#pragma code
#pragma interruptlow ccp1_isr //the ISR
void ccp1_isr(){
if(ServoPin==1){ //will be 1 if we are at end of pulse
ServoPin=0; //turn off servo output
CCPR1=20000-ServoPos; //Off time = 20mS - Servo Time
}
else{
ServoPin=1; //turn on servo output
CCPR1=ServoPos; //On time
}
PIR1bits.CCP1IF=0; //clear int flag
}
#pragma code
void main(){
OSCCON=0x70; //Osc=8MHz
ADCON0=0b00000101; //A2D on and select AN1
ADCON1=0x7d; //A1 = analogue
ADCON2=0b10110101; //Right justify - Fosc/16
ServoTris=0; //make bit 0 output
ServoPin=0; //Servo output off
CCP1CON=0b00001011; //Special event trigger
T1CON=0b10010001; //Timer 1 on with Pre=2
ServoPos=1500; //set servo to mid position
CCPR1=ServoPos; //set CCP initial value
PIE1bits.CCP1IE=1; //enable CCP1 interrupt
INTCONbits.PEIE=1; //enable peripheral interrupts
INTCONbits.GIE=1; //enable glogal interrupts
INTCON2bits.RBPU=0; //enable port b week pullups
while(1){ //loop forever
static char Mode=0; //0 = use ADC, 1=fixed pos
static char Keys; //holds previous key values
char OldKeys,Edges; //local variables
while(!ServoPin); //Wait for start of servo pulse
while(ServoPin); //wait for end - makes for good debounce
OldKeys=Keys; //make a copy of keys
Keys=PORTB&0b00100101; //get switch state
Keys^=0b00100101; //make pressed keys = 1
if(Keys==0b00100101) //all 3 pressed?
Mode=0; //yes, set to use ADC input
Edges=(Keys^OldKeys); //keep only keys that have changed
Edges&=Keys; //keep only new key presses - not key releases
if(Mode==0){ //are we using the pot?
ADCON0bits.GO=1; //yes, start conversion
while(ADCON0bits.GO); //Wait for it to complete
ServoPos=ADRES+1000; //Pos will be 1mS to 2.023mS
}
if(Edges!=0) //any key pressed
Mode=1; //switch to fixed mode
if(Edges==0b00000001) //Key 1 pressed
ServoPos=1000; //set servo fully left
if(Edges==0b00000100) //key 2?
ServoPos=1500; //set center
if(Edges==0b00100000) //key 3?
ServoPos=2000; //set fully right
}
}