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 support@ccsinfo.com

keypad problem

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



Joined: 17 Jul 2006
Posts: 7

View user's profile Send private message Send e-mail Visit poster's website AIM Address Yahoo Messenger MSN Messenger

keypad problem
PostPosted: Thu Nov 13, 2008 10:29 am     Reply with quote

First my keypad is a 4x4 matrix keypad with an extra common pin. I have it hooked to portb with pullups active. Upon a button press I get a col and row pin shorted to gnd indicating which button is pressed. I took newguy's interrupt code (http://www.ccsinfo.com/forum/viewtopic.php?t=19726) and modified it.

What I get is the button code press and then release. But I have to hold down the button to get the push and release code. If I quickly tap the key I only get the release code.

Is my keypad (all electronics) bad or my code wrong?
Code:

/*============================================
pic16f877a keypad routine.                                              11/12/08

Jason Berkhimer

Keypad from all electronics. 4 col pins, 4 row pins and common. col and row
connected to portb and common to gnd. pullups active. keypad press detected
through interrupts.
============================================*/
 
#include <16F877A.h>
#fuses HS           // fast oscillator
#fuses NOWDT      // no watch dog timer
#fuses NOPROTECT   // no code protection
#fuses NODEBUG      // no debugger
#fuses NOPUT      // no power up timer
#fuses NOBROWNOUT   // no brown out reset
#fuses NOLVP      // no low voltage programming
#fuses NOCPD      // no EE memory protection
#fuses NOWRT      //

#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
#byte portd = 0x08
#byte porte = 0x09
#use fast_io(B)

// #include <stdlib.h>

// variables ===================================================================
int1 key_pressed = FALSE;
static int old_b_state, new_b_state;
static int16 key = 0;
char kchar;

// interrupts ==================================================================
#int_RB
void RB_isr(void) {
   new_b_state = input_b();   
   if (old_b_state != new_b_state) {
      old_b_state = input_b();
//      if (old_b_state == 0xff)
         key_pressed = TRUE;
   }
}

// functions ===================================================================
void find_key(void) {
   int pin, b_state, delay = 10;
   disable_interrupts(INT_RB);
   delay_ms(50);  // debounce
   b_state = portb;
   printf("%X",b_state);
   old_b_state=input_b();
   enable_interrupts(INT_RB);
}

// main ========================================================================
void main() {
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);

   port_b_pullups(TRUE);
   delay_us(50);         //wait for pullups to come on.

   set_tris_b(0xff);
   old_b_state = input_b();       //read portb before turning on int.
   enable_interrupts(INT_RB);
   enable_interrupts(global);

   printf("keypad test");
   while(TRUE)
   {
      if (key_pressed) {
         key_pressed = FALSE;
         find_key();
      }
      output_d(0x0);
      delay_ms(250);
      output_d(0x2);
      delay_ms(250);
   }
}

_________________
compiler PCM version 4.064
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Thu Nov 13, 2008 10:56 am     Reply with quote

I would start by changing this
Code:

void RB_isr(void) {
   new_b_state = input_b();   
   if (old_b_state != new_b_state) { <---- Not required as this interrupted due to a change in state!
      old_b_state = input_b(); 
//      if (old_b_state == 0xff)
         key_pressed = TRUE;
   }
}

change to

void RB_isr(void) {
  old_b_state = input_b();
  if (old_b_state == 0xFF)
    key_pressed = true;
}



You don't actually use the push code ?
I can't see what your problem is!
shroder300



Joined: 17 Jul 2006
Posts: 7

View user's profile Send private message Send e-mail Visit poster's website AIM Address Yahoo Messenger MSN Messenger

PostPosted: Thu Nov 13, 2008 11:09 am     Reply with quote

Right now I am only printing the codes to the serial port.

My problem is the keypad buttons have to be held down for at least half a second before the program prints a press code and then release code (once the button is released). If I don't hold down the button I only get a release code on the serial port.

The changes you suggested didn't change the results at all.
_________________
compiler PCM version 4.064
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Nov 13, 2008 2:00 pm     Reply with quote

Look at this CCS example file on using push buttons with #int_rb:
Quote:
c:\program files\picc\examples\ex_pbutt.c

It has an example of how to do the isr (for 'press' or 'release' but not both).

Your complaint about the requirement for a 500ms hold down time is
caused by the delays in your loop. Your program only tests the status
every 1/2 second. That's the update rate.
Guest








PostPosted: Fri Nov 14, 2008 5:54 am     Reply with quote

thanks, I didnt think about that. Embarassed should I be checking the status in the isr instead?
shroder300



Joined: 17 Jul 2006
Posts: 7

View user's profile Send private message Send e-mail Visit poster's website AIM Address Yahoo Messenger MSN Messenger

PostPosted: Fri Nov 14, 2008 10:21 am     Reply with quote

Here is my final code. the int routine will pick up both a press and a release. the main function will only print a press, however.

Code:
/*==============================================================================
pic16f877a keypad routine.                                              11/12/08

Jason Berkhimer

keypad from all electronics. 4 col pins, 4 row pins and common. col and row
connected to portb and common to gnd. pullups active. keypad press detected
through interrupts. prints raw data from keypad to serial port and portd
==============================================================================*/
 
#include <16F877A.h>
#fuses HS           // fast oscillator
#fuses NOWDT      // no watch dog timer
#fuses NOPROTECT   // no code protection
#fuses NODEBUG      // no debugger
#fuses NOPUT      // no power up timer
#fuses NOBROWNOUT   // no brown out reset
#fuses NOLVP      // no low voltage programming
#fuses NOCPD      // no EE memory protection
#fuses NOWRT      //

#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
#byte portd = 0x08
#byte porte = 0x09
#use fast_io(B)
#use fast_io(D)

// #include <stdlib.h>

// variables ===================================================================
int1 key_pressed = FALSE;
static int old_b_state, new_b_state;
static int16 key = 0;
char kchar;

// interrupts ==================================================================
#int_RB
void RB_isr(void) {          // detects both press and release
      new_b_state = input_b();
      if (new_b_state != old_b_state);   // make sure state changed
         key_pressed = TRUE;
      old_b_state=new_b_state;
   
}

// functions ===================================================================
void find_key(void) {
   int pin, b_state, delay = 10;
   disable_interrupts(INT_RB);
   delay_ms(50);           // debounce
   b_state = portb;
   if (b_state != 0xff){      // only print on press
      printf("-%X-",b_state);
      output_d(b_state);
   }
   enable_interrupts(INT_RB);
}

// main ========================================================================
void main() {
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);

   port_b_pullups(TRUE);
   delay_us(50);         // wait for pullups to come on.

   set_tris_b(0xff);
   set_tris_d(0x00);
   set_tris_c(0x00);

   old_b_state = input_b();       // read portb before turning on int.
   enable_interrupts(INT_RB);
   enable_interrupts(global);

   printf("keypad test");

   while(TRUE)
   {
      if (key_pressed) {
         key_pressed = FALSE;
         find_key();
      }
   }
}



_________________
compiler PCM version 4.064
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