/* ***************************************************************** timer0.c - timer demo modified to polls switch on RA3 modified by Doug Rice, 28/11/2009 ***************************************************************** */ #include #define dev16F886 1 //#define dev16F690 1 #ifdef dev16F886 /* config for 16F886 */ //__CONFIG(WDTDIS & INTCLK & UNPROTECT & MCLREN & BORDIS & LVPDIS & IESODIS & FCMDIS ); // Program config. word 1 __CONFIG(WDTDIS & INTCLK & UNPROTECT & MCLRDIS & BORDIS & LVPDIS & IESODIS & FCMDIS ); // Program config. word 1 __CONFIG(FCMEN); // Program config. word 2 #endif #ifdef dev16F690 /* config for 16F690 */ //__CONFIG(WDTDIS & INTCLK & UNPROTECT & MCLREN & BORDIS & IESODIS & FCMDIS ); // Program config. word 1 __CONFIG(WDTDIS & INTCLK & UNPROTECT & MCLRDIS & BORDIS & IESODIS & FCMDIS ); // Program config. word 1 #endif /* * Example code for using timer0 on a 16F690 * sets up tmr0. When it matures poll the switches and increments a variable */ /* * Calculate preload value for one second timer */ #define PERIOD 1000000 // period in uS - one second here #define XTAL 4000000 // crystal frequency - 4MHz #define IPERIOD (4 * 1000000 / XTAL) // Period of instruction clock in uSeconds //#define SCALE 256 // Timer 0 prescaler //#define T0_TICKS 256 // Number of counts for interrupt #define SCALE 16 // Timer 0 prescaler #define T0_TICKS 16 // Number of counts for interrupt #define TICK_PERIOD (SCALE * IPERIOD) // Period (uSec) of one increment of timer 0 // #define RELOADS ((PERIOD/T0_TICKS)/TICK_PERIOD) #define RELOADS 1 #ifdef dev16F886 #define PORT_BUTTONS PORTE #define PORT_BUTTON 3 #endif #ifdef dev16F690 #define PORT_BUTTONS PORTA #define PORT_BUTTON 3 #endif void incLed(); void setLed(); // unsigned long seconds; // second count near char reload = 0; near char count = 0; near char divide = 0; near char holdoff = 0; // unsigned long shiftReg = 0; near unsigned char shiftReg = 0; near char lastPortButton =0xff; near char newPortButton =0xff; near char pressedPortButton = 0; near char releasedPortButton = 0; /* service routine for timer 0 interrupt */ void interrupt timer0_isr(void) { if(reload == 0){ // effect a change on PORTB whenever our desired period is reached. // Note this timing will contain a margin of error. reload = RELOADS + 1; // seconds++; // PORTB++; // effect a change on PORTB - debugger interferes with this so shadow setLed(); } reload--; T0IF = 0; } void setLed(){ // effect a change on PORTB whenever our desired period is reached. // Note this timing will contain a margin of error. //reload = RELOADS + 1; //seconds++; // PORTB++; // effect a change on PORTB - debugger interferes with this so shadow //count++; #ifdef dev16F886 //PORTB=count; PORTB= ( shiftReg & 0x0f ); #endif #ifdef dev16F690 //PORTC=count; PORTC= ( shiftReg & 0x0f ); #endif } void IPpollSwitches(){ // Poll buttons lastPortButton = newPortButton; newPortButton = PORT_BUTTONS; // lastPortButton ----_____ // newPortButton -----____ pressedPortButton = pressedPortButton | ( lastPortButton & ~newPortButton ); // lastPortButton ___---- // newPortButton __----- releasedPortButton = releasedPortButton | ( ~lastPortButton & newPortButton ); } main() { // initialize timer 0; OPTION = 0b011; // prescale by 256 T0CS = 0; // select internal clock T0IE = 1; // enable timer interrupt GIE = 0; // enable global interrupts #ifdef dev16F886 TRISB = 0; // output changes on LED #endif #ifdef dev16F690 TRISC = 0; // output changes on LED #endif // for(;;) // continue; // let interrupt do its job IPpollSwitches() ; pressedPortButton = 0 ; while( 1 ){ // test if button has just been pressed if ( pressedPortButton & 1 << PORT_BUTTON ) { // clear the event pressedPortButton = pressedPortButton & ~(1 << PORT_BUTTON ) ; // do something //count++; holdoff = 2; shiftReg = shiftReg+shiftReg+1; setLed(); } if ( releasedPortButton & 1 << PORT_BUTTON ) { // clear the event releasedPortButton = releasedPortButton & ~(1 << PORT_BUTTON ) ; // do something //count++; holdoff = 2; shiftReg = shiftReg+shiftReg+1; setLed(); } if ( T0IF ) { // poll switches eevry time that TMR0 matures. IPpollSwitches(); divide ++; if( divide == 244 ) { divide = 0; #ifdef dev16F886 if ( ( holdoff == 0 ) && ( PORTB=shiftReg != 0 ) ) { #endif #ifdef dev16F690 if ( ( holdoff == 0 ) && ( PORTC=shiftReg != 0 ) ) { #endif shiftReg = shiftReg >> 1; setLed(); } else { holdoff--; } } // clear TMR0 event T0IF = 0; } } }