CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

keypad scan with an interrupt (change on port B)

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 30, 2010 5:27 pm     Reply with quote

Quote:

You will notice that some members recommend not using the Port B
change interrupt but instead use a Timer interrupt to poll the keypad.

Here is some sample code to do that. The program below calls the
Flex keypad driver (I didn't write that one) in the Code Library:
http://www.ccsinfo.com/forum/viewtopic.php?t=26333
I have connected my keypad with the Row pins on B1-B4 and the
column pins on pins E0-E2 on the 16F877. That's because I can
then easily turn on PortB pull-ups for the Row pins.

The program polls the keypad every 10ms in the #int_rtcc routine
and uses code from the CCS example file Ex_Sisr.c to create a
circular buffer to store the key presses. The user then calls bkbhit()
to see if there are any keys in the buffer, and if so, he can get them
by calling bgetc().

In the program below, you just press keys on the keypad and
they will appear on the terminal window on your PC. I'm using
TeraTerm as the terminal window program.
http://www.ccsinfo.com/forum/viewtopic.php?t=39388&start=18
Code:

#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

// Use the Flex keypad driver from the CCS Code Library forum.
#include "flex_kbd.c"

#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;

// This preload value will give an RTCC interrupt
// rate of 100 Hz (every 10 ms) with a pre-scaler
// of 256, and if the PIC is running at 4 MHz.
#define RTCC_PRELOAD (256 - 39)

//------------------------------
// The keypad is polled every 10ms in this interrupt
// routine.
#int_rtcc
void rtcc_isr(void)
{
int t;
int k;

set_rtcc(RTCC_PRELOAD); // Reload Timer0 for 10ms rate

k = kbd_getc();  // Check the keypad for a keypress

// If we got a keypress, put it in the circular
// buffer.
if(k != 0) 
  {
   buffer[next_in] = k;
   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE;
   if(next_in==next_out)
      next_in=t;
  }

}

#define bkbhit (next_in!=next_out)

//------------------------------
int8 bgetc(void)
{
int8 c;

while(!bkbhit);
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}


//==================================
void main()

int8 key;

kbd_init();  // Enable PortB pull-ups on keypad Row pins

// Setup the RTCC (also called Timer0).
setup_counters(RTCC_INTERNAL, RTCC_DIV_256);
set_rtcc(RTCC_PRELOAD);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);

while(1)
  {
   // Check if a key is available in the buffer.
   if(bkbhit)
     {
      key = bgetc();  // If so, get the key
      putc(key);  // 'key' is an ASCII char, so display it
     }
  }

Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group