[CODE] [C] 4x4 KEYPAD

Go To Last Post
17 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Below is the code for 4x4 matrix keypad connected in PORTC of xmega a3bu, i want to if there any logical errors in the code and also will the data be transferred from PORTA.IN to any variable like in the code below.

The problem is LED is not blinking.

PC0-PC3- are inputs - Rows

PC4-PC7 - are outputs - Columns

 

 

 

 

 

 

#define F_CPU 1600000UL
#include <avr/io.h>
#include <util/delay.h>
  

 

void keypadscan(void);
  void blink(void);

 

uint8_t blinkduration = 0;

int main()
{
        PORTR_DIRSET = 0x01; //LED
         
          PORTC.DIR = 0b00001111;
          PORTC.OUT = 0b11110000;  // Rows are low columns are high
          
      
                
    while(1)
    {
        keypadscan();
    }
}
    

void keypadscan()
{
    if(PORTC.IN == 0b11110000) return
    
    _delay_ms(50);
    
    uint8_t keypresscode = (PORTC.IN); //copying contents of portc to variable
    
    
    PORTC.DIR = 0b11110000;
    PORTC.OUT = 0b00001111;  // Rows are high columns are low
    
    asm volatile("nop");
    asm volatile("nop");
    
     keypresscode |= (PORTC.IN);
    
    
    

    if(keypresscode == 0b11101110) blinkduration = 1;blink(); //binary code for keypresses
    if(keypresscode == 0b11011110) blinkduration = 2;blink();
    if(keypresscode == 0b10111110) blinkduration = 3;blink();
    if(keypresscode == 0b01111110) blinkduration = 4;blink();

    if(keypresscode == 0b11101101) blinkduration = 5;blink(); 
    if(keypresscode == 0b11011101) blinkduration = 6;blink(); 
    if(keypresscode == 0b10111101) blinkduration = 7;blink();  
    if(keypresscode == 0b01110101) blinkduration = 8;blink();
    
    if(keypresscode == 0b11101011) blinkduration = 9; blink();
    if(keypresscode == 0b11011011) blinkduration = 10;blink();
    if(keypresscode == 0b10111011) blinkduration = 11;blink();
    if(keypresscode == 0b01111011) blinkduration = 12;blink();
    
    if(keypresscode == 0b11100111) blinkduration = 13;blink();
    if(keypresscode == 0b11010111) blinkduration = 14;blink();
    if(keypresscode == 0b10110111) blinkduration = 15;blink();
    if(keypresscode == 0b01110111) blinkduration = 16;blink();

                    

    
}
void blink()
{
    for (int i; i<blinkduration;i++)
    {
        _delay_ms(100);
        PORTR_OUTCLR= 0x01; //blinking of led
        _delay_ms(100);
        PORTR_OUTSET = 0x01;
    }
}
 

This topic has a solution.

Nitin Shenoy

Last Edited: Thu. Jan 17, 2019 - 07:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the LED is not blinking it is because your blink routine doesn't work or the blink routine is not called.  I'll leave you to think how to check which.

 

David

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I went through it several times then i didnt find any solution and posted it here.I cant find any reason why blink routine is not called.

Nitin Shenoy

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nitinjs wrote:

I went through it several times then i didnt find any solution and posted it here.I cant find any reason why blink routine is not called.

 

Does your blink routine work?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I cant find any reason why blink routine is not called.

 

Can you tell me when it is called then.

 

David 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Everytime the keypress condition holds good.. The blinkduration is set to 1 and the blink routine is called. The for loop works

Nitin Shenoy

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your code will not compile. You have not posted the code as passed to your compiler. Please cut and paste the EXACT code and use the CODE tags (<> button) so that it appears correctly.

 

 

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nitinjs wrote:

Everytime the keypress condition holds good.. The blinkduration is set to 1 and the blink routine is called. The for loop works

 

No. Not true.

 

Hint...read a good book on structuring single line IF statements.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have 16 states for the keypress.  What happens if the keypress is not one of those 16 states?

 

David

 

edit - typo

 

Last Edited: Sat. Jan 12, 2019 - 05:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

exact code and removed the blink routine.


#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
  

 

void keypadscan(void);
//  void blink(void);

