2
$\begingroup$

I'm dealing a C code here which is run on MSP430 LaunchPad. What I need to do here is modifying the program, so that at the push of the button, the micro cycles through 4 different modes:

  1. LED1 flashes while LED2 off
  2. LED2 flashes while LED1 off
  3. LED1 and LED2 flash simultaneously
  4. LED1 and LED2 flash alternatively

I quite don't understand here what I can do to make both LED flash simultaneously and alternatively. LED1 flashes and LED2 off if SW2 is HIGH and vice versa. How do the other two work?

Down here is what has been done so far:

#include <msp430.h> 
#include "msp430g2553.h"
int sw2=0;

int main(void) 
{
    WDTCTL = WDTPW | WDTHOLD;      //stop watchdog timer

    P1DIR  = 0x00;         //port 1 all inputs
    P1DIR |= (BIT0 | BIT6);        //set P1.0 and P1.6 as outputs (LED1, LED2)
    P1REN |= BIT3;         //activate resister on P1.3
    P1OUT |= BIT3;         //make it pull up because SW2 is active low

    for(;;)
    { sw2 = P1IN;          //read values from P1
      sw2 &= BIT3;         //mask out only BIT3 where SW2 is connected
      if (sw2 == BIT3)               
         {             //if SW2 is high
            P1OUT &= ~BIT6;    //turn LED2 off 
            P1OUT ^= BIT0;     //toggle LED1
          __    delay_cycles(50000);   //delay 50,000 micro seconds
         }
      else             
         {             //else (SW2 is low) 
            P1OUT &= ~BIT0;    //turn LED1 off
            P1OUT ^= BIT6;     //toggle LED2
            __delay_cycles(200000);   //delay 200,000 micro seconds
         }
     }
// end of infinite loop
}
//end of main
$\endgroup$
1
1
$\begingroup$

I can only see that you've programmed the switch to "if high - do one thing, if low - do something else". You need to include a counter for the switch (and debounce). then 4 if statements, one for every mode you're cycling through.

Pseudo-ish code:

int sw2 = 0;
int counter = 0;
flipbit = 0;

Int main(void) {

   (whatever ports/bits you need to set up here)

   If (sw2 == 1) {                    //if the switch is depressed..
      delay_cycles(200,000);          //Wait 200ms (lazy debounce) as long as you click a button quicker than 200ms no worries
      counter == counter + 1;         //increment the counter
   }
   if (counter == 1) {
      P1OUT ^= BIT0;                  //turn led1 on
      __delay_cycles(200000);         //wait 200ms
      P1OUT ^= BIT0;                  //turn led1 off
      __delay_cycles(200000);         //wait 200ms
   }
   if (counter == 2) {
      P1OUT ^= BIT6;                  //turn led2 on
      __delay_cycles(200000);         //wait 200ms
      P1OUT ^= BIT6;                  //turn led2 off
      __delay_cycles(200000);         //wait 200ms
   }
   if (counter == 3) {
      P1OUT &= ~BIT0;                 //turn led 1 on
      P1OUT ^= BIT6;                  //turn led 2 on
      delay_cycles(200,000);          //wait 200ms
      P1OUT &= ~BIT0;                 //turn led 1 off
      P1OUT ^= BIT6;                  //turn led 2 off
      delay_cycles(200,000);          //wait 200ms
   }
   if (counter == 4) {                //now it gets exciting...
      if (flipbit == 0) {             //this statement lets us run a statement once per loop
         P1OUT &= ~BIT0;              //turn led1 on
         flipbit == flipbit + 1       //make flipbit = 1 so it doesn't run again this cycle
         }
      P1OUT &= ~BIT0;                 //turn led 1 off
      P1OUT ^= BIT6;                  //turn led 2 on
      delay_cycles(200,000);          //wait 200ms
      P1OUT &= ~BIT0;                 //turn led 1 on
      P1OUT ^= BIT6;                  //turn led 2 off
      delay_cycles(200,000);          //wait 200ms
   }
   if (counter == 5) {                //you clicked the button again, to return to the first mode
      P1OUT &= ~BIT0;                 //turn led1 back off, ready to start the cycle again
      flipbit = 0;
      counter = 1;                     //set counter to 1, so it starts on first mode
   }

As you're 'toggling' bits rather than definitively setting them as 1 or 0, i've made sure to keep track of what state they're in by making them do a complete cycle within each statement, i.e turning them on and BACK off before it can move on.

This 'flipbit' is there to offset the pattern by turning led1 on first so we can use the same pattern as mode 3, and the fifth step of the counter is to turn that led back off and to reset that flipbit to 0.

There's a few ways of implementing this. This one was the easiest i could think that was 'readable'.

EDIT:

Just looked it up and the '__delay_cycles' is actually similar to arduino whereas it will halt code execution. This is not great as your button presses will go unnoticed for a large part of the program. There's 2 ways to go about it, either use an interrupt for the switch or use a timer instead of delay. This link shows you how.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.