#include <xc.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define XMAX 605
#define XMIN 405
#define YMAX 605
#define YMIN 405
#define ABS(N) ( (N) >= 0 ? (N) : -(N) )
#pragma config LVP = OFF, BOREN = OFF, FOSC = INTOSC, MCLRE = OFF, WDTE = OFF, PWRTE = OFF, PLLEN = OFF
volatile unsigned int RES;
void delayUs(int x)
{
x>>=3; // 125 * 8uS = 1000uS
while(x--) // a little bit out... 16 cylcles @ 0.5uS = 8uS
{
NOP(); // this means the lowest uS delay is 12uS ( including the call and the shift )
NOP();
}
}
void delayMs(int x)
{
while(x--)
delayUs(1000); // Self explanitory
}
void interrupt ISR(void)
{
if (TMR2IF) // End of period! start again
{
CCPR2L = RES & 0xFF; // set CCP2
CCPR2H = (RES>>8)&0xFF; // finish position
TMR1L = TMR1H = 0; // reset timer
CCP2CON = 0x09; // turn on CCP2 pin
TMR2IF = 0; // Clear timer flag
}
else
{
TMR1L = TMR1H = 0; // Okay! CCP interrupt.. reset timer
CCP2CON = 0x0; // Force Pin low
CCP2IF = 0; // Clear CCP interrupt
}
}
unsigned int GetFromAdc(unsigned char Channel)
{
unsigned int res;
ADON = 1; // Start ADC module
delayUs(100);
GO = 1;
while(GO); // wait for conversion
res = (unsigned int)ADRESH<<8;
res += ADRESL;
//res<<=1; // if 11 bit is wanted!!
return res; // 10 bit result
}
void SetPwm(void)
{
RES = GetFromAdc(0); // Set duty
RES += 0x0800; // according to ADC reading on channel 0
} // Add in 1mS
void main(void)
{
OSCCON = 0x70; // 8Mhz
ADCON1 = 0xB0; // set ADC TAD
ANSELA = ANSELB = ANSELC = 0; // All digital to start
TRISA = TRISC = 0x0; // Prep ports
TRISB = 0xAF;
T2CON = 0x4E; // Timer2 on
PR2 = 250; //
TMR2IE = 1; // interrupt on timer 2 required
INTCON = 0xC0; // GIE and PEIE on
T1CON = 1; // Turn on timer 1
CCP2SEL = 1;
CCP2IE = 1; // interrupt on CCP match required!!
TMR1L = TMR1H = 0; // reset timer
ANSELA = 0x01; // AN0 selected
ADCON1 = 0xb0; // Again!! Christ knows why!!
CCPR2L = 0;
CCPR2H = 0x08; // start at 1mS
while(1)
{
SetPwm(); // Super loop and read pot!
}
}