• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

4x4 and 3x3 keypad interfacing with ATmega128 problem?

Status
Not open for further replies.

nihal_2000

New Member
Hi friends...I am just trying to connect key pad. There are two keypads connected to controller one is on PORTD which is 4x4 and other on PORTC 3x3, in following code just trying to get key number and display using LED's on PORTA. FCPU is 12MHz and Controller is ATmega128.
i am using Code-vision compiler...i have tried my level best to get the result .....but all the LED's on PORTA are constantly glowing irrespective to pressed key .... Please help me!

Code:
#include <mega16.h>
#include <delay.h>
#include <stdlib.h>

                
int key(void);

void main(void)
{

    unsigned char i=0; 
    DDRA=0xff;
    DDRB=0x0F;
    DDRC=0x07;
    DDRD=0x0F;

  

    i=key();

    while(1){
    
     PORTA=i;
    
            }

}


int key(void){
char KEY = 1 ;
while(KEY){

        PORTD.0 = 1 ;
        PORTD.1 = 0 ;
        PORTD.2 = 0 ;
        PORTD.3 = 0 ;
        if(PIND.4 == 1){return 7 ; KEY = 0;delay_ms(50);}     
        if(PIND.5 == 1){return 8 ; KEY = 0;delay_ms(50);}    
        if(PIND.6 == 1){return 9 ; KEY = 0;delay_ms(50);}   
        if(PIND.7 == 1){return 10; KEY = 0;delay_ms(50);}       
        //==========================================
        PORTD.0 = 0 ;
        PORTD.1 = 1 ;
        PORTD.2 = 0 ;
        PORTD.3 = 0 ;
        if(PIND.4 == 1){return 4 ; KEY = 0;}     
        if(PIND.5 == 1){return 5 ; KEY = 0;}    
        if(PIND.6 == 1){return 6 ; KEY = 0;}
        if(PIND.7 == 1){return 11; KEY = 0;}       
        //==========================================
        PORTD.0 = 0 ;
        PORTD.1 = 0 ;
        PORTD.2 = 1 ;
        PORTD.3 = 0 ;
        if(PIND.4 == 1){return 1 ; KEY = 0;}         
        if(PIND.5 == 1){return 2 ; KEY = 0;}       
        if(PIND.6 == 1){return 3 ; KEY = 0;}      
        if(PIND.7 == 1){return 12; KEY = 0;}         
        //==========================================
        PORTD.0 = 0 ;
        PORTD.1 = 0 ;
        PORTD.2 = 0 ;
        PORTD.3 = 1 ;
        if(PIND.4 == 1){return 15; KEY = 0;}        
        if(PIND.5 == 1){return 0 ; KEY = 0;}        
        if(PIND.6 == 1){return 14; KEY = 0;}       
        if(PIND.7 == 1){return 13; KEY = 0;}

        //=======================================================
        PORTC.0 = 1 ;
        PORTC.1 = 0 ;
        PORTC.2 = 0 ;
        if(PINC.5 == 1){return 16 ; KEY=0;}
        if(PINC.6 == 1){return 17; KEY=0;}
        if(PINC.7 == 1){return 18 ; KEY=0;}
        //===================================================== 
        PORTC.0 = 0 ;
        PORTC.1 = 1 ;
        PORTC.2 = 0 ;
        if(PINC.5 == 1){return 19 ; KEY=0;}         
        if(PINC.6 == 1){return 20 ; KEY=0;}
        if(PINC.7 == 1){return 21 ; KEY=0;}
        //=====================================================
        PORTC.0 = 0 ;
        PORTC.1 = 0 ;
        PORTC.2 = 1 ;
        if(PINC.5 == 1){return 22 ; KEY=0;} 
        if(PINC.6 == 1){return 23 ; KEY=0;}
        if(PINC.7 == 1){return 24 ; KEY=0;}
 
KEY = 1 ;       
}
}
 
Last edited:

mneary

