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

LCD Displays Random Output

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



Joined: 25 Mar 2010
Posts: 11

View user's profile Send private message

LCD Displays Random Output
PostPosted: Thu Mar 25, 2010 12:50 pm     Reply with quote

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 Smile

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 Confused

Any help really apprecieated Smile


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

View user's profile Send private message

PostPosted: Thu Mar 25, 2010 1:03 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Mar 25, 2010 1:51 pm     Reply with quote

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 Confused
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 25, 2010 2:01 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Mar 25, 2010 2:06 pm     Reply with quote

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 Confused
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 25, 2010 2:17 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Mar 25, 2010 3:50 pm     Reply with 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.

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

View user's profile Send private message Visit poster's website

PostPosted: Thu Mar 25, 2010 9:31 pm     Reply with quote

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?
Code:
while(1);


Rohit


edit: the word b u t t is NOT spam! Razz
Chris007



Joined: 25 Mar 2010
Posts: 11

View user's profile Send private message

PostPosted: Fri Mar 26, 2010 3:48 am     Reply with quote

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: 19469

View user's profile Send private message

PostPosted: Fri Mar 26, 2010 4:38 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Mar 26, 2010 9:24 am     Reply with quote

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 Confused

I'm really confused here :( Any advice?
Chris007



Joined: 25 Mar 2010
Posts: 11

View user's profile Send private message

PostPosted: Mon Mar 29, 2010 3:23 pm     Reply with quote

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 Very Happy

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

View user's profile Send private message Visit poster's website

PostPosted: Mon Mar 29, 2010 8:41 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Mar 30, 2010 1:32 am     Reply with quote

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 Confused

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?
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