#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) { // 3 ways to disable the A to D converter; // ADCON0 &= 0b11111110; // bitclr(ADCON0,0); ADON = 0; // Make sure that no pin is connected to the A/D ANSEL = 0b00000000; ANSELH = 0b00000000; // 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; // Sets bit 3 of port A to trigger an interrupt on change IOCA = 0b00001000; // Clears PORTA/B interrupt flag RABIF = 0; // Allows PORTA/B to trigger an interrupt RABIE = 1; } void timer_setup(void) { // Set all the parameters for Timer0 // See section 5.1.3 #asm clrwdt #endasm // Selects the processor clock for Timer0 (See OPTION reg) T0CS = 0; // Selects the pre-scaller for Timer0 (See OPTION reg) PSA = 0; // Sets the pre-scaller value to 256 OPTION = ((OPTION & 0b11111000) | 0b00000111); // Loads Timer0 register TMR0 = 0; // clear Timer0 interrupt flag (see INTCON) T0IF = 0; // Allows Timer0 to generate an exception (see INTCON) T0IE = 1; } static void interrupt interupt_handler(void) { // Was the interrupt generated by Register A/B? if (RABIF == 1) { if (RA3 == 1) { bitclr(PORTC,3); } else { bitset(PORTC,3); } // clears the RegiterA/B interrupt flag RABIF = 0; } // Was the interrupt generated by Timer0? if (T0IF == 1) { // Resets the value of Timer0 TMR0 = 0; PORTC ^= 0b00000001; // clears the Timer0 interrupt flag T0IF = 0; } } void main( void) { // set the oscillator speed to 1 MHz OSCCON = ((OSCCON & 0b10001111) | 0b01000000); // setup the ports io_port_setup(); // setup the timer timer_setup(); // Interrupts are on GIE = 1; // Loop for ever while (1) { } }