/* Routine to decode quadrature signals on the AT89C2051 */ /* Basic Algorithm: * * Program monitors 2 external input lines, for phases A and B of the quadrature signal. * Use an interrupt service routine to trigger a read, or just poll. * Compare the 'current' state of the inputs with the 'last' state of the inputs and * use a truth table to figure out which way we are going. * Use this info to increment or decrement a counter. * * | Last State | Current State | Direction | * | A B | A B | | * |----------------------------------------| * | 0 0 | 0 1 | dec | * | 0 0 | 1 0 | inc | * | | | | * | 0 1 | 1 1 | dec | * | 0 1 | 0 0 | inc | * | | | | * | 1 0 | 0 0 | dec | * | 1 0 | 1 1 | inc | * | | | | * | 1 1 | 1 0 | dec | * | 1 1 | 0 1 | inc | * | | | | * */ #include /* global variables */ int counter; bit a, b, am1, bm1, dir; void quad_dec(void); void main(void) { /* set port 1 for output mode */ P1 = 0x00; /* set these 2 bits for input mode */ P1_0 = 1; P1_1 = 1; a=0; b=0; am1=0; bm1=0; dir=0; while(1) { a = P1_0; b = P1_1; quad_dec(); am1 = a; bm1 = b; P1_2 = counter&0x00000001; P1_3 = (counter&0x00000002)>>1; P1_4 = (counter&0x00000004)>>2; P1_5 = (counter&0x00000008)>>3; P1_7 = dir; } } void quad_dec(void) { if( !am1 && !bm1) { /* <00> - state #3 */ if( a && !b ) { ++counter; dir = 1; } else if( !a && b ) { --counter; dir = 0; } } else if( !am1 && bm1 ) { /* <01> - state #2 */ if( a && b ) { --counter; dir = 0; } else if( !a && !b ) { ++counter; dir = 1; } } else if( am1 && !bm1 ) { /* <10> - state #0 */ if( a && b ) { ++counter; dir = 1; } else if( !a && !b ) { --counter; dir = 0; } } else { /* <11> - state #1 */ if( a && !b ) { --counter; dir = 0; } else if( !a && b ) { ++counter; dir = 1; } } }