Chapter 12 Capturing Input
Di Jasio - Programming 32-bit Microcontrollers in C Button Inputs
Di Jasio - Programming 32-bit Microcontrollers in C Inputs Packing int readK( void) { // returns 0..F if keys pressed, 0 = none int c = 0; if ( !_RD6) // leftmost button c |= 8; if ( !_RD7) c |= 4; if ( !_RA7) c |= 2; if ( !_RD13) // rightmost button c |= 1; return c; } // readK
Di Jasio - Programming 32-bit Microcontrollers in C De-Bouncing int getK( void) { // wait for a key pressed and debounce int i=0, r=0, j=0; int c; // 1. wait for a key pressed for at least.1sec do{ Delayms( 10); if ( (c = readKEY())) { if ( c>r) // if more than one button r = c; // take the new code i++; } else i=0; } while ( i<10); // 2. wait for key released for at least.1 sec i =0; do { Delayms( 10); if ( (c = readKEY())) { if (c>r) // if more then one button r = c; // take the new code i=0; j++; // keep counting } else i++; } while ( i<10); // 3. check if a button was pushed longer than 500ms if ( j>50) r+=0x80; // add a flag in bit 7 // 4. return code return r; } // getK
Di Jasio - Programming 32-bit Microcontrollers in C Rotary Encoders
Di Jasio - Programming 32-bit Microcontrollers in C Polling Example /* ** Rotary.c */ // configuration bit settings, Fcy=72MHz, Fpb=36MHz #pragma config POSCMOD=XT, FNOSC=PRIPLL #pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_18, FPLLODIV=DIV_1 #pragma config FPBDIV=DIV_2, FWDTEN=OFF, CP=OFF, BWP=OFF #include #define ENCHA _RA9 // channel A #define ENCHB _RA10 // channel B main( void) { int i = 0; char s[16]; initLCD(); // main loop while( 1) { while( ENCHA); // detect CHA falling edge Delayms( 5); // debounce i += ENCHB ? 1 : -1; while( !ENCHA); // wait for CHA rising edge Delayms( 5); // debounce // display relative counter value clrLCD(); sprintf( s, "%d", i); putsLCD( s); } // main loop } // main
Di Jasio - Programming 32-bit Microcontrollers in C Interrupt Driven Rotary Encoder State Machine Diagram Rotary Encoder State Machine Transitions Table
Di Jasio - Programming 32-bit Microcontrollers in C Interrupt Driven Example /* ** Rotary2.c */ // configuration bit settings, Fcy=72MHz, Fpb=36MHz #pragma config POSCMOD=XT, FNOSC=PRIPLL #pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_18, FPLLODIV=DIV_1 #pragma config FPBDIV=DIV_2, FWDTEN=OFF, CP=OFF, BWP=OFF #include #define ENCHA _RA9 // encoder channel A #define ENCHB _RA10 // encoder channel B #define TPMS (FPB/1000) // PB clock ticks per ms // state machine definitions #define R_IDLE 0 #define R_DETECT 1 volatile int RCount; char RState; void initR( void) { // init state machine RCount = 0; // init counter RState = 0; // init state machine // init Timer2 T2CON = 0x8020; // enable Timer2, Fpb/4 PR2 = 5*TPMS/4; // 5ms period mT2SetIntPriority( 1); mT2ClearIntFlag(); mT2IntEnable( 1); } // init R
Di Jasio - Programming 32-bit Microcontrollers in C Interrupt Service Routine void __ISR( _TIMER_2_VECTOR, ipl1) T2Interrupt( void) { static char d; switch ( RState) { default: case R_IDLE: // waiting for CHA rise if ( ! ENCHA) { RState = R_DETECT; if ( ! ENCHB) d = -1; } else d = 1; break; case R_DETECT: // waitin for CHA fall if ( ENCHA) { RState = R_IDLE; RCount += d; } break; } // switch mT2ClearIntFlag(); } // T2 Interrupt
Di Jasio - Programming 32-bit Microcontrollers in C Example (cont.) main( void) { int i = 0; char s[16]; initEX16(); // init and enable interrupts initLCD(); // init LCD module initR(); // init Rotary Encoder // main loop while( 1) { Delayms( 100); // place holder for a complex app. clrLCD(); sprintf( s, "RCount = %d", RCount); putsLCD( s); } // main loop } // main
Di Jasio - Programming 32-bit Microcontrollers in C Keyboards Physical Interface (5-pin DIN) Physical Interface (6-pin mini-DIN)
Di Jasio - Programming 32-bit Microcontrollers in C PS2 Communication Protocol Host Communication Waveform
Di Jasio - Programming 32-bit Microcontrollers in C Input Capture Modules Figure 15-1 (DS61143)
Di Jasio - Programming 32-bit Microcontrollers in C PS/2 Bit Timing
Di Jasio - Programming 32-bit Microcontrollers in C IC State Machine
Di Jasio - Programming 32-bit Microcontrollers in C IC ISR void __ISR( _INPUT_CAPTURE_1_VECTOR, ipl1) IC1Interrupt( void) { // input capture interrupt service routine int d; // 1. reset timer on every edge TMR2 = 0; switch( PS2State){ default: case PS2START: if ( ! PS2DAT) // verify start bit { KCount = 8; // init bit counter KParity = 0; // init parity check PR2 = TMAX; // init timer period T2CON = 0x8000; // enable TMR2, 1:1 PS2State = PS2BIT; } break; case PS2BIT: KBDBuf >>=1; // shift in data bit if ( PS2DAT) KBDBuf += 0x80; KParity ^= KBDBuf; // update parity if ( --KCount == 0) // if all bit read, move on PS2State = PS2PARITY; break; case PS2PARITY: if ( PS2DAT) // verify parity bit KParity ^= 0x80; if ( KParity & 0x80) // if parity odd, continue PS2State = PS2STOP; else PS2State = PS2START; break; case PS2STOP: if ( PS2DAT) // verify stop bit { KBDCode = KBDBuf; // save code in mail box KBDReady = 1; // set flag, code available T2CON = 0; // stop the timer } PS2State = PS2START; break; } // switch state machine // clear interrupt flag d = IC1BUF; // discard capture mIC1ClearIntFlag(); } // IC1 Interrupt
Di Jasio - Programming 32-bit Microcontrollers in C Using Stimulus Files
Di Jasio - Programming 32-bit Microcontrollers in C Test Program /* ** PS2ICTest.c ** */ // configuration bit settings, Fcy=72MHz, Fpb=36MHz #pragma config POSCMOD=XT, FNOSC=PRIPLL #pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_18, FPLLODIV=DIV_1 #pragma config FPBDIV=DIV_2, FWDTEN=OFF, CP=OFF, BWP=OFF #include #include "PS2IC.h" main() { int Key; initEX16(); // init and enable interrupts initKBD(); // initialization routine while ( 1) { if ( KBDReady) // wait for the flag { Key = KBDCode; // fetch the key code KBDReady = 0; // clear the flag } } // main loop } //main
Di Jasio - Programming 32-bit Microcontrollers in C Simulator Profiler