Sign in

username:

password:



Not a member?

Search msp430



Search tips

Subscribe to msp430



Ads

Discussion Groups

Discussion Groups | MSP430 | Problems with scanning key on my keypad program

The purpose of this group is to foster exchange of information on the Texas Instruments MSP430 family of microcontrollers and related tools. Everyone welcome, all levels of familiarity/expertise.

Problems with scanning key on my keypad program - Eddy - Aug 17 20:27:52 2008

Hi guys,

I am designing a wireless keypad with eZ430-RF2500. I have been using
eZ430-RF2500 demo program and application note SLAA139 as my
foundation. The hardware part is hooked up similar to SLAA139, yet I
switched Port 1 interrupt to Port 2, and Port 3 to Port 4 on my
design, and I use IAR to develop my code.

I have got the Port 2 interrupt working on with this program. (I
deleted the BSP_ISR_FUNCTION() from the demo program and added my own
ISR in the end of the code)

Few things are bugging me here. Could you please help me to solve it?

1. Why doesn't my KeyScan() function work? The scanning result is
always the same? Is it actually running?

2. Is my debounce() function running? Timer A counting up?

3. Last question may sound kind of stupid. Where does the program go
to after returning from interrupt service routine? Doesn't it return
to where the program was running instead of where the interrupt was
enable??

Thank you in advance for answering my questions.

Eddy

//////////////////////////////////////////////////////////////////////
#include "bsp.h"
#include "mrfi.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "vlo_rand.h"
void linkTo(int data[7]);
void debounce(void);
void Set_For_Press(void);
int Look_Up( int column, int row);
void KeyScan(void);
void Wait_For_Release(int row);
void createRandomAddress();

__no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address set
randomly

static unsigned int column;
static unsigned int row;
static unsigned int flag = 0;

static unsigned int ISR_key;
static unsigned int ISR_debounce;

void main (void)
{
addr_t lAddr;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
{
// delay loop to ensure proper startup before SimpliciTI increases DCO
// This is typically tailored to the power supply used, and in this case
// is overkill for safety due to wide distribution.
volatile int i;
for(i = 0; i < 0xFFFF; i++){}
}
if( CALBC1_8MHZ == 0xFF ) // Do not run if cal
values are erased
{
volatile int i;
P1DIR |= 0x03;
BSP_TURN_ON_LED1();
BSP_TURN_OFF_LED2();
while(1)
{
for(i = 0; i < 0x5FFF; i++){}
BSP_TOGGLE_LED2();
BSP_TOGGLE_LED1();
}
}

// SimpliciTI will change port pin settings as well
P1DIR = 0xFF;
P1OUT = 0x00;
P2DIR = 0x27;
P2OUT = 0x00;
P3DIR = 0xC0;
P3OUT = 0x00;
P4DIR = 0xFF;
P4OUT = 0x00;

BSP_Init();

if( Flash_Addr[0] == 0xFF &&
Flash_Addr[1] == 0xFF &&
Flash_Addr[2] == 0xFF &&
Flash_Addr[3] == 0xFF )
{
createRandomAddress(); // set Random device
address at initial startup
}
lAddr.addr[0]=Flash_Addr[0];
lAddr.addr[1]=Flash_Addr[1];
lAddr.addr[2]=Flash_Addr[2];
lAddr.addr[3]=Flash_Addr[3];
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);

BCSCTL1 = CALBC1_8MHZ; // Set DCO after random
function
DCOCTL = CALDCO_8MHZ;
BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO

int data[7]; // Data send
for (int x = 0; x <=6; x++)
{data[x] = 9;} // Initial value

while(1)
{
Set_For_Press();
debounce();
KeyScan();
switch (column)
{
case 0:
for (int x = 0; x <=6; x++)
{data[x] = 0;}
break;
case 1:
for (int x = 0; x <=6; x++)
{data[x] = 1;}
break;
case 2:
for (int x = 0; x <=6; x++)
{data[x] = 3;}
break;
}

// keep trying to join until successful. toggle LEDS to indicate
that
// joining has not occurred. LED3 is red but labeled LED 4 on
the EXP
// board silkscreen. LED1 is green.
while (SMPL_NO_JOIN == SMPL_Init((uint8_t (*)(linkID_t))0))
{
BSP_TOGGLE_LED1();
BSP_TOGGLE_LED2();
__bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts
enabled
}

// unconditional link to AP which is listening due to successful
join.
linkTo(data);
}
}

