//*************************************************************************************** // This code implements a state machine that "rolls" a die. The drawing of the state machine can be // seen at http://www.swarthmore.edu/NatSci/echeeve1/Class/e15/E15Lab2/E15Lab2.html#DieStates. // // The face of the die is implemented by seven LED's arranged as shown below. // o o // // o o o // // o o // In the code the LED's are referred to by their position (upper left, middle left...). // // There is also a pushbutton switch that is used to roll the die (the die rolls when the // button is pushed, and stops when the button is released. // While the die is rolling (button is pushed) it cycles rapidly through 6 states // representing the six possible outcomes of a roll of the die, but the LED's are all off. // When the button is released, the LED stops cycling through states, and instead lights the // LED's as appropriate for a die (for example the number 3 is represented by lighting the upper // left, center and lower right LED's // * o // // o * o // // o * // // Connection to the MSP430 are as shown below: // // MSP4302553 // +-----------------+ // | | // Pushbutton (active low)-->|P1.3 P1.7|-->LED, upper left // | P1.6|-->LED, middle left // | P1.4|-->LED, lower left // | P2.1|-->LED, center // | P2.3|-->LED, upper right // | P2.4|-->LED, middle right // | P2.5|-->LED, lower right // | | // // Written by Erik Cheever #include // Include standard MSP430 definitions // Define bits for LED connections #define LEDul BIT7 // The upper left LED is connected to bit 7, Port 1 #define LEDml BIT6 // The middle left LED is connected to bit 6, Port 1 #define LEDll BIT4 // The lower left LED is connected to bit 4, Port 1 #define LEDc BIT1 // The center LED is connected to bit 1, Port 2 #define LEDur BIT3 // The upper right LED is connected to bit 3, Port 2 #define LEDmr BIT4 // The middle right LED is connected to bit 4, Port 2 #define LEDlr BIT5 // The lower right LED is connected to bit 5, Port 2 // Define the bit for the pushbutton switch #define PushButton BIT3 // The pushbutton is connected to bit 3, Port 1 // Use a #define to give a true value when button is pushed. Recall that the bit // will be cleared if the button is pushed, and set when the button is released. #define PB (!(PushButton & P1IN)) // Returns true when (PushButton & P1IN) is false (button pushed). // Define states (DIESTATE1 is when the die value is 1....) #define DIESTATE1 1 // Note: the numeric values associated with the states #define DIESTATE2 12 // are abitrary, they just need to be unique. #define DIESTATE3 33 #define DIESTATE4 11 #define DIESTATE5 55 #define DIESTATE6 6 //Also... if you know C, a quicker way to do this is to create an enumerated type (enum) //******************************************************************* // This function, LED_Die(), takes an integer (val) as input. // If val is not in the range from 1 to 6, no LED's on the die face light. // If val=1, the center one lights. // If val=2, two diagonal corner LED's light. // If val=3, three diagonal LED's light. // If val=4, the four corner LED's light. // if val=5, the four corner and the center LED's light. // if val=6, the four corner and two side LED's light. void LED_Die(int val) { // Turn off all LED's. Note: If LED's are turned on later in the function the blink // will not be perceived because the time that the LED's are off will be so short. P1OUT &= ~(LEDul | LEDml | LEDll); // Turn off all LED's on Port 1 P2OUT &= ~(LEDc | LEDur | LEDmr | LEDlr); // Turn off all LED's on Port 2 // Use a switch statement to determine which LED's to light. switch (val) { case 1: P2OUT |= LEDc; break; // Turn on center LED (i.e., display a "one") case 2: P1OUT |= LEDul; // Turn on upper left and lower right P2OUT |= LEDlr; // (i.e., display a "two") break; case 3: P1OUT |= LEDul; // Turn on upper left P2OUT |= LEDc | LEDlr; // Turn on center and lower right break; case 4: P1OUT |= LEDul | LEDll; // Turn on upper left and lower left P2OUT |= LEDur | LEDlr; // Turn on upper right and lower right break; case 5: P1OUT |= LEDul | LEDll; // Turn on upper left and lower left P2OUT |= LEDc | LEDur | LEDlr; // Turn on center, upper right, lower right break; case 6: P1OUT |= LEDul | LEDll | LEDml; // Turn on LED's in left column P2OUT |= LEDur | LEDlr | LEDmr; // Turn on LED's in right column break; default: } } //********************************************************************* void main(void) { int myState; // This variable keeps track of current state of the state machine // Initialization WDTCTL = WDTPW + WDTHOLD; // Stop watchdog P1DIR |= LEDul | LEDml | LEDll; // Set P1 bits to output if connected to LED. P2DIR |= LEDc | LEDur | LEDmr | LEDlr ; // Set P2 bits to output if connected to LED. P1DIR &= ~PushButton; // Set P1 bit 3 to input (pushbutton on Launchpad) P1OUT |= PushButton; // We'll discuss this line (and the next) in class P1REN |= PushButton; myState = DIESTATE1; // Start in state1 while (1) { //Do this forever //************************************************************** // Code for state transitions. In each state we check the status of the button. // If it is down, we go to the next state. // If it is not down, we do nothing (i.e., stay in the current state). switch (myState) { case DIESTATE1: if (PB) myState = DIESTATE2; break; case DIESTATE2: if (PB) myState = DIESTATE3; break; case DIESTATE3: if (PB) myState = DIESTATE4; break; case DIESTATE4: if (PB) myState = DIESTATE5; break; case DIESTATE5: if (PB) myState = DIESTATE6; break; case DIESTATE6: if (PB) myState = DIESTATE1; break; // The default state should never occur, but if it does, we go to state 1 default: myState=DIESTATE1; // This should never happen! } //************************************************************** // Code for state outputs. In each state we check the button status. // If the button is down (die is rolling), we call LED_Die(0) which turns all the LED's off // If it is not down, we light up the appropriate LED's on the die face. switch (myState) { case DIESTATE1: if (PB) LED_Die(0); else LED_Die(1); break; case DIESTATE2: if (PB) LED_Die(0); else LED_Die(2); break; case DIESTATE3: if (PB) LED_Die(0); else LED_Die(3); break; case DIESTATE4: if (PB) LED_Die(0); else LED_Die(4); break; case DIESTATE5: if (PB) LED_Die(0); else LED_Die(5); break; case DIESTATE6: if (PB) LED_Die(0); else LED_Die(6); break; default: LED_Die(0); // This should never happen! } } }