sp3ctrm5tr

KEYPAD scan driver implementing RB interrupt

Apr 12th, 2012
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.85 KB | None | 0 0
  1. ///////////////////////////////////////////////////////////////////////////
  2. ////                             keypad.c                              ////
  3. ////                  Generic keypad scan driver                       ////
  4. ////                                                                   ////
  5. ////  kbd_init()   Must be called before any other function.           ////
  6. ////                                                                   ////
  7. ////  c = kbd_getc(c)  Will return a key value if pressed or /0 if not ////
  8. ////                   This function should be called frequently so as ////
  9. ////                   not to miss a key press.                        ////
  10. ////                                                                   ////
  11. ///////////////////////////////////////////////////////////////////////////
  12. #define __delay_cycles _delay  
  13. //Now using RB change interrupt
  14.  
  15. #ifndef BYTE
  16. #define BYTE unsigned char
  17. #endif
  18.  
  19. #define KBD_DEBOUNCE_FACTOR 33    // Set this number to apx n/333 where
  20.                                   // n is the number of times you expect
  21.                                   // to call kbd_getc each second
  22.  
  23. // Keypad layout:
  24. char const KEYS[4][4] = {{'7','8','9','/'},
  25.                          {'4','5','6','x'},
  26.                          {'1','2','3','-'},
  27.                          {'C','0','=','+'}};
  28.  
  29.  
  30. BYTE kchar;
  31. BYTE col;
  32. BYTE row;
  33. BYTE kbd_down=0;
  34. BYTE last_key=0;
  35.  
  36. //--Interrupt Service function--
  37. interrupt ISR (void) // Interrupt function definition
  38. {  
  39.     if (RBIF) // If the RB change flag is 1, do .....
  40.     {  
  41.         RBIE=0; //Disable RB change interrupt
  42.         {  
  43.             kbd_down=1;
  44.             col = (PORTB >> 4) & 0x0F;
  45.             if (col == 0b1110)
  46.             col = 0;
  47.             else if (col == 0b1101)
  48.             col = 1;
  49.             else if (col == 0b1011)
  50.             col = 2;
  51.             else
  52.             col = 3;
  53.  
  54.             last_key = KEYS[row][col];
  55.             kchar = last_key;
  56.         }
  57.         RBIF=0; // Reset the external interrupt flag
  58.         RBIE=1; // RE-Enable RB change interrupt
  59.     }
  60.     GIE=1; //Enable Global Interrupt
  61. }
  62.  
  63. void kbd_init( )
  64. {
  65.     TRISB = 0xF0; //Port B in/output
  66.     nRBPU = 0; // Enable PORTB pullups
  67.     RBIE=1; //Enable the RB port change interrupt
  68.     GIE=1; // Global interrupt enable
  69.     RBIF=0; //Clear RB port change interrupt flag
  70. }
  71.  
  72. char kbd_getc( )
  73. {
  74.    static BYTE kbd_call_count;
  75.  
  76.    kchar=last_key;
  77.     for (row=0;row<4; row++)
  78.     {      
  79.         switch (row)
  80.         {
  81.             case 0 : PORTB = PORTB | 0b11111110;
  82.             RB0 = 0;
  83.             break;
  84.            
  85.             case 1 : PORTB = PORTB | 0b11111101;
  86.             RB1 = 0;   
  87.             break;
  88.          
  89.             case 2 : PORTB = PORTB | 0b11111011;
  90.             RB2 = 0;   
  91.             break;
  92.          
  93.             case 3 : PORTB = PORTB | 0b11110111;
  94.             RB3 = 0;
  95.         }
  96.         __delay_cycles(KBD_DEBOUNCE_FACTOR );
  97.  
  98.         if (kbd_down==1)
  99.         {  
  100.             kbd_down=0;
  101.             break;
  102.         }
  103.         else kchar = 0;
  104.     }      
  105.    
  106.     PORTB = PORTB | 0xFF;    //Reset Port B
  107.     return(kchar);
  108. }  //End of keypad
Advertisement
Add Comment
Please, Sign In to add comment