////////////////////////////////////////////////////////////////////////////////

void KeyScan()
{
P2OUT &= ~0x07; // Clear P2.0-P2.2

for(int mask = 0; mask < 4 ; mask++)
{
//leak charge on pins
P4OUT &= ~0x78; // Output low on P4.3 to P4.6

P2DIR |= 0x07; // P2.0-P2.2 as output
P2OUT &= ~0x07; // P2.0-P2.2 output low

P2DIR &= ~0x07; //P2.0-P2.2 as input to scan column
P4OUT = 0x08< if (P2IN & 0x01){
column = 0;
row = mask;
flag = 0;
P4OUT |= 0x78;
return;}
else if (P2IN & 0x02){
column = 1;
row = mask;
flag = 0;
P4OUT |= 0x78;
return;}
else if (P2IN & 0x04){
column = 2;
row = mask;
flag = 0;
P4OUT |= 0x78;
return;}
}
flag = 1;
P4OUT |= 0x78;
return;
}

////////////////////////////////////////////////////////////////////////////////
void Wait_For_Release(int row)
{
// Isolate one row that is in use
P3OUT = row&0x78;

// Setup for interrupt on key release
P2DIR |= 0x07;
P2OUT &= ~0x07;

P2DIR &= ~0x07; // P2.0-P2.2 as input
P2IE |= 0x07; // P2.0-P2.2 interrupt enable
P2IES |= 0x07; // P2.0-P2.2 Hi/lo edge
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
__bic_SR_register(LPM4_bits+GIE);

}

////////////////////////////////////////////////////////////////////////////////
int Look_Up( int column, int row)
{
int key;
// key = enter values, 10 = * , 11 = # , 12 = erro

if (column == 0x01){
if (row ==0x04)
key = 1;
else if (row == 0x10)
key = 4;
else if (row == 0x20)
key = 7;
else if (row == 0x40)
key = 10; // 10 => *
else
key = 12;
}
else if (column == 0x02){
if (row ==0x04)
key = 2;
else if (row == 0x10)
key = 5;
else if (row == 0x20)
key = 8;
else if (row == 0x40)
key = 0;
else
key = 12;
}
else if (column == 0x04){
if (row ==0x04)
key = 3;
else if (row == 0x10)
key = 6;
else if (row == 0x20)
key = 9;
else if (row == 0x40)
key = 11; // 11 => #
else
key = 12;
}
else
key = 12;

return key;
}
////////////////////////////////////////////////////////////////////////////////
void Set_For_Press()
{
P4DIR |= 0x78;
P4OUT |= 0x78;

P2DIR &= ~0x07; // P2.0-P2.2 as input
P2IE |= 0x07; // P2.0-p2.2 interrupt
enabled
P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
__bic_SR_register(LPM4_bits+GIE);
}
////////////////////////////////////////////////////////////////////////////////
void debounce()
{
TACCTL0 = CCIE; // TACCR0 interrupt enabled
TACCR0 = 480; // 40ms
TACTL = TASSEL_1 + MC_1; // ACLK, upmode
ISR_debounce = 1;
__bic_SR_register(LPM0_bits+GIE);
}

////////////////////////////////////////////////////////////////////////////////

void createRandomAddress()
{
unsigned int rand, rand2;
do
{
rand = TI_getRandomIntegerFromVLO(); // first byte can not be
0x00 of 0xFF
}
while( (rand & 0xFF00)==0xFF00 || (rand & 0xFF00)==0x0000 );
rand2 = TI_getRandomIntegerFromVLO();

BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing
Generator
FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits
FCTL1 = FWKEY + WRT; // Set WRT bit for write
operation

Flash_Addr[0]=(rand>>8) & 0xFF;
Flash_Addr[1]=rand & 0xFF;
Flash_Addr[2]=(rand2>>8) & 0xFF;
Flash_Addr[3]=rand2 & 0xFF;

FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit
}

