KEYPAD PORT CHANGE.

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

Can someone help me change the port of keypad 4x4? I want to shift lower nibble port D pins to port B lower nibble because I have to use serial communication and external interrupts.

////////////////////////	KEYAPD	/////////////////////////////
#define KEY_PRT 	PORTD
#define KEY_DDR		DDRD
#define KEY_PIN		PIND

unsigned char keypad[4][4] = {
	{'A','3','2','1'},
	{'B','6','5','4'},
	{'C','9','8','7'},
	{'D','#','0','*'}};

	unsigned char colloc, rowloc;

	char keyfind()
	{
		while(1)
		{
			KEY_DDR = 0xF0;           /* set port direction as input-output */
			KEY_PRT = 0xFF;

			do
			{
				KEY_PRT &= 0x0F;      /* mask PORT for column read only */
				asm("NOP");
				colloc = (KEY_PIN & 0x0F); /* read status of column */
			}while(colloc != 0x0F);

			do
			{
				do
				{
					_delay_ms(20);             /* 20ms key debounce time */
					colloc = (KEY_PIN & 0x0F); /* read status of column */
					}while(colloc == 0x0F);        /* check for any key press */

					_delay_ms (40);	            /* 20 ms key debounce time */
					colloc = (KEY_PIN & 0x0F);
				}while(colloc == 0x0F);

				/* now check for rows */
				KEY_PRT = 0xEF;            /* check for pressed key in 1st row */
				asm("NOP");
				colloc = (KEY_PIN & 0x0F);
				if(colloc != 0x0F)
				{
					rowloc = 0;
					break;
				}

				KEY_PRT = 0xDF;		/* check for pressed key in 2nd row */
				asm("NOP");
				colloc = (KEY_PIN & 0x0F);
				if(colloc != 0x0F)
				{
					rowloc = 1;
					break;
				}

				KEY_PRT = 0xBF;		/* check for pressed key in 3rd row */
				asm("NOP");
				colloc = (KEY_PIN & 0x0F);
				if(colloc != 0x0F)
				{
					rowloc = 2;
					break;
				}
				KEY_PRT = 0x7F;		/* check for pressed key in 4th row */
				asm("NOP");
				colloc = (KEY_PIN & 0x0F);
				if(colloc != 0x0F)
				{
					rowloc = 3;
					break;
				}
			}

			if(colloc == 0x0E)
			return(keypad[rowloc][0]);
			else if(colloc == 0x0D)
			return(keypad[rowloc][1]);
			else if(colloc == 0x0B)
			return(keypad[rowloc][2]);
			else
			return(keypad[rowloc][3]);
		}
////////////////////////////////////////////////////

I cannot find a new code for the keypad which works.

thanks for help.

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

Get rid of your Magic Numbers - instead #define symbolic names so that you can easily use arbitrary pins on arbitrary ports!

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thats not my code i just copy paste it

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

can I change this 

#define KEY_PRT 	PORTD
#define KEY_DDR		DDRD
#define KEY_PIN		PIND

by bit manipulation like join both port d and b (D7, D6, D5, D4, B3, B2, B1, B0).

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

Obviously, if your keypad is not on a single port, you can't just have a single #define for the port - can you?

 

How general do you want it to be?

 

In the OP, you just talked about having 4 bits on the lower nibble of one port, and 4 bits on the lower nibble of another port.

 

Or do you want to make it completely general - so that any bit can be on any pin of any port?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I juat want that col goes to port d upper nibble and rows goes to port b lower nibble . How can i do this ?

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

Do you understand how the code you copied works?

 

You could start by just modifying it to use a different complete port.

 

Then think about how to combine half of one port and half of the other ...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Because of this

#define KEY_DDR		DDRD

and this

		KEY_DDR = 0xF0;           /* set port direction as input-output */

It's clear that this existing code is using PD7..PD4 as the outputs and PD3..PD0 as the inputs. If you want to split this you are going to need something like:

#define KEY_DDR_OUT		DDRD
#define KEY_DDR_IN		DDRB

then something like:

        KEY_DDR_OUT = 0x0F;           /* set low 4 bits of D as the outputs */
        KEY_DDR_IN  = 0x?0;           /* set low 4 bits of B as the inputs */        

I left ? in second line here as I don't know what you want to do with the upper 4 bits of B ?

 

In the same way that I have split this you will need to split:

#define KEY_PRT 	PORTD
#define KEY_PIN		PIND

In a similar way - now if it's the case that writes are only ever made to KEY_PRT and reads are only ever made to KEY_PIN then this may be as simple as:

#define KEY_PRT 	PORTD
#define KEY_PIN		PINB

but now the output bits are in the lower 4 of D you are going to need to change lines such as:

				KEY_PRT = 0xEF;            /* check for pressed key in 1st row */

to be

				KEY_PRT = 0x?E;            /* check for pressed key in 1st row */

Again I used ? because I can't know what you want to do with the 4 high bits now.