Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Problem interfacing keypad with MSP430g2231

Status
Not open for further replies.

richardlaishram

Member level 4
Member level 4
Joined
Jan 6, 2013
Messages
77
Helped
6
Reputation
12
Reaction score
6
Trophy points
1,298
Location
Planet Earth
Visit site
Activity points
1,804
Hi, I've gone through a similar thread Link and I've checked the links provided in that also, but the example stated is in Assembly.
I've designed a 2x2 Keypad (same logic as in 4x4 keypad) just for trial before going for the actual 4x4 keypad. I'm using a msp430g2231 microcontroller and I'm connecting the keypad pins to the Launchpad IO pins. Posted below is the code which I've written in CCS v5.5. Please suggest me where I can go wrong in this code.

Code:
#include <msp430.h> 
#define COL1	(P1OUT &= BIT2)
#define COL2	(P1OUT &= BIT3)
#define ROW1	(P1IN &= BIT4)
#define ROW2	(P1IN  &= BIT5)
volatile unsigned int i, j, k, count;
void delay(j){
	for(i = 0; i <= j; i++)
		k = 1000;
		do{
			k--;
		}while(k != 0);
}

int keypad(){
	COL1;
	if(ROW1){delay(1000); while(ROW1); return 1;}
	if(ROW2){delay(1000); while(ROW2); return 2;}
	COL2;
	if(ROW1){delay(1000); while(ROW1); return 3;}
	if(ROW2){delay(1000); while(ROW2); return 4;}
}

int main(void){
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    P1DIR = BIT0 + BIT2 + BIT3 + BIT6;
    P1REN = BIT2 + BIT3 + BIT4 + BIT5;
    while(1){
    	count = keypad();
        if(count == 1){P1OUT = BIT0;}
        if(count == 2){P1OUT = BIT6;}
        if(count == 3){P1OUT = BIT0 + BIT6;}
        if(count == 4){P1OUT = BIT0; delay(1000); P1OUT = BIT6; delay(1000);}
    }
	return 0;
}

Please bear with me, I'm using msp430 chips for the first time.
 

Hello!

It looks like you didn't get how it works.
If you want to make a 2 x 2 keypad, it means that you have 2 lines and 2 columns. You power
for example the columns alternatively and then you read the lines.
In your main code, you have set P1DIR in output for your lines AND columns. How will you be
able to read?
What you have to do (in pseudo code)

LOOP
PowerCol1();
CheckLinesStatus();
PowerCol2();
CheckLinesStatus();
ENDLOOP

Beside this, there is some confusion in your indices. You uses BIT2 ~ BIT5 of port 1, but
you use also BIT0 and BIT6...

Now one more comment:
When you are using a 4x4 keypad, it's worth doing it this way because you can detect 16 keys
with 8 signal lines. Now if you use a 2x2 keypad, you detect 4 buttons with 4 signal lines, which
complicates unnecessarily. If you need interruptible lines for other purposes (port 1 or 2), then
it would make sense, but in this case you would have to power your switches with port 3 or more.

Dora.
 

It looks like you didn't get how it works.
I'm aware of the scanning function of the keypad.
Beside this, there is some confusion in your indices. You uses BIT2 ~ BIT5 of port 1, but you use also BIT0 and BIT6...
The column is BIT2 + BIT3 is output and the row BIT4 + BIT5 is input. BIT0 and BIT6 are the pins which I've connected to the LED so that I can check if the keypad is properly working or not.
if you use a 2x2 keypad, you detect 4 buttons with 4 signal lines, which complicates unnecessarily.
I'm going to work with the 4x4 keypad only for my real project, but as I don't have that, I was checking if the working logic is working fine with a 2x2 keypad which requires 4 IO pins for 4 buttons.

I'm finding difficulties in declaring the IO Pin functionality also. Please have a look at this commented code and correct me. Thanks in advance.
Code:
int keypad(){
	COL1;     // Column 1 is made high
	if(ROW1){delay(1000); while(ROW1); return 1;}   // Return 1 if Row 1 is high
	if(ROW2){delay(1000); while(ROW2); return 2;}   // Return 2 if Row 2 is high
	COL2;    // Column 2 is made high
	if(ROW1){delay(1000); while(ROW1); return 3;}   // Return 3 if Row 1 is high
	if(ROW2){delay(1000); while(ROW2); return 4;}   // Return 4 if Row 2 is high
}
 

Hello!

Your ROW1 and ROW2 tests are wrong.

If you do this:

#define ROW1 (P1IN &= BIT4)

it means:
P1IN = P1IN & BIT4;

For example in this section:

(1) COL1; // Column 1 is made high
(2) if(ROW1){delay(1000); while(ROW1); return 1;} // Return 1 if Row 1 is high
(3) if(ROW2){delay(1000); while(ROW2); return 2;} // Return 2 if Row 2 is high

Suppose you have a 1 to row 2.

(1) you power the column, and you get the ROW2 bit.
(2) you AND P1 with ROW1 bit => ROW 2 bit disappears.
(3) you test for ROW 2, but you have just removed it in (2).

I guess it's the reason it does not work.

Now I think you should not do polling. You should use interrupts, that's what they are made
for. If you have no interrupt, then you can keep low power mode. And you work only if you
get one interrupt.
With your implementation, the processor will keep consuming clock cycles for nothing.
In this case, there is no point using a low power processor.

Dora.
 
I'll work on using Interrupts instead of polling, thank you very much for your suggestions, hopefully it'll work after I put some extra efforts again.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top