////////////////////////////////////////////////////////////////////////////////
void linkTo(int data[7])
{
linkID_t linkID1;
uint8_t msg[7];

// keep trying to link...
while (SMPL_SUCCESS != SMPL_Link(&linkID1))
{
__bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts
enabled
BSP_TOGGLE_LED1();
BSP_TOGGLE_LED2();
}

// Turn off all LEDs
if (BSP_LED1_IS_ON())
{
BSP_TOGGLE_LED1();
}
if (BSP_LED2_IS_ON())
{
BSP_TOGGLE_LED2();
}

while(1)
{
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, "" );
__bis_SR_register(LPM3_bits+GIE); // LPM3 with interrupts
enabled
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, "" );

BSP_TOGGLE_LED2();

msg[0] = '0' + data[0];
msg[1] = '0' + data[1];
msg[2] = '0' + data[2];
msg[3] = '0' + data[3];
msg[4] = '0' + data[4];
msg[5] = '0' + data[5];
msg[6] = '0' + data[6];

if (SMPL_SUCCESS == SMPL_Send(linkID1, msg, sizeof(msg)))
{
BSP_TOGGLE_LED2();
}
else
{
BSP_TOGGLE_LED2();
BSP_TOGGLE_LED1();
}
}
}

/*------------------------------------------------------------------------------
* Timer A0 interrupt service routine
------------------------------------------------------------------------------*/
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
__bic_SR_register_on_exit(LPM0_bits); // Clear LPM3 bit from
0(SR)
TACTL |= TACLR;
TACCTL0 &= CCIFG;
}

////////////////////////////////////////////////////////////////////////////////
// Port 2 interrupt service routine
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
__bic_SR_register_on_exit(LPM4_bits);
MRFI_GpioIsr();
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
ISR_key = 1;
}

------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )


RE: Problems with scanning key on my keypad program - Pablo Villaverde Padilla - Aug 18 0:24:19 2008

Hello there:

Is your processor entering LPM before it is awaken by a P2 interrupt? Is
your TimerA stopping after you return from the associated ISR? It must be
stopped for the next debounce and it seems you let it run all the time after
you configure it.

Your comments suggest you are getting an ISR as soon as you enable the
interrupt. Debug and find out why if that's the case.

It's possible that your code is always going the same wrong path, so you see
the same result every time. That's why in my other post I recommended you
studied the app note more deeply to understand the important details that
make it work. Oh, and by the way, recheck your C translation , I think there
are subtle errors when you set or reset bits in the code you included in
this post. Little details are a huge difference.

Good luck!

Pablo

De: m...@yahoogroups.com [mailto:m...@yahoogroups.com] En nombre de Eddy
Enviado el: Sunday, August 17, 2008 7:28 PM
Para: m...@yahoogroups.com
Asunto: [msp430] Problems with scanning key on my keypad program

Hi guys,

I am designing a wireless keypad with eZ430-RF2500. I have been using
eZ430-RF2500 demo program and application note SLAA139 as my
foundation. The hardware part is hooked up similar to SLAA139, yet I
switched Port 1 interrupt to Port 2, and Port 3 to Port 4 on my
design, and I use IAR to develop my code.

I have got the Port 2 interrupt working on with this program. (I
deleted the BSP_ISR_FUNCTION() from the demo program and added my own
ISR in the end of the code)

Few things are bugging me here. Could you please help me to solve it?

1. Why doesn't my KeyScan() function work? The scanning result is
always the same? Is it actually running?

2. Is my debounce() function running? Timer A counting up?

3. Last question may sound kind of stupid. Where does the program go
to after returning from interrupt service routine? Doesn't it return
to where the program was running instead of where the interrupt was
enable??

Thank you in advance for answering my questions.

Eddy

//////////////////////////////////////////////////////////////////////
#include "bsp.h"
#include "mrfi.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "vlo_rand.h"

void linkTo(int data[7]);
void debounce(void);
void Set_For_Press(void);
int Look_Up( int column, int row);
void KeyScan(void);
void Wait_For_Release(int row);
void createRandomAddress();

