Re: MSP430-ez430 Basics - reading in pushbutton values



On Apr 21, 8:00 pm, larwe <zwsdot...@xxxxxxxxx> wrote:
Hi,

On Apr 21, 1:33 pm, Hamza <hamzasag...@xxxxxxxxxxxxxx> wrote:

First, thank you for posting such a well-enunciated inquiry. It
doesn't happen often enough here.

I've connected two pushbuttons, one to P1.3 and one to P1.4 and they
are pulled up to Vcc with 10K resistors. I've hooked them up to my
multimeter and they drop to 0V when the button is pressed so they seem
to be working.
P1DIR = 0x1D;
P1OUT = 0x00;

As a rule you should also make it a point to initialize the PxSEL
register when using the MSP430 family. So add P1SEL = 0x00 here. But
that isn't your problem:



for (;;){
if ( !(P1IN & 0x10) ){ // button a on port1.3 pressed?

No it isn't, this code checks if P1.4 is pressed.

P1OUT |= 0x80; // turn on led 1 (port 1.0)

No it isn't... this code turns on P1.7.

} else if ( !(P1IN & 0x08) ){ // button b on port1.4
pressed?

No it isn't... this code checks if P1.3 is pressed.

P1OUT |= 0x20; // turn on led 2 (port 1.2)

No it isn't... this code turns on P1.5

} else {
P1OUT = 0xFF;
}

and this code ensures that both LEDs are always on even if the buttons
aren't pressed :)

The header files define macros for you to access the bits directly to
avoid confusion.
So try this:

if ( !(P1IN & BIT3) ){ // button a on port1.3
pressed?
P1OUT |= BIT0; // turn on led 1 (port 1.0)
} else if ( !(P1IN & BIT4) ){ // button b on port1.4
pressed?
P1OUT |= BIT2; // turn on led 2 (port 1.2)
} else {
P1OUT &= ~(BIT0 | BIT2); // turn off LEDs
}

This code is still not bug-free (consider what happens when only one
button is pressed, then the second is pressed and released while the
first is still held down), but it is closer to what you're trying to
do.


Silly me!

I really should have looked deeper before I let it out, sorry about
the mess :)

Thank you very much for your help, and also the hint on the shorthand
BIT macros. I understand the flaws of this approach to handling
pushbuttons, I was just trying to test if I was actually reading
anything.

Moving one step ahead on the same topic, I have written this little
bit of code to implement interrupt handling, which I believe is a
better alternative to polling. The idea is the LED on P1.0 will toggle
away happily until a key is pressed and then the interrupt handler
p1_interrupt() will kick in and toggle the LED on P1.2.

I have scavenged bits and pieces from some samples and came up with
the following mess:

#include <io.h>
#include <signal.h>

#ifndef __MSP430_2012__
#define __MSP430_2012__
#endif

interrupt (PORT1_VECTOR) p1_interrupt(){
dint();
if(P1IFG==0x01){
P1OUT ^= BIT2; // toggle LED on P1.2
}
eint();
}

int main(void){
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR = 0x07;
P1OUT = 0x00;
P1SEL = 0x00;
P1IFG = 0X00; // No interrupt is pending
P1IES = 0X01; // The PxIFGx flag is set with a high-to-low transition
P1IE = 0X01; // The interrupt is enabled

eint();

int i;
for (;;){
// toggle the LED on p1.0
P1OUT ^= BIT0;
i = 20000;
while (i != 0){ i--; };
}
}


It compiles fine but the problem is the program never leaves the
interrupt handler! P1.2 toggles continuously whether I press the
button or not.


Am I missing something really obvious again?


Many thanks,
Hamza.

.