![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
altanonat
Joined: 07 Feb 2011 Posts: 21 Location: Turkey
|
4x4 Keypad Problem Pic18f4550!!! |
Posted: Mon Feb 07, 2011 12:52 am |
|
|
Hello everyone!
I am trying to use a 4x4 keypad with pic18f4550, I am using the codes which PCM Programmer gave in this link:
http://www.ccsinfo.com/forum/viewtopic.php?t=28022&start=14
besides I have looked at several discussions in this forum but I could not be successful. I am giving the code and schematic below, I will be glad if you can say where I did wrong,
Code: |
#include <18F4550.h>
#fuses XTPLL,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <flex_lcd.c>
//=============================
//Keypad connection:
#define row0 PIN_B4
#define row1 PIN_B5
#define row2 PIN_B6
#define row3 PIN_B7
#define col0 PIN_B0
#define col1 PIN_B1
#define col2 PIN_B2
#define col3 PIN_B3
// Keypad layout:
char const KEYS[4][4] =
{{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}};
#define KBD_DEBOUNCE_FACTOR 33
// Set this number to apx n/333 where
// n is the number of times you expect
// to call kbd_getc each second
void kbd_init()
{
//set_tris_b(0x0F);
//output_b(0x0F);
//port_b_pullups(true);
}
short int ALL_ROWS (void)
{
if(input (row0) & input (row1) & input (row2) & input (row3))
return (0);
else
return (1);
}
char kbd_getc()
{
static byte kbd_call_count;
static short int kbd_down;
static char last_key;
static byte col;
byte kchar;
byte row;
kchar='\0';
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR)
{
switch (col)
{
case 0:
output_low(col0);
output_high(col1);
output_high(col2);
output_high(col3);
break;
case 1:
output_high(col0);
output_low(col1);
output_high(col2);
output_high(col3);
break;
case 2:
output_high(col0);
output_high(col1);
output_low(col2);
output_high(col3);
break;
case 3:
output_high(col0);
output_high(col1);
output_high(col2);
output_low(col3);
break;
}
if(kbd_down)
{
if(!ALL_ROWS())
{
kbd_down=false;
kchar=last_key;
last_key='\0';
}
}
else
{
if(ALL_ROWS())
{
if(!input (row0))
row=0;
else if(!input (row1))
row=1;
else if(!input (row2))
row=2;
else if(!input (row3))
row=3;
last_key =KEYS[row][col];
kbd_down = true;
}
else
{
++col;
if(col==4)
col=0;
}
}
kbd_call_count=0;
}
return(kchar);
}
//===========================
void main()
{
char k;
kbd_init();
lcd_init();
lcd_gotoxy(1,1);
lcd_putc("Starting ...");
delay_ms(3000);
lcd_putc("\f");
while(TRUE)
{
k=kbd_getc();
lcd_gotoxy(1,1);
lcd_putc("Keypad is read ...");
delay_ms(1000);
lcd_putc("\f");
lcd_putc("...");
delay_ms(1000);
lcd_putc("\f");
if(k!='\0')
{
if(k=='*'){
lcd_gotoxy(1,2);
printf(lcd_putc,"%c", '*');
delay_ms(3000);
lcd_putc("\f");}
else{
lcd_gotoxy(1,2);
printf(lcd_putc,"%c", k);
delay_ms(3000);
lcd_putc("\f");}
}
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 07, 2011 1:22 am |
|
|
You have series resistors on the row pins. That's wrong. Also, you have
row pin 'A' connected to Vdd. That's also wrong.
This is a series resistor. This is what your schematic shows:
Code: | PIC pin ------/\/\/\/-------- Keypad pin |
This is a pull-up resistor. This is what you need on each of the row pins:
Code: |
+5v ---/\/\/\/---
|
|
PIC pin ------------o---------- Keypad pin
|
Or, because you're using Port B, you could just enable Port B pull-ups
like this:
Code: |
void kbd_init()
{
port_b_pullups(true);
} |
Also, the keypad must be polled at a high rate. You have huge 1000ms
and 3000ms delays in your main loop. Delete all those delays.
Look at this CCS example file:
Quote: |
c:\program files\picc\examples\ex_lcdkb.c
|
They don't have any delays in the polling loop that calls kbd_getc().
Do it similar to that. |
|
![](templates/subSilver/images/spacer.gif) |
altanonat
Joined: 07 Feb 2011 Posts: 21 Location: Turkey
|
|
Posted: Mon Feb 07, 2011 1:38 am |
|
|
Dear PCM programmer
Thank you very much for such a light speed reply. Actually I am doing exactly as you said above, all the rows are connected to Vdd not only the row pin 'A'. I have commented out Port B pull-ups section because I use external resistors. Is there a way to do this with delays?
I am doing a project, rf data collection system, I need to transfer some id codes to a receiver. These id codes must be character arrays. This(keypad reading) will be the very first step for me, but I have failed even reading a single key in keypad.
Just two days ago I have done an rfid reader card with pic16f877a. However when I tried it on a pic18f4550 it did not work. I think it is because of the register adresses but I could not see any register adress in the library em4095_read.c , but I have to say this is very annoying situation. It is meaningless to use libraries which is mcu dependent. I have to admit that because of this situation I am thinking of changing the compiler. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Mon Feb 07, 2011 5:27 am |
|
|
The em4094 _library_, is device independent.
However the _demo_, is written to run on either a 16F876A, or a 18F452. It is a _demo_. The idea is that it will give you the 'basics' of how to use the library.
There is also a lot of configuration needed by the RS485 driver, which is designed to be useable on chips both with and without the hardware UART, so needs to be told a lot about what hardware to use before starting. On the two chips the demo is setup to use, this is done for you. On other chips, _you_ need to do this first.
Now, you seem to be trying to jump in at the deep end, without making sure that you can swim first. _Before_ starting to work with complex libraries, start by doing a simple 'flash an LED' test, and verify:
1) That the chip is running.
2) That it is running at the correct frequency.
Also, what else is on the pins you are trying to use?.
SETUP_PSP(FALSE);
Might be a good place to start....
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
altanonat
Joined: 07 Feb 2011 Posts: 21 Location: Turkey
|
|
Posted: Mon Feb 07, 2011 6:03 am |
|
|
Ttelmah wrote: | The em4094 _library_, is device independent.
However the _demo_, is written to run on either a 16F876A, or a 18F452. It is a _demo_. The idea is that it will give you the 'basics' of how to use the library.
There is also a lot of configuration needed by the RS485 driver, which is designed to be useable on chips both with and without the hardware UART, so needs to be told a lot about what hardware to use before starting. On the two chips the demo is setup to use, this is done for you. On other chips, _you_ need to do this first.
Now, you seem to be trying to jump in at the deep end, without making sure that you can swim first. _Before_ starting to work with complex libraries, start by doing a simple 'flash an LED' test, and verify:
1) That the chip is running.
2) That it is running at the correct frequency.
Also, what else is on the pins you are trying to use?.
SETUP_PSP(FALSE);
Might be a good place to start....
Best Wishes |
Dear Ttelmah,
Thank you for the suggestions. I have solved my keypad problem, instead of using flex kbd code I used the code below:
Code: |
#include <16F877A.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define LCD_DATA_PORT getenv("SFR:PORTD")
#define LCD_ENABLE_PIN PIN_D0
#define LCD_RS_PIN PIN_D1
#define LCD_RW_PIN PIN_D2
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
//#include <flex_lcd.c>
#include <lcd.c>
//=============================
//Keypad connection:
/*#define row0 PIN_B4
#define row1 PIN_B5
#define row2 PIN_B6
#define row3 PIN_B7
#define col0 PIN_B0
#define col1 PIN_B1
#define col2 PIN_B2
#define col3 PIN_B3*/
char readkey()
{
output_low(PIN_B1);
output_low(PIN_B2);
output_low(PIN_B3);
output_high(PIN_B0);
delay_ms(100);
if(input_state(PIN_B4)==1)
{
delay_ms(20);
return '1';
}
if(input_state(PIN_B5)==1)
{
delay_ms(20);
return '4';
}
if(input_state(PIN_B6)==1)
{
delay_ms(20);
return '7';
}
if(input_state(PIN_B7)==1)
{
delay_ms(20);
return '*';
}
output_low(PIN_B0);
delay_ms(100);
output_low(PIN_B0);
output_low(PIN_B2);
output_low(PIN_B3);
output_high(PIN_B1);
delay_ms(100);
if(input_state(PIN_B4)==1)
{
delay_ms(20);
return '2';
}
if(input_state(PIN_B5)==1)
{
delay_ms(20);
return '5';
}
if(input_state(PIN_B6)==1)
{
delay_ms(20);
return '8';
}
if(input_state(PIN_B7)==1)
{
delay_ms(20);
return '0';
}
output_low(PIN_B1);
delay_ms(100);
output_low(PIN_B0);
output_low(PIN_B1);
output_low(PIN_B2);
output_high(PIN_B3);
delay_ms(100);
if(input_state(PIN_B4)==1)
{
delay_ms(20);
return '3';
}
if(input_state(PIN_B5)==1)
{
delay_ms(20);
return '6';
}
if(input_state(PIN_B6)==1)
{
delay_ms(20);
return '9';
}
if(input_state(PIN_B7)==1)
{
delay_ms(20);
return '#';
}
output_low(PIN_B3);
delay_ms(100);
output_low(PIN_B0);
output_low(PIN_B1);
output_low(PIN_B3);
output_high(PIN_B2);
delay_ms(100);
if(input_state(PIN_B4)==1)
{
delay_ms(20);
return 'A';
}
if(input_state(PIN_B5)==1)
{
delay_ms(20);
return 'B';
}
if(input_state(PIN_B6)==1)
{
delay_ms(20);
return 'C';
}
if(input_state(PIN_B7)==1)
{
delay_ms(20);
return 'D';
}
output_low(PIN_B2);
delay_ms(100);
return 'x';
}
//===========================
void main()
{
SET_TRIS_B(0b11110000);//you mus set in main function before infinite loop port configuration
char key;
//kbd_init();
lcd_init();
lcd_gotoxy(1,1);
lcd_putc("Basliyor ...");
delay_ms(2000);
lcd_putc("\f");
while(TRUE)
{
lcd_gotoxy(1,1);
lcd_putc("Tus takımı okunuyor ...");
delay_ms(200);
lcd_putc("\f");
lcd_putc("...");
delay_ms(200);
lcd_putc("\f");
key = readkey();
delay_ms(500);
if(key!='x')
{
if(key=='*'){
lcd_gotoxy(1,2);
printf(lcd_putc,"%c", '*');
delay_ms(1000);
lcd_putc("\f");
}
else{
lcd_gotoxy(1,2);
printf(lcd_putc,"%c", key);
delay_ms(1000);
lcd_putc("\f");
}
}
}
}
|
About the rfid reader, I could not modify em4095.c to work with pic18f pics. If you know the way and tell me, it will be appreciated.
Code: |
/////////////////////////////////////////////////////////////////////////
//// em4095.c ////
//// This file contains drivers for a EM4095 RFID basestation. ////
//// ////
/////////////////////////////////////////////////////////////////////////
|
++++++++++++++++++++
em4095.c code deleted.
Reason: Forum Rule #10
10. Don't post the CCS example code or drivers, or ask for such code and drivers.
Forum Rules:
http://www.ccsinfo.com/forum/viewtopic.php?t=26245
-- Forum Moderator
++++++++++++++++++++ |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|