int main()
{
        PORTR_DIRSET = 0x01;
         
          PORTC.DIR = 0b00001111;
          PORTC.OUT = 0b11110000;
          
      
                
    while(1)
    {
        keypadscan();
    }
}
  
      

void keypadscan()
{
    if(PORTC.IN == 0b11110000) return
    
    _delay_ms(50);
    
    uint8_t keypresscode = (PORTC.IN);
    
    
    PORTC.DIR = 0b11110000;
    PORTC.OUT = 0b00001111;
    
    asm volatile("nop");
    asm volatile("nop");
    
     keypresscode |= (PORTC.IN);
    
    uint8_t blinkduration = 0;
    
    if(keypresscode == 0b11101110) blinkduration = 1; 
        
    if(keypresscode == 0b11011110) blinkduration = 2;
    if(keypresscode == 0b10111110) blinkduration = 3;
    if(keypresscode == 0b01111110) blinkduration = 4;

    if(keypresscode == 0b11101101) blinkduration = 5;
    if(keypresscode == 0b11011101) blinkduration = 6;
    if(keypresscode == 0b10111101) blinkduration = 7;
    if(keypresscode == 0b01110101) blinkduration = 8;
    
    if(keypresscode == 0b11101011) blinkduration = 9; 
    if(keypresscode == 0b11011011) blinkduration = 10;
    if(keypresscode == 0b10111011) blinkduration = 11;
    if(keypresscode == 0b01111011) blinkduration = 12;
    
    if(keypresscode == 0b11100111) blinkduration = 13;
    if(keypresscode == 0b11010111) blinkduration = 14;
    if(keypresscode == 0b10110111) blinkduration = 15;
    if(keypresscode == 0b01110111) blinkduration = 16;
    
                    

    

if (keypresscode < 0b11111111)
{
    for (int i; i<blinkduration;i++)
    {
        _delay_ms(400);
        PORTR_OUTCLR= 0x01;
        _delay_ms(400);
        PORTR_OUTSET = 0x01;
        
    }
}

}

 

Nitin Shenoy

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

nitinjs wrote:

exact code and removed the blink routine.

    if(PORTC.IN == 0b11110000) return
   

 

It can't be the exact code because this line will throw an error.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Its is actually not.. Its compiling without error

Nitin Shenoy

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nitinjs wrote:
Its is actually not.. Its compiling without error

 

Well that's your first problem then that needs sorting out, that missing ';' is most definitely an error. You need to find out why your compiler is not throwing an error.

 

But you have a more serious problem because your code is doing what it should and blinking the LED exactly zero times. Think about it, how can any of your 'if' tests in keyscan() be true if you do not change PC4-7? They are set as low outputs...

 

    PORTC.DIR = 0b11110000;
    PORTC.OUT = 0b00001111;

 

...so a statement like this...

 

    if(keypresscode == 0b01111110) blinkduration = 4;

 

...can never be true.

 

 

More than that, you never change PC4-7 so you are not scanning your keypad.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

4x4 usually involves two 4 bit groups in 8 bits so you are going to find 0xF0 and 0x0F as very useful AND masks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I didnt understand.

Nitin Shenoy

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

As Brian pointed out:

  PORTC.DIR = 0b11110000;

That suggests you are using the top 4 bits as output and the bottom 4 as input. So when you read the inputs you can use:

 keypresscode = PORTC.IN & 0x0F;

That just sets the 4 upper bits to 0 so you no longer need to worry about those. However when I start to look at your code I realise this isn't going to help as it seems to only be half an implementation. I simply cannot see the place where you set the output row low ??

 

Can I suggest that rather than just typing C into your editor you take a step back and actually DESIGN how this code should work BEFORE you attempt to implement it. The use of 4x4 is fairly well known - it involve 4 output lines potentially connected to 4 input lines. because pull-ups (rather than pull-downs) are usually employed it then involves taking each of the 4 output bits in turn low (one at a time). For each you then read the input bits and check for any that are now pulled low. At the time of reading the input you might mask with 0x0F to isolate just 4 of the 8 bits.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey, thanks a lot everyone.I solved the mistakes i made.

 

PS: Had to change the whole code though.

Nitin Shenoy