MSP430 - Semaphore - język C


3

Mam tu do czynienia z kodem C, który jest uruchamiany na MSP430 LaunchPad. Muszę tutaj zmodyfikować program, aby za jednym naciśnięciem przycisku mikrokolej przechodził przez 4 różne tryby:

  1. Dioda LED1 miga, gdy dioda LED2 jest wyłączona
  2. Dioda LED2 miga, gdy dioda LED1 jest wyłączona
  3. Migają jednocześnie diody LED1 i LED2
  4. Migają naprzemiennie diody LED1 i LED2

Nie rozumiem tutaj, co mogę zrobić, aby obie diody LED migały jednocześnie i alternatywnie. Dioda LED1 miga, a dioda LED2 jest wyłączona, jeśli SW2 jest WYSOKA i odwrotnie. Jak działają pozostałe dwie?

Oto, co do tej pory zostało zrobione:

#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

W tytule masz semafor. Nie widzę przywoływanego semafora w innym miejscu pytania. Spojrzeć na SYS / BIOS Szybki start dla MSP430
Mahendra Gunawardena

Odpowiedzi:


1

Widzę tylko, że zaprogramowałeś przełącznik na „jeśli jest wysoki - zrób jedną rzecz, jeśli jest niski - zrób coś innego”. Musisz włączyć licznik dla przełącznika (i odrzucić). następnie 4 instrukcje if, po jednym dla każdego trybu, w którym jedziesz.

Kod pseudo-ish:

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
   }

Ponieważ „przełączasz” bity, zamiast definitywnie ustawiać je na 1 lub 0, upewniłem się, że śledzę stan, w którym się znajdują, sprawiając, że wykonują pełny cykl w ramach każdej instrukcji, tj. Włączają i wracają wyłącz, zanim będzie mógł przejść dalej.

Ten „flipbit” ma zrównoważyć wzór, obracając najpierw diodę led1, abyśmy mogli użyć tego samego wzoru co tryb 3, a piąty krok licznika polega na wyłączeniu tej diody i zresetowaniu tego flipbita do 0.

Jest kilka sposobów wdrożenia tego. Ta była najłatwiejsza, jaką mogłem pomyśleć, była „czytelna”.

EDYTOWAĆ:

Po prostu sprawdziłem, a '__delay_cycles' jest właściwie podobny do arduino, podczas gdy zatrzyma wykonanie kodu. Nie jest to świetne, ponieważ naciśnięcia przycisków nie zostaną zauważone przez większą część programu. Istnieją dwa sposoby, aby to zrobić, albo użyć przerwania dla przełącznika, albo użyć zegara zamiast opóźnienia. Ten link pokazuje jak.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.