mnpumar 2 Posted November 21, 2010 Share Posted November 21, 2010 I'm trying to use P2.7 as an input pin, but it doesn't seem to be working. Here's the code I'm using: int main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; P2OUT = 0; //P2 is output low P2DIR = BIT6 + BIT7; //P2 is output P2SEL = 0; //P2 is digital i/0 P2REN = 0; //P2 disable pullup resistors */ int i = 1; for(;{ //Digital Input while (P2IN & BIT7); //wait for P1.7 to go low (buttion is pressed) Display(i); //display while (!(P2IN & BIT7)); //wait for P1.7 to go high (button is released) i = i + 1; //increase counter if (i > 12) i = 0; //maximum display is 12 } } Whole code is here if necessary: #include "io430.h" void delay(unsigned int n){ while (n > 0) n--; } void TurnON(unsigned x, unsigned y) { unsigned YBITS[5] = {BIT0, BIT1, BIT2, BIT3, BIT4}; unsigned XBITS[3] = {BIT5, BIT6, BIT7}; P1OUT &= ~YBITS[y]; P1SEL &= ~YBITS[y]; P1DIR |= YBITS[y]; P1OUT |= YBITS[y]; if(x < 3) { P1OUT &= ~XBITS[x]; P1SEL &= ~XBITS[x]; P1DIR |= XBITS[x]; P1OUT |= XBITS[x]; }else { P2OUT &= ~BIT6; P2SEL &= ~BIT6; P2DIR |= BIT6; P2OUT |= BIT6; } } void TurnOFF(unsigned x, unsigned y) { unsigned YBITS[5] = {BIT0, BIT1, BIT2, BIT3, BIT4}; unsigned XBITS[3] = {BIT5, BIT6, BIT7}; P1OUT &= ~YBITS[y]; if(x < 3) { P1OUT &= ~XBITS[x]; }else { P2OUT &= ~BIT6; } } void Display(unsigned number) { if(number == 1) { TurnON(3,0); TurnOFF(3,0); TurnON(3,1); TurnOFF(3,1); TurnON(3,2); TurnOFF(3,2); TurnON(3,3); TurnOFF(3,3); TurnON(3,4); TurnOFF(3,4); } if(number == 2) { TurnON(1,0); TurnOFF(1,0); TurnON(2,0); TurnOFF(2,0); TurnON(3,0); TurnOFF(3,0); TurnON(3,1); TurnOFF(3,1); TurnON(3,2); TurnOFF(3,2); TurnON(2,3); TurnOFF(2,3); TurnON(2,2); TurnOFF(2,2); TurnON(1,2); TurnOFF(1,2); TurnON(1,3); TurnOFF(1,3); TurnON(1,4); TurnOFF(1,4); TurnON(2,4); TurnOFF(2,4); TurnON(3,4); TurnOFF(3,4); } else if(number == 3) { Display(1); TurnON(1,0); TurnOFF(1,0); TurnON(2,0); TurnOFF(2,0); TurnON(2,3); TurnOFF(2,3); TurnON(2,2); TurnOFF(2,2); TurnON(1,2); TurnOFF(1,2); TurnON(1,4); TurnOFF(1,4); TurnON(2,4); TurnOFF(2,4); } else if(number == 4) { Display(1); TurnON(1,0); TurnOFF(1,0); TurnON(3,0); TurnOFF(3,0); TurnON(1,1); TurnOFF(1,1); TurnON(1,2); TurnOFF(1,2); TurnON(2,2); TurnOFF(2,2); } else if(number == 5) { TurnON(1,0); TurnOFF(1,0); TurnON(2,0); TurnOFF(2,0); TurnON(3,0); TurnOFF(3,0); TurnON(1,1); TurnOFF(1,1); TurnON(2,2); TurnOFF(2,2); TurnON(1,2); TurnOFF(1,2); TurnON(3,2); TurnOFF(3,2); TurnON(3,3); TurnOFF(3,3); TurnON(1,4); TurnOFF(1,4); TurnON(2,4); TurnOFF(2,4); TurnON(3,4); TurnOFF(3,4); } else if(number == 6) { Display(5); TurnON(1,3); TurnOFF(1,3); } if(number == 7) { Display(1); TurnON(2,0); TurnOFF(2,0); TurnON(1,0); TurnOFF(1,0); } else if(number == 8) { Display(6); TurnON(3,1); TurnOFF(3,1); } else if(number == 9){ Display(7); TurnON(1,1); TurnOFF(1,1); TurnON(1,2); TurnOFF(1,2); TurnON(2,2); TurnOFF(2,2); } else if(number==10){ Display(7); TurnON(1,1); TurnOFF(1,1); TurnON(1,2); TurnOFF(1,2); TurnON(1,3); TurnOFF(1,3); TurnON(1,4); TurnOFF(1,4); TurnON(2,4); TurnOFF(2,4); TurnON(0,0); TurnOFF(0,0); TurnON(0,1); TurnOFF(0,1); TurnON(0,2); TurnOFF(0,2); TurnON(0,3); TurnOFF(0,3); TurnON(0,4); TurnOFF(0,4); }else if(number == 11){ Display(1); TurnON(0,0); TurnOFF(0,0); TurnON(0,1); TurnOFF(0,1); TurnON(0,2); TurnOFF(0,2); TurnON(0,3); TurnOFF(0,3); TurnON(0,4); TurnOFF(0,4); }else if(number == 12){ Display(2); TurnON(0,0); TurnOFF(0,0); TurnON(0,1); TurnOFF(0,1); TurnON(0,2); TurnOFF(0,2); TurnON(0,3); TurnOFF(0,3); TurnON(0,4); TurnOFF(0,4); } } int main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; P2OUT = 0; //P2 is output low P2DIR = BIT6 + BIT7; //P2 is output P2SEL = 0; //P2 is digital i/0 P2REN = 0; //P2 disable pullup resistors */ int i = 1; for(;{ //Digital Input while (P2IN & BIT7); //wait for P1.7 to go low (buttion is pressed) Display(i); //display while (!(P2IN & BIT7)); //wait for P1.7 to go high (button is released) i = i + 1; //increase counter if (i > 12) i = 0; //maximum display is 12 } } EDIT: I tried replacing display(i) with just TurnON(1,0), and the light turned on instantly and ever turned off, even when i applied VCC to pin 2.7... Quote Link to post Share on other sites
GeekDoc 226 Posted November 21, 2010 Share Posted November 21, 2010 Your display function seems to have a "turnon" immediately followed by a "turnoff", with no delay. I'd bet your code's working fine, but it's too fast for you to see. I see a delay function defined, but never implemented. Quote Link to post Share on other sites
mnpumar 2 Posted November 21, 2010 Author Share Posted November 21, 2010 Just tried this: int main( void ){ // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; P2OUT = 0; //P2 is output low P2DIR = BIT7; //P2 is output P2SEL = 0; //P2 is digital i/0 P2REN = 0; //P2 disable pullup resistors */ int i = 1; for(;{ //Digital Input while (P2IN & BIT7); //wait for P1.7 to go low (buttion is pressed) TurnON(1,0); //display while (!(P2IN & BIT7)); //wait for P1.7 to go high (button is released) i = i + 1; //increase counter if (i > 12) i = 0; //maximum display is 12 delay(10000); TurnOFF(1,0); } } The LED stays on and never turns off from the beginning :? Quote Link to post Share on other sites
bluehash 1,581 Posted November 21, 2010 Share Posted November 21, 2010 Is there any reason why you did not them up as interrupts? I think it should be easier that way, rather than poll P2.7 Quote Link to post Share on other sites
mnpumar 2 Posted November 21, 2010 Author Share Posted November 21, 2010 Is there any reason why you did not them up as interrupts? I think it should be easier that way, rather than poll P2.7 I am not familiar with interrupts i thought i'd be more comfortable working with inputs Quote Link to post Share on other sites
GeekDoc 226 Posted November 21, 2010 Share Posted November 21, 2010 Do you have an external pull-up resistor on P2.7? If not, you're probably detecting the drop to low, but when the button is released, the input just floats and never goes high (about 2.3v+). Quote Link to post Share on other sites
simpleavr 399 Posted November 21, 2010 Share Posted November 21, 2010 it looks like your P2.7 is setup as output, but u intend to use it as an input to read button. P2DIR = BIT7; //P2 is output u should just leave it as P2DIR = 0; also, how did u wire your button, is it a tie between P2.7 and Vcc or P2.7 and Gnd? either way, u may consider using pull-up to be more stable. also if u can have a choice, u should avoid P2.7 as it is also XOUT (crystal) from the g2x21 manual, page 6, footnote 3 If XOUT/P2.7 is used as an input, excess current will flow until P2SEL.7 is cleared. This is due to the oscillator output driver connection to this pad after reset Quote Link to post Share on other sites
mnpumar 2 Posted November 21, 2010 Author Share Posted November 21, 2010 I don't really have a button, I was just connecting the pin to ground/vcc with a wire. I got it to work by doing the following: int main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; P2OUT = 0; //P2 is output low P2DIR = BIT7; //P2 is output P2SEL = 0; //P2 is digital i/0 P2REN = 0; //P2 disable pullup resistors */ P2DIR &= ~BIT7; int i = 1; for(;{ //Digital Input while (!(P2IN & BIT7)){ Display(i); } //wait for P1.7 to go high (button is released) i = i + 1; //increase counter if (i > 12) i = 0; //maximum display is 12 while (P2IN & BIT7); //wait for P1.7 to go low (buttion is pressed) //delay(10000); } } Problem now is that it's a pretty unreliable switch. Whenever i trigger it, the number goes up a random number of times. I thought the while (P2IN & BIT7); //wait for P1.7 to go low (buttion is pressed) is supposed to prevent this from happening? Quote Link to post Share on other sites
bluehash 1,581 Posted November 21, 2010 Share Posted November 21, 2010 You probably need to debounce it. When you connect a wire like that, the pin does not see a clean signal, but goes high and low a few times before it settles. A simple way to do it is to see if the state remains the same, say for 10 iterations - only then Display(i) Quote Link to post Share on other sites
simpleavr 399 Posted November 21, 2010 Share Posted November 21, 2010 see the second diagram in the following link http://www.rentron.com/Myke6.htm also, u should set P2DIR = 0 instead of P2DIR = BIT7, your P2IN can still get reading but it may not be reliable, if your P2OUT has also set BIT7 on (which u did not), u may even blow up a pin when u use a wire to poke around. from slau144e.pdf 8.2.3 Direction Registers PxDIR Each bit in each PxDIR register selects the direction of the corresponding I/O pin, regardless of the selected function for the pin. PxDIR bits for I/O pins that are selected for other functions must be set as required by the other function. Bit = 0: The port pin is switched to input direction Bit = 1: The port pin is switched to output direction to do non-interrupt button de-bounce, i would . setup P2.7 as input, w/ pull-up enable P2DIR = 0; P2REN = BIT7; P2OUT = BIT7; . tie the button between P2.7 and Gnd (i.e. low activate) . use a counter for de-bouncing. this setup will be input normally high and button press does a low trigger. u will want to capture the transition of low to high (button release) for your activities. while (1) { // u thing here, may be display display(i); unsigned wait=0; while (!(P2IN & BIT7) wait++; // P2.7 is low, we have a key-press, wait it out // we will only consider it as a trigger if it takes wait to reach at least 20 counts // this will avoid / skip those button jitters, if no good, try a higher value if (wait > 20) { // or try some other value i++; if (i>=12) i=0; } } i haven't tried the code, just look right to me. if u tried it and still have problems, i will try something for u. mnpumar 1 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.