__no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address set
randomly

static unsigned int column;
static unsigned int row;
static unsigned int flag = 0;

static unsigned int ISR_key;
static unsigned int ISR_debounce;

void main (void)
{
addr_t lAddr;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
{
// delay loop to ensure proper startup before SimpliciTI increases DCO
// This is typically tailored to the power supply used, and in this case
// is overkill for safety due to wide distribution.
volatile int i;
for(i = 0; i < 0xFFFF; i++){}
}
if( CALBC1_8MHZ == 0xFF ) // Do not run if cal
values are erased
{
volatile int i;
P1DIR |= 0x03;
BSP_TURN_ON_LED1();
BSP_TURN_OFF_LED2();
while(1)
{
for(i = 0; i < 0x5FFF; i++){}
BSP_TOGGLE_LED2();
BSP_TOGGLE_LED1();
}
}

// SimpliciTI will change port pin settings as well
P1DIR = 0xFF;
P1OUT = 0x00;
P2DIR = 0x27;
P2OUT = 0x00;
P3DIR = 0xC0;
P3OUT = 0x00;
P4DIR = 0xFF;
P4OUT = 0x00;

BSP_Init();

if( Flash_Addr[0] == 0xFF &&
Flash_Addr[1] == 0xFF &&
Flash_Addr[2] == 0xFF &&
Flash_Addr[3] == 0xFF )
{
createRandomAddress(); // set Random device
address at initial startup
}
lAddr.addr[0]=Flash_Addr[0];
lAddr.addr[1]=Flash_Addr[1];
lAddr.addr[2]=Flash_Addr[2];
lAddr.addr[3]=Flash_Addr[3];
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);

BCSCTL1 = CALBC1_8MHZ; // Set DCO after random
function
DCOCTL = CALDCO_8MHZ;
BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO

int data[7]; // Data send
for (int x = 0; x <=6; x++)
{data[x] = 9;} // Initial value
while(1)
{
Set_For_Press();
debounce();
KeyScan();
switch (column)
{
case 0:
for (int x = 0; x <=6; x++)
{data[x] = 0;}
break;
case 1:
for (int x = 0; x <=6; x++)
{data[x] = 1;}
break;
case 2:
for (int x = 0; x <=6; x++)
{data[x] = 3;}
break;
}

// keep trying to join until successful. toggle LEDS to indicate
that
// joining has not occurred. LED3 is red but labeled LED 4 on
the EXP
// board silkscreen. LED1 is green.
while (SMPL_NO_JOIN == SMPL_Init((uint8_t (*)(linkID_t))0))
{
BSP_TOGGLE_LED1();
BSP_TOGGLE_LED2();
__bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts
enabled
}

// unconditional link to AP which is listening due to successful
join.
linkTo(data);
}
}

////////////////////////////////////////////////////////////////////////////
////

void KeyScan()
{
P2OUT &= ~0x07; // Clear P2.0-P2.2

for(int mask = 0; mask < 4 ; mask++)
{
//leak charge on pins
P4OUT &= ~0x78; // Output low on P4.3 to P4.6

P2DIR |= 0x07; // P2.0-P2.2 as output
P2OUT &= ~0x07; // P2.0-P2.2 output low

P2DIR &= ~0x07; //P2.0-P2.2 as input to scan column
P4OUT = 0x08< if (P2IN & 0x01){
column = 0;
row = mask;
flag = 0;
P4OUT |= 0x78;
return;}
else if (P2IN & 0x02){
column = 1;
row = mask;
flag = 0;
P4OUT |= 0x78;
return;}
else if (P2IN & 0x04){
column = 2;
row = mask;
flag = 0;
P4OUT |= 0x78;
return;}
}
flag = 1;
P4OUT |= 0x78;
return;
}

