Jump to content
43oh

Change led with button


Recommended Posts

I am currently working on a project and i can not figure it out, and i have noticed there is very little around the web. i am using a msp430g2211. what i want to do is have 6 leds connected to the board. on pins 0, 1, 4, 5, 6, and 7. and a button on pin 2. when the board turns on i want it to turn on 2 leds on pins 0 and 1 and when you press the button i want it to switch to 4 and 5 and so on. any help would help alot.

Link to post
Share on other sites

Try this:

 

First, define your pins as globals.

#define LED0     BIT0
#define LED1   BIT1
.
.
.
#define BUTTON BIT2 

 

In binary, BIT0 = 00000001, BIT1 = 00000010, and so on.

 

In your main method, start by turning the watchdog timer off.

WDTCTL = WDTPW | WDTHOLD;

 

Then, set the direction for all your ports. You want pins 0,1,4,5,6, and 7 to all be output, while pin 2 to be input.

The register P1DIR controls whether a pin is set to input or output for all the P1.X pins. If a bit is set to 1, it is output, while if it is set to 0, it is input.

 

Therefore, you want P1DIR to be 11110011. Alternatively, an easier way to do this might be to OR all the pins you want output (LED0|LED1...etc).

 

Set the P1OUT register, which determines which pins are being turned on to something like PIN0|PIN1 so that the first two LEDs are on.

 

After that, start an infinite for loop in which your main LED blinking sequence runs. Within the for loop, have a while that waits for the button to be pressed. The P1IN register contains all of the inputs. Therefore if you AND P1IN and BUTTON, you will have a logical answer to whether the button is being pressed.

while((P1IN & BUTTON) != 0) {}

 

After the while loop, you can put in the code for your LED switch. The easiest way to do this would be an XOR.

P1OUT ^= LED1|LED0|LED4|LED5; 

 

You can then continue putting in while loops for more switches.

 

Sorry if I didn't explain that too well- here's the solution:

 

#define     LED0                  BIT0
#define     LED1                  BIT1
#define     LED4                  BIT4
#define     LED5                  BIT5
#define     LED6                  BIT6
#define     LED7                  BIT7
#define	BUTTON		 BIT2

void main (void)
{
WDTCTL = WDTPW | WDTHOLD;
P1DIR = LED0 | LED1 | LED4| LED5 | LED6 | LED7; //Sets all the LEDs to output
P1OUT = LED0 | LED1; //Turns LED0 and LED1 on.
for(; //Infinite loop
{ 
	while((P1IN & B1) == 0) {} //Waste time while the button ISN'T pressed
	P1OUT ^= LED1|LED0|LED4|LED5; //"Flip" the outputs of LED0, LED1, LED4, and LED5
               while((P1IN & B1) == 0) {}
	P1OUT ^= LED4|LED5|LED6|LED7;
               while((P1IN & B1) == 0) {}
               P1OUT ^= LED6|LED7|LED0|LED1;
}
}

 

Let me know if you have any questions or my code is horribly broken. ;)

I highly recommend looking at the user manual for the value line series- it has all the info you need.

Link to post
Share on other sites
thanks for the help. the code does work but not in the way i would like. i would like the led to stay on the next "setting". the way it is now when you press the button they change but when you let go they go back.

 

Also B1 in the code was not defined but i changed B1 to Button. is this right.

 

Whoops!

What the code needs is an extra while loop to wait when the button is let go again.

 

Try this:

 

#define     LED0                  BIT0
#define     LED1                  BIT1
#define     LED4                  BIT4
#define     LED5                  BIT5
#define     LED6                  BIT6
#define     LED7                  BIT7
#define   BUTTON       BIT2