New Member
You call key() exactly once and then display the same returned value forever. You never call key() again to see if any keys are pressed.

You can make your code readable. "Go Advanced" just below here, to the right. Click "#" to wrap with
Code:
 tags.
 

nihal_2000

New Member
Thanks mneary for your replay. Sorry for not wrapping the code.
Sorry i am a dumb.......little bit confused to understand your suggestion....follow i have try to explain the code with proper tagging....Please help me!

Code:
void main(void)
{

    unsigned char i=0;     //initialized unsigned char i
    DDRA=0xff;                 //PORTA is set as put LED PORT
    DDRB=0x0F;
    DDRC=0x07;
    DDRD=0x0F;

  

    i=key();                       //KEY function called here . KEY value is assigned to i 

    while(1){
    
     PORTA=i;                  // i assigned to PORTA as o/p
    
            }
 

mneary

New Member
Code:
i=key();                       //KEY function called here . KEY value is assigned to i 
// ^^^ You call key() here but never come back to check again

    while(1)[COLOR=Purple]{ 
    
     PORTA=i;                  // i assigned to PORTA as o/p
//      ^ You write i to PORTA and then do it again and again. i is always the same.
            }[/COLOR]
Thanks for wrapping the code - a lot of people don't know how and it's rewarding to me that I can help.

I have changed the color of the while(1) block. See that key() is not inside?
 
Last edited:

nihal_2000

New Member
Thanks for your advice, i have tried it in following way....but it didn't work. Sorry I am new to C ...Please guide me to gate key values on PORTA.....thanks a lot!


Code:
void main(void)
{

    unsigned char i=0;     //initialized unsigned char i
    DDRA=0xff;                 //PORTA is set as put LED PORT
    DDRB=0x0F;
    DDRC=0x07;
    DDRD=0x0F;

    i=key();                       //KEY function called here . KEY value is assigned to i 
    PORTA=i;                  // i assigned to PORTA as o/p

    }
 

mneary

New Member
Now, you find that main() executes only once and returns without checking the keys again. The following code will work, but I would like you to explain why:

Code:
void main(void)
{

    unsigned char i=0;     //initialized unsigned char i
    DDRA=0xff;                 //PORTA is set as put LED PORT
    DDRB=0x0F;
    DDRC=0x07;
    DDRD=0x0F;

while(1){
    i=key();                       //KEY function called here . KEY value is assigned to i 
    PORTA=i;                  // i assigned to PORTA as o/p
          }                        // we look at key again and display what we find

    }
 

nihal_2000

New Member
Thanks mneary I appreciate your efforts. Now the function is called in a infinite loop……so after displaying out put on PORTA…program will again call key() and in that function it will keep on scanning until switch is pressed. When you press some key it will execute the next step by displaying key on PORTA......again....key()......continue.... I hope I am right.
But the problem is not yet solved, theoretically it has to show pressed key on PORTA……in practical still all LED’s are ON irrespective to what switch you pressed. I am using STK600 board & ATmega128. FCPU is 12MHz.
 
Last edited:

nihal_2000

New Member
I have debugged this code in AVR Studio, specially function key() it is perfectly scanning ....key board..........I request to go through it one more time........with your wast experience you can very easily find out the bug...........Please help me out.
 
Last edited:

Pommie

Well-Known Member
Most Helpful Member
I took the liberty of modifying your program as there were a few errors. All the lines such as,
Code:
if(PIND.4 == 1){return 7 ; [COLOR="red"]KEY = 0;delay_ms(50);}[/COLOR]
The code in red never gets executed as the return instruction will exit the function.

I moved the debounce after the wrile loop and used KEY to return the value. I also moved the function call (key) into the while loop.
Code:
#include <mega16.h>
#include <delay.h>
#include <stdlib.h>

                
int key(void);

void main(void)
{
    unsigned char i=0; 
    DDRA=0xff;
    DDRB=0x0F;
    DDRC=0x07;
    DDRD=0x0F;

    while(1){
        i=key();    
        PORTA=i;    
    }
}


int key(void){
char KEY = 255 ;
   while(KEY==255){
        PORTD.0 = 1 ;
        PORTD.1 = 0 ;
        PORTD.2 = 0 ;
        PORTD.3 = 0 ;
        if(PIND.4 == 1)
            KEY = 7;     
        if(PIND.5 == 1)
            KEY = 8;    
        if(PIND.6 == 1)
            KEY = 9;   
        if(PIND.7 == 1)
            KEY = 10;       
        //==========================================
        PORTD.0 = 0 ;
        PORTD.1 = 1 ;
        PORTD.2 = 0 ;
        PORTD.3 = 0 ;
        if(PIND.4 == 1)
            KEY = 4;     
        if(PIND.5 == 1)
            KEY = 5;    
        if(PIND.6 == 1)
            KEY = 6;
        if(PIND.7 == 1)
            KEY = 11;       
        //==========================================
        PORTD.0 = 0 ;
        PORTD.1 = 0 ;
        PORTD.2 = 1 ;
        PORTD.3 = 0 ;
        if(PIND.4 == 1)
            KEY = 1;         
        if(PIND.5 == 1)
            KEY = 2;       
        if(PIND.6 == 1)
            KEY = 3;      
        if(PIND.7 == 1)
            KEY = 12;         
        //==========================================
        PORTD.0 = 0 ;
        PORTD.1 = 0 ;
        PORTD.2 = 0 ;
        PORTD.3 = 1 ;
        if(PIND.4 == 1)
            KEY = 15;        
        if(PIND.5 == 1)
            KEY = 0;        
        if(PIND.6 == 1)
            KEY = 14;       
        if(PIND.7 == 1)
            KEY = 13;
        //======================================================= 
    }
    delay_ms(50);     
    return KEY;
}
I removed the 3*4 code but you can easily add it back.

Mike.
 

nihal_2000

New Member
Thanks pommie i really appreciate your efforts. I am going to add 3*4 code and get back to forum with result....thanks a lot!
 

nihal_2000

New Member
Hi friends,
I have been trying this modified code to print the pressed number on LCD, but it is constantly printing a string of numbers ......without even pressed the key board....I am using code vision LCD driver routine by adding lcd.h. LCD is a char LCD HD44780 controller based ......please help me!

Code:
#include <mega16.h>
#include <delay.h>
#include <lcd.h>
#include <stdlib.h>
#include <math.h>

#asm
   .equ __lcd_port=0x18
#endasm

int key();

char y=0 , lcd[25], z ;
//#############################################
void main(void){

DDRB=0x0F;
DDRC=0x07;
DDRD=0x0F;

lcd_init(16);
lcd_clear();
key();
z=10;                          //Just to check LCD is working printing z on lcd and cleared it before  it enters while loop
itoa(z,lcd);
lcd_puts(lcd);
delay_ms(100);
lcd_clear();
while (1){
      y=key();
      itoa(y,lcd);
      lcd_puts(lcd);
      delay_ms(50);
}
}
//######################################################### 
 

int key(void){
char KEY = 255 ;
   while(KEY==255){
        PORTD.0 = 1 ;
        PORTD.1 = 0 ;
        PORTD.2 = 0 ;
        PORTD.3 = 0 ;
        if(PIND.4 == 1)
            KEY = 7;     
        if(PIND.5 == 1)
            KEY = 8;    
        if(PIND.6 == 1)
            KEY = 9;   
        if(PIND.7 == 1)
            KEY = 10;       
        //==========================================
        PORTD.0 = 0 ;
        PORTD.1 = 1 ;
        PORTD.2 = 0 ;
        PORTD.3 = 0 ;
        if(PIND.4 == 1)
            KEY = 4;     
        if(PIND.5 == 1)
            KEY = 5;    
        if(PIND.6 == 1)
            KEY = 6;
        if(PIND.7 == 1)
            KEY = 11;       
        //==========================================
        PORTD.0 = 0 ;
        PORTD.1 = 0 ;
        PORTD.2 = 1 ;
        PORTD.3 = 0 ;
        if(PIND.4 == 1)
            KEY = 1;         
        if(PIND.5 == 1)
            KEY = 2;       
        if(PIND.6 == 1)
            KEY = 3;      
        if(PIND.7 == 1)
            KEY = 12;         
        //==========================================
        PORTD.0 = 0 ;
        PORTD.1 = 0 ;
        PORTD.2 = 0 ;
        PORTD.3 = 1 ;
        if(PIND.4 == 1)
            KEY = 15;        
        if(PIND.5 == 1)
            KEY = 0;        
        if(PIND.6 == 1)
            KEY = 14;       
        if(PIND.7 == 1)
            KEY = 13;
        //======================================================= 
    }
    delay_ms(50);     
    return KEY;
}

//############################################################
Here is lcd.h which is a code vision LCD driver routine...


/* LCD driver routines
Code:
  CodeVisionAVR C Compiler
  (C) 1998-2003 Pavel Haiduc, HP InfoTech S.R.L.

  BEFORE #include -ING THIS FILE YOU
  MUST DECLARE THE I/O ADDRESS OF THE
  DATA REGISTER OF THE PORT AT WHICH
  THE LCD IS CONNECTED!

  EXAMPLE FOR PORTB:

    #asm
        .equ __lcd_port=0x18
    #endasm
    #include <lcd.h>

*/

  
#ifndef _LCD_INCLUDED_
#define _LCD_INCLUDED_

#pragma used+

void _lcd_ready(void);
void _lcd_write_data(unsigned char data);
// write a byte to the LCD character generator or display RAM
void lcd_write_byte(unsigned char addr, unsigned char data);
// read a byte from the LCD character generator or display RAM
unsigned char lcd_read_byte(unsigned char addr);
// set the LCD display position  x=0..39 y=0..3
void lcd_gotoxy(unsigned char x, unsigned char y);
// clear the LCD
void lcd_clear(void);
void lcd_putchar(char c);
// write the string str located in SRAM to the LCD
void lcd_puts(char *str);
// write the string str located in FLASH to the LCD
void lcd_putsf(char flash *str);
// initialize the LCD controller
unsigned char lcd_init(unsigned char lcd_columns);

#pragma used-
#pragma library lcd.lib

#endif
 
Last edited:

Pommie

Well-Known Member
Most Helpful Member
Do you have pull down resistors on portd bits 4-7? That's the only thing I can think of that would make it see a key press all the time. Infact, don't AVR input pins have a weak pullup? If so you should switch your logic to inverted and it should work.

Mike.
Edit, like this,
Code:
   while(KEY==255){
        PORTD.0 = 0 ;
        PORTD.1 = 1 ;
        PORTD.2 = 1 ;
        PORTD.3 = 1 ;
        if(PIND.4 == 0)
            KEY = 7;     
        if(PIND.5 == 0)
            KEY = 8;    
        if(PIND.6 == 0)
            KEY = 9;   
        if(PIND.7 == 0)
            KEY = 10;
I just checked and the weak pullups need to be turned on.
 
Last edited:

0y1k

New Member
@nihal_2000 : On PORT how you put the LCD?

i try to change ur code :)

Code:
void main()
{
unsigned char lcd[16];
lcd_init(16);
lcd_clear();
key();
z=10;                          //Just to check LCD is working printing z on lcd and cleared it before  it enters while loop
sprintf(lcd,"%c",z);
lcd_puts(lcd);
delay_ms(100);
lcd_clear();
// and u can continue
Remember u must correct puts LCD pin to PORT uC
 

zaverijuhi

New Member
full code

so please tell me did you find the correnct complete code for keypad interfacing??can u provide it to me.i need it.
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top