////////////////////////////////////////////////////////////////////////////
////
void Wait_For_Release(int row)
{
// Isolate one row that is in use
P3OUT = row&0x78;

// Setup for interrupt on key release
P2DIR |= 0x07;
P2OUT &= ~0x07;

P2DIR &= ~0x07; // P2.0-P2.2 as input
P2IE |= 0x07; // P2.0-P2.2 interrupt enable
P2IES |= 0x07; // P2.0-P2.2 Hi/lo edge
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
__bic_SR_register(LPM4_bits+GIE);

}

////////////////////////////////////////////////////////////////////////////
////
int Look_Up( int column, int row)
{
int key;
// key = enter values, 10 = * , 11 = # , 12 = erro

if (column == 0x01){
if (row ==0x04)
key = 1;
else if (row == 0x10)
key = 4;
else if (row == 0x20)
key = 7;
else if (row == 0x40)
key = 10; // 10 => *
else
key = 12;
}
else if (column == 0x02){
if (row ==0x04)
key = 2;
else if (row == 0x10)
key = 5;
else if (row == 0x20)
key = 8;
else if (row == 0x40)
key = 0;
else
key = 12;
}
else if (column == 0x04){
if (row ==0x04)
key = 3;
else if (row == 0x10)
key = 6;
else if (row == 0x20)
key = 9;
else if (row == 0x40)
key = 11; // 11 => #
else
key = 12;
}
else
key = 12;

return key;
}
////////////////////////////////////////////////////////////////////////////
////
void Set_For_Press()
{
P4DIR |= 0x78;
P4OUT |= 0x78;

P2DIR &= ~0x07; // P2.0-P2.2 as input
P2IE |= 0x07; // P2.0-p2.2 interrupt
enabled
P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
__bic_SR_register(LPM4_bits+GIE);
}
////////////////////////////////////////////////////////////////////////////
////
void debounce()
{
TACCTL0 = CCIE; // TACCR0 interrupt enabled
TACCR0 = 480; // 40ms
TACTL = TASSEL_1 + MC_1; // ACLK, upmode
ISR_debounce = 1;
__bic_SR_register(LPM0_bits+GIE);
}

////////////////////////////////////////////////////////////////////////////
////

void createRandomAddress()
{
unsigned int rand, rand2;
do
{
rand = TI_getRandomIntegerFromVLO(); // first byte can not be
0x00 of 0xFF
}
while( (rand & 0xFF00)==0xFF00 || (rand & 0xFF00)==0x0000 );
rand2 = TI_getRandomIntegerFromVLO();

BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing
Generator
FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits
FCTL1 = FWKEY + WRT; // Set WRT bit for write
operation

Flash_Addr[0]=(rand>>8) & 0xFF;
Flash_Addr[1]=rand & 0xFF;
Flash_Addr[2]=(rand2>>8) & 0xFF;
Flash_Addr[3]=rand2 & 0xFF;

FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit
}

////////////////////////////////////////////////////////////////////////////
////
void linkTo(int data[7])
{
linkID_t linkID1;
uint8_t msg[7];

// keep trying to link...
while (SMPL_SUCCESS != SMPL_Link(&linkID1))
{
__bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts
enabled
BSP_TOGGLE_LED1();
BSP_TOGGLE_LED2();
}

// Turn off all LEDs
if (BSP_LED1_IS_ON())
{
BSP_TOGGLE_LED1();
}
if (BSP_LED2_IS_ON())
{
BSP_TOGGLE_LED2();
}

while(1)
{
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, "" );
__bis_SR_register(LPM3_bits+GIE); // LPM3 with interrupts
enabled
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, "" );

BSP_TOGGLE_LED2();

msg[0] = '0' + data[0];
msg[1] = '0' + data[1];
msg[2] = '0' + data[2];
msg[3] = '0' + data[3];
msg[4] = '0' + data[4];
msg[5] = '0' + data[5];
msg[6] = '0' + data[6];

if (SMPL_SUCCESS == SMPL_Send(linkID1, msg, sizeof(msg)))
{
BSP_TOGGLE_LED2();
}
else
{
BSP_TOGGLE_LED2();
BSP_TOGGLE_LED1();
}
}
}

/*----------------------------------------------------------
* Timer A0 interrupt service routine
----------------------------------------------------------*/
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
__bic_SR_register_on_exit(LPM0_bits); // Clear LPM3 bit from
0(SR)
TACTL |= TACLR;
TACCTL0 &= CCIFG;
}

