#include __CONFIG(INTIO & WDTDIS & PWRTDIS & MCLRDIS & UNPROTECT & BORDIS & IESODIS & FCMDIS); #define bitset(var,bitno) ((var) |= 1 << (bitno)) #define bitclr(var,bitno) ((var) &= ~(1 << (bitno))) void io_port_setup(void) { // Sets all bits for port C for output TRISC = 0b00000000; // All bits for port C are off PORTC = 0b00000000; // Sets all bits for port A for input TRISA = 0b00111111; ADON = 1; // RA0/AN0 connected to the A/D ANSEL = 0b00000001; ANSELH = 0b00000000; // The result will be left aligned in ADRESH ADFM = 0; // We are using VCC as reference VCFG = 0; // We are sampling AN0 ADCON0 = ((ADCON0 & 0b11000011) | 0b00000000); // Clock source is F/2 ADCON1 = ((ADCON1 & 0b10001111) | 0b00000000); // Clears A2D interrupt flag ADIF = 0; // Allows A2D to trigger an interrupt ADIE = 1; // Allows for PE interupts PEIE = 1; // Start a conversion GODONE = 1; } void PWM_setup(void) { // Select PWM mode, P1D active high; CCP1CON = ((CCP1CON & 0b11110000) | 0b00001100); // Select Single output CCP1CON = ((CCP1CON & 0b00111111) | 0b00000000); // Steer the output to P1C or RC3 STRC = 1; // No post-scaler T2CON = ((T2CON & 0b10000111) | 0b00000000); // 16 as a prescaler T2CON = ((T2CON & 0b11111100) | 0b00000011); // Frequency: 61 Hz PR2 = 0xFF; // Duty cycle: 0 (OFF) CCP1CON = ((CCP1CON & 0b11001111) | 0b00000000); CCPR1L = 0; // Timer is ON! TMR2ON = 1; } static void interrupt interupt_handler(void) { // Was the interrupt generated by A2D? if (ADIF == 1) { // Update the Duty Cycle CCPR1L = ADRESH; CCP1CON = ((CCP1CON & 0b11001111) | ((ADRESL & 0b11000000) >> 2)); GODONE = 1; ADIF = 0; } } void main( void) { // set the oscillator speed to 1 MHz OSCCON = ((OSCCON & 0b10001111) | 0b01000000); // setup the ports io_port_setup(); // setup PWM PWM_setup(); // Interrupts are on GIE = 1; // Loop forever while (1) { } }