|
|
View previous topic :: View next topic |
Author |
Message |
Chris007
Joined: 25 Mar 2010 Posts: 11
|
LCD Displays Random Output |
Posted: Thu Mar 25, 2010 12:50 pm |
|
|
Hi guys, gr8 forum u got here. I've been following and have got lots of help from here. Now I got a small problem and thought maybe you could help me
Parts:
PIC16F877A
20x4 Alphanumeric LCD
4x4 Matrix Keypad
4MHz Crystal
Ok first I want to interface the keypad with the lcd so that if I press any key, it will show the respective letter/number on the screen. I have everything connected up in the right way. I'm using 10k pull-up resistors on pins 5-8 of the keypad, there is a 22pF capacitor connected to the crystal.
I am using the following drivers for the keypad & lcd:
LCD Driver: lcd420.c
Code: | //LCD connection:
// B0 enable
// B1 rs
// B2 rw
// B4 D4
// B5 D5
// B6 D6
// B7 D7
//
// LCD pins D0-D3 are not used and PIC B3 is not used.
struct lcd_pin_map { // This structure is overlayed
BOOLEAN enable; // on to an I/O port to gain
BOOLEAN rs; // access to the LCD pins.
BOOLEAN rw; // The bits are allocated from
BOOLEAN unused; // low order up. ENABLE will
int data : 4; // be pin B0.
} lcd;
#byte lcd = 6 // This puts the entire structure
// on to port B (at address 6)
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
BYTE lcdline;
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_b(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_b(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
set_tris_b(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0, LCD_INIT_STRING[i]);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
switch(y) {
case 1 : address=0x80;break;
case 2 : address=0xc0;break;
case 3 : address=0x94;break;
case 4 : address=0xd4;break;
}
address+=x-1;
lcd_send_byte(0,address);
}
void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
lcdline=1;
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,++lcdline); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
} |
Keypad Driver: kbd44.c
Code: | //Keypad connection:
#define ROW0 PIN_C4
#define ROW1 PIN_C5
#define ROW2 PIN_C6
#define ROW3 PIN_C7
#define COL0 PIN_D4
#define COL1 PIN_D5
#define COL2 PIN_D6
#define COL3 PIN_D7
// 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
void kbd_init()
{
}
short int ROW_HIGH()
{
if(input (ROW0) || input (ROW1) || input (ROW2) || input (ROW3))
return (1);
else
{
return (0);
}
}
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_high(col0);
output_low(col1);
output_low(col2);
output_low(col3);
break;
case 1:
output_low(col0);
output_high(col1);
output_low(col2);
output_low(col3);
break;
case 2:
output_low(col0);
output_low(col1);
output_high(col2);
output_low(col3);
break;
case 3:
output_low(col0);
output_low(col1);
output_low(col2);
output_high(col3);
break;
}
if(kbd_down)
{
if(!ROW_HIGH())
{
kbd_down=false;
kchar=last_key;
last_key='\0';
}
}
else
{
if(ROW_HIGH())
{
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);
} |
This is my program to test the interfacing:
Code: | #include<16f877a.h>
#fuses xt,noprotect,nowdt
#use delay(clock=4000000)
#include<lcd420.c>
#include<kbd44.c>
void main()
{
char k=0;
lcd_init();
kbd_init();
lcd_putc("\fReady...\n");
while(1)
{
k=kbd_getc();
if(k!=0)
if(k=='*')
lcd_putc('\f');
else
lcd_putc(k);
}
} |
The problem is, I power everything on and get the message "Ready", 1 second later random numbers/letters are displayed on the screen and this doesn't stop
Any help really apprecieated
Last edited by Chris007 on Thu Mar 25, 2010 1:11 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 25, 2010 1:03 pm |
|
|
Quote: | void main()
{
char k=0;
lcd_init();
kbd_init();
lcd_putc("\fReady...\n");
while(1);
.
.
.
} |
First, prove that the problem is in the keypad code or hardware.
Add the continuous while() loop statement shown in bold.
See if you still get the problem. If you don't get the problem,
then it confirms that it's in the keypad code or hardware.
Next, assuming it's the keypad, verify that you really have the
pull-up resistors connected to the Row pins on the keypad.
Make sure you know what the "row" and "column" pins are,
on the keypad. |
|
|
Chris007
Joined: 25 Mar 2010 Posts: 11
|
|
Posted: Thu Mar 25, 2010 1:51 pm |
|
|
PCM programmer wrote: | Quote: | void main()
{
char k=0;
lcd_init();
kbd_init();
lcd_putc("\fReady...\n");
while(1);
.
.
.
} |
First, prove that the problem is in the keypad code or hardware.
Add the continuous while() loop statement shown in bold.
See if you still get the problem. If you don't get the problem,
then it confirms that it's in the keypad code or hardware.
Next, assuming it's the keypad, verify that you really have the
pull-up resistors connected to the Row pins on the keypad.
Make sure you know what the "row" and "column" pins are,
on the keypad. |
Thanks for replying, I used the continuous while loop. Now only "Ready" shows on the screen. If I press a button, there is no response, it still remains as "Ready" on the screen.
Also, pins 5-8 are the row pins on the keypad, I have added 10k resistors on them.
Is there a difference between normal resistors and pull up resistors, cos I have put normal resistors on the pins 5-8 of my circuit. My mate told me that there is no difference, its jus the way u connect it up e.g. series resistors |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 25, 2010 2:01 pm |
|
|
This is a series resistor:
Code: |
PIC pin ------/\/\/\/-------- Keypad pin
|
This is a pull-up resistor:
Code: |
+5v
|
>
< 10K
>
|
PIC pin ---------o-------- Keypad pin
|
Make sure you have pull-up resistors on the row pins. |
|
|
Chris007
Joined: 25 Mar 2010 Posts: 11
|
|
Posted: Thu Mar 25, 2010 2:06 pm |
|
|
Right, I see. What I'm missing is the 5v connection.
Also, just to make sure... Physically the resistors are the same right?
Sorry for asking noobish questions |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 25, 2010 2:17 pm |
|
|
There must be 4 individual resistors. Each resistor goes between the
respective Row pin and +5v. i.e., each row pin has its own pull-up
resistor. Each resistor must be 10K ohms in value. |
|
|
Chris007
Joined: 25 Mar 2010 Posts: 11
|
|
Posted: Thu Mar 25, 2010 3:50 pm |
|
|
Ok I've got the resistors in the correct place with 5v and they are all 10k. When I power up, same thing just says "Ready". No action from the keypad, but I know the keypad is 100% working.
Is there anything else important which I need to check? and the program I have, is there any error in the code?
Also about the capacitors, I have 22pF connected to pins 13&14 of the microcontroller and the crystal is also on here aswell. These are correct right? |
|
|
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Thu Mar 25, 2010 9:31 pm |
|
|
Let me b u t t in..... Quote: | Ok I've got the resistors in the correct place with 5v and they are all 10k. When I power up, same thing just says "Ready". No action from the keypad, but I know the keypad is 100% working. | Have you removed the semicolon?
Rohit
edit: the word b u t t is NOT spam! |
|
|
Chris007
Joined: 25 Mar 2010 Posts: 11
|
|
Posted: Fri Mar 26, 2010 3:48 am |
|
|
Hi Rohit, yea I've tried with and without the semicolon, my original code doesn't have the semicolon anyways. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Fri Mar 26, 2010 4:38 am |
|
|
Er.
If you study the keyboard driver being used, it scans the keyboard, by _raising_ a single column line at a time. It looks for a 'pressed' key, by testing for the input lines being high. As such, it required _pull down_ resistors, not 'pull_up' resistors, or it is permanently going to return every possible key (exactly what is being seen.....).
Best Wishes |
|
|
Chris007
Joined: 25 Mar 2010 Posts: 11
|
|
Posted: Fri Mar 26, 2010 9:24 am |
|
|
I've changed to pull down resistor, hasn't solved the problem :(
I removed the keypad from the circuit and powered it. Now random characters are still appearing on the screen even without any input
I'm really confused here :( Any advice? |
|
|
Chris007
Joined: 25 Mar 2010 Posts: 11
|
|
Posted: Mon Mar 29, 2010 3:23 pm |
|
|
I've managed to get everything working now. The pull-down resistors worked!
On start-up, the screen shows "Ready", If I press 0-9, or A-D, the letters show up on the screen accordingly which is what I wanted
Only 1 little bug, which is after pressing a button, the correct digit pressed shows on the screen but sometimes this symbol ll appears on the screen.
It's like two straight line next to each other, so the LCD would look something like this:
1234ABllCD
The ll would just randomly appear after receiving an input from the keypad.
Any help on this? Appreciate all the help given so far. |
|
|
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Mon Mar 29, 2010 8:41 pm |
|
|
Umm, what was the reason for the random characters? Was the LCD 'spewing' characters? Or did a random character pop up only when you pressed a button? One thing you can do is check for loose/faulty connections between the PIC and LCD.
Rohit |
|
|
Chris007
Joined: 25 Mar 2010 Posts: 11
|
|
Posted: Tue Mar 30, 2010 1:32 am |
|
|
Yea I think the LCD was 'spewing' characters, but the pull down resistors managed to overcome this problem. I've checked the LCD/PIC connections and they are correct
I've put a pull up resistor on pin 1, do you think that I should connect a 1uF capacitor here and ground it as well? |
|
|
|
|
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
|