////////////////////////////////////////////////////////////////////////////
////
// Port 2 interrupt service routine
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
__bic_SR_register_on_exit(LPM4_bits);
MRFI_GpioIsr();
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
ISR_key = 1;
}

[Non-text portions of this message have been removed]
------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )

Re: Problems with scanning key on my keypad program - Eddy - Aug 18 3:32:41 2008

Hi Pablo,

Thanx for the suggestion. I checked my Timer A. You were right about
that. It does keep going even after ISR. I cleared the timer interrupt
flag in the ISR, yet it doesn't stop afterwards. Any suggestions?

And for the KeyScan() function. I made some modification on it and
tried it on a small individual program(included below). It does work
to indicate which keypad column I press on port 3 output. Yet, it
fails when I join it with the demo code. Does the demo code use Port 2
for some other purpose so I can't configure port 2 to other configuration?

I am still trying to figure out where the hell my program is running to.

Thanx for the help.

Eddy
/////////////////////////Test Program//////////////////////////////

#include "msp430x22x4.h"
void KeyScan(void);

static unsigned int column;
static unsigned int row;
static unsigned int flag;

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= 0x03; // P1.0-P1.1 as output
P1OUT &= ~0x03; // Port 1 output low

P4DIR |= 0x78;
P4OUT |= 0x78;
P3DIR = 0xff;
P3OUT = 0x00;

P2DIR &= ~0x07; // P2.0-P2.2 as input
P2IE |= 0x07; // P2.0-p2.2 interrupt
enabled
P2IES &= ~0x07; // P2.0-p2.2 lo/Hi edge
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
__bis_SR_register(LPM4_bits + GIE); // Enter LPM4 w/interrupt

while(1)
{
if(column == 0)
P3OUT = 0x01;
else if(column == 1)
P3OUT = 0x02;
else if(column == 2)
P3OUT = 0x04;
else
P3OUT = 0x04;
}
}

////////////////////////////////////////////////////////////////////////////////
void KeyScan()
{
P2OUT &= ~0x07; // Clear P2.0-P2.2

for(int mask = 0; mask < 4 ; mask++)
{
//leak charge on pins
P4OUT &= ~0x78; // Output low on P4.3 to P4.6
P2DIR |= 0x07; // P2.0-P2.2 as output
P2OUT &= ~0x07; // P2.0-P2.2 output low
// for(int x = 0; x<= 2000; x++){}

P2DIR &= ~0x07; //P2.0-P2.2 as input to scan column
P4OUT = 0x08< if (P2IN & 0x01){
column = 0;
row = mask;
flag = 0;
P4OUT |= 0x78;
return;}
else if (P2IN & 0x02){
column = 1;
row = mask;
flag = 0;
P4OUT |= 0x78;
return;}
else if (P2IN & 0x04){
column = 2;
row = mask;
flag = 0;
P4OUT |= 0x78;
return;}
}
flag = 1;
P4OUT |= 0x78;
return;
}
////////////////////////////////////////////////////////////////////////////////
// Port 2 interrupt service routine
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
__bic_SR_register_on_exit(LPM4_bits);
P2IFG &= ~0x07; // P2.0-P2.2 IFG cleared
KeyScan();
}
///////////////////////////end of the program////////////////////////

> Is your processor entering LPM before it is awaken by a P2
interrupt? Is
> your TimerA stopping after you return from the associated ISR? It
must be
> stopped for the next debounce and it seems you let it run all the
time after
> you configure it.
>
> Your comments suggest you are getting an ISR as soon as you enable the
> interrupt. Debug and find out why if that's the case.
>
>
>
> It's possible that your code is always going the same wrong path, so
you see
> the same result every time. That's why in my other post I
recommended you
> studied the app note more deeply to understand the important details
that
> make it work. Oh, and by the way, recheck your C translation , I
think there
> are subtle errors when you set or reset bits in the code you included in
> this post. Little details are a huge difference.
>
>
>
> Good luck!
>
>
>
> Pablo

------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )