// ******************************************************************************************* // #include "p24fj64ga002.h" // ******************************************************************************************* // // Configuration bits for CONFIG1 and CONFIG2. // // Make sure "Configuration Bits set in code." option is checked in MPLAB. // This option can be set by selecting "Configuration Bits..." under the Configure // menu in MPLAB. // // These settings are appropriate for debugging the PIC microcontroller. If you need to // program the PIC for standalone operation, change the COE_ON option to COE_OFF. _CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_ON & COE_ON & ICS_PGx1 & FWDTEN_OFF & WINDIS_OFF & FWPSA_PR128 & WDTPS_PS32768 ) _CONFIG2( IESO_OFF & SOSCSEL_SOSC & WUTSEL_LEG & FNOSC_PRIPLL & FCKSM_CSDCMD & OSCIOFNC_OFF & IOL1WAY_OFF & I2C1SEL_PRI & POSCMOD_XT ) // ******************************************************************************************* // #define S_NO_PRESS 0 #define S_1ST_PRESS 1 #define S_2ND_PRESS 2 volatile int pState = S_NO_PRESS; volatile int elapsedTime = 0; // ******************************************************************************************* // int main(void) { _TRISB15 = 0; // Configure RB15 as output _LATB15 = 1; // Initialize LED to off // ******************************************************************************* // // Timer 2 is used for Input Capture // ******************************************************************************* // // Set Timer 2's period value regsiter to value for 750ms. // Fosc/2 = (7372800 * 4)/2 = 14745600 // Timer Freq = 14745600 / 256 = 57600 // PRx = 750e-3 * 57600 - 1 = 43199 T2CONbits.TCKPS = 3; // Set Timer2's Prescaler to 1:256 PR2 = 43199; TMR2 = 0; // Clear Timer 2 to 0 _T2IF = 0; // Clear Timer 2 interrupt flag // ******************************************************************************* // // Input Capture 1 is used timing of button presses from SW5 (RP5) // ******************************************************************************* // RPINR7bits.IC1R = 5; // RP5 is input for Input Capture 1 IC1CONbits.ICM = 2; // Capture on every falling edge (i.e. button press) IC1CONbits.ICTMR = 1; // Timer 2 used IC1CONbits.ICI = 0; // Interrupt on every capture _IC1IF = 0; // Clear Input Capture 1 interrupt flag _IC1IE = 1; // Enable Interrupt Capture 1 interrupt // ******************************************************************************* // while(1) { // Nothing to see here. Move along everybody. } return 0; } // ******************************************************************************************* // // Timer 2 interrupt will be executed if 750 ms have pasted since first press. void _ISR _T2Interrupt(void) { _T2IF = 0; // Clear Timer 2 interrupt flag // Check if we have detected two presses... if( pState == S_2ND_PRESS ) { _LATB15 = ~_LATB15; // Toggle LED pState = S_1ST_PRESS; // Reset to first press state } // Otherwise, only first press detected, reset to no press state... else { pState = S_NO_PRESS; // Reset to no press state T2CONbits.TON = 0; // Stop Timer 2 TMR2 = 0; // Reset Timer 2 _T2IE = 0; // Disable Timer 2 interrupt } } // ******************************************************************************************* // // Input Capture Interrupt used to measure time between first and second press. Further // implements a simple state machine for monitoring the number of button presses // we have observed so far. void _ISR _IC1Interrupt(void) { int dummy; _IC1IF = 0; // Clear Input Capture interrupt flag switch (pState) { case S_NO_PRESS: pState = S_1ST_PRESS; // Found first press TMR2 = 0; // Reset Timer 2 _T2IE = 1; // Enable Timer 2 Interrupt T2CONbits.TON = 1; // Start Timer 2 elapsedTime = IC1BUF; // Read the buffer to avoid overflow break; case S_1ST_PRESS: pState = S_2ND_PRESS; // Found second press elapsedTime = IC1BUF; // Keep track of time between first and second press break; case S_2ND_PRESS: T2CONbits.TON = 0; // Stop Timer 2 TMR2 -= elapsedTime; // Adjust Timer 2 to time of last press (now the first press) T2CONbits.TON = 1; // Start Timer 2 elapsedTime = IC1BUF - elapsedTime; // Log time between new first and second press break; } } // ******************************************************************************************* //