void main (void)
{
  WDTCTL = WDTPW | WDTHOLD;
  P1DIR = LED0 | LED1 | LED4| LED5 | LED6 | LED7; //Sets all the LEDs to output
  P1OUT = LED0 | LED1; //Turns LED0 and LED1 on.
  for(; //Infinite loop
  { 
     while((P1IN & BUTTON) == 0) {} //Waste time while the button ISN'T pressed
     P1OUT ^= LED1|LED0|LED4|LED5; //"Flip" the outputs of LED0, LED1, LED4, and LED5
     while((P1IN & BUTTON) != 0) {}

     while((P1IN & BUTTON) == 0) {}
     P1OUT ^= LED4|LED5|LED6|LED7;
     while((P1IN & BUTTON) != 0) {}

     while((P1IN & BUTTON) == 0) {}
     P1OUT ^= LED6|LED7|LED0|LED1;
     while((P1IN & BUTTON) != 0) {}
  }
}

Link to post
Share on other sites

what i am making is basiclly a color changer. so when it turns on its red. press the button its blue. press it again it is green. and what i would like to do is have it so when you press it one more time it cycles thru the colors till you press the button again witch will bring it back to red. and i really appreciate all the help so far.

Link to post
Share on other sites
what i am making is basiclly a color changer. so when it turns on its red. press the button its blue. press it again it is green. and what i would like to do is have it so when you press it one more time it cycles thru the colors till you press the button again witch will bring it back to red. and i really appreciate all the help so far.

All it's missing is the code that brings it back to LED0 and LED1 at the end of the for loop. You should be able to copy/paste it in.

Link to post
Share on other sites
you miss understood. what i ment is you can manually go thro the colors (eg. red, blue, green,) then after thos you press it one more time and it will auto sequence the colors until you press it again and it goes back to red.

Oh, ok. You would need to put in another while loop that constantly changes the colors until button press. Each change in color should have a delay before the next. You can either have a while loop keep counting for some arbitrary number or set up one of the internal MSP430 timers.

Link to post
Share on other sites

Hi shadow,

 

Forgive me if I'm wrong, but it looks to me that you are trying to make this: 7-Color Blinking LED

 

This device is an RGB LED, with an IC built-in to control the LEDs. It has an input pin, Vcc, and GND.

When you first apply power, it does a little light show, flashing the LEDs in sequence for several seconds, then turns them off.

Give it a negative pulse on the input, it changes to red. Do it again, off.

Again, green. Off.

Blue. Off.

Red and green. Off.

Green and blue. Off.

Blue and red. Off.

All on. Off.

Red fades in, then green, then blue, red fades out, then green, then blue, repeating. Off.

Red again, the cycle starts over.

Link to post
Share on other sites

You would want to do something like this:

#include "msp430g2231.h"

#define RED BIT0
#define GRN BIT1
#define BLU BIT2
#define BTN BIT3

void startup(int ms1, int ms2, int ms3);

void delay_ms(unsigned ms) { do __delay_cycles(100000); while(--ms); }

bool btnFlag;
int timing =0;
void main( void )
{
 // Stop watchdog timer to prevent time out reset
 WDTCTL = WDTPW + WDTHOLD;

 { // IO PIN SETUP
 P1OUT |= RED+GRN+BLU; // SET OUTPUTS HIGH
 P1DIR |= RED+GRN+BLU; // SET AS OUTPUTS

 P1REN |= BTN; // TURN ON INTERNAL PULL-UP RESISTOR
 P1OUT |= BTN;; // SET OUTPUT HIGH
 P1DIR &= ~BTN; // SET PIN AS INPUT
 }

 startup(1,1,1);
 while(1){
   for(;{
     (P1IN & BTN) ? (btnFlag = true) : (btnFlag = false);
     if(!btnFlag){
timing++;
break;
     }
   }
   if(timing == 16){
     timing = 0;
   }
   switch(timing){
   case 0: P1OUT &= ~RED;
   case 2: P1OUT &= ~GRN;
   case 4: P1OUT &= ~BLU;

   case 6: P1OUT &= ~RED+GRN;
   case 8: P1OUT &= ~GRN+BLU;
   case 10: P1OUT &= ~BLU+RED;

   case 12: P1OUT &= ~RED;
   case 14: {
     for(int i=0; i < 3; i++){
P1OUT ^= RED;
delay_ms(3);
       P1OUT ^= GRN;
       delay_ms(3);
       P1OUT ^= BLU;
       delay_ms(3);
       P1OUT ^= RED;
       delay_ms(3);
       P1OUT ^= GRN;
       delay_ms(3);
       P1OUT ^= BLU;
       delay_ms(3);
     }
   }
   default: P1OUT |= RED|GRN|BLU;
  }
  __delay_cycles(1000000);

 }
}

void startup(int ms1, int ms2, int ms3){
 int i=0;
 for(i=0; i < 3; i++){
   P1OUT ^= RED;
   delay_ms(ms1);
   P1OUT ^= GRN;
   delay_ms(ms1);
   P1OUT ^= BLU;
   delay_ms(ms1);
   P1OUT ^= RED;
   delay_ms(ms1);
   P1OUT ^= GRN;
   delay_ms(ms1);
   P1OUT ^= BLU;
   delay_ms(ms1);
 }
 for(i=0; i < 3; i++){
   P1OUT ^= RED+GRN;
   delay_ms(ms2);
   P1OUT ^= RED+GRN;
   delay_ms(ms2);
   P1OUT ^= BLU+GRN;
   delay_ms(ms2);
   P1OUT ^= BLU+GRN;
   delay_ms(ms2);
   P1OUT ^= RED+BLU;
   delay_ms(ms2);
   P1OUT ^= RED+BLU;
   delay_ms(ms2);
 }
 for(i=0; i < 3; i++){
   P1OUT ^= RED;
   delay_ms(ms3);
   P1OUT ^= RED;
   delay_ms(ms3);
   P1OUT ^= GRN;
   delay_ms(ms3);
   P1OUT ^= GRN;
   delay_ms(ms3);
   P1OUT ^= BLU;
   delay_ms(ms3);
   P1OUT ^= BLU;
   delay_ms(ms3);
 }
}

 

This program does not do any fading; everything is just "on" or "off". For the parts that need to fade, you would need to use PWM (Pulse-Width-Modulation). This program is also built for a common-anode RGB led. It was built using IAR Kickstart.

 

Edit: Code modified as per oPossum's suggestion.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...