E15 Laboratory 2

Introduction to Microcontrollers and C State Machines

Please contact me if you find any errors or other problems (e.g., something is unclearly stated) in this web page

Useful references for E15 labs

In this lab you will be performing many of the same tasks that you did in the last lab.  The goal is to teach you new methods, but also to give you an appreciation of various solutions to the same problem.

Task 0: Code Composer tutorial

Go through the tutorial describing the writing and debugging of a C program in Code Composer Studio.

C State Machines

A Method for Programming Real World Interfaces

This may seem familiar:  You have seven LED's (light emitting diodes) as shown below:

The LED's are connected to an MSP430G2553 as shown in the table below:

LED 1 (Red):    A
MSP430:    P1.7
  LED 7 (Red):    E
MSP430:    P2.3
LED 2 (Yellow):B
MSP430:    P1.6
LED 5 (Yellow):D
MSP430:    P2.1
LED 8 (Yellow):F
MSP430:    P2.4
LED 3 (Green):  C
MSP430:    P1.4
  LED 9 (Green):G
MSP430:    P2.5

We will simulate a die rolling by implementing a "state machine" with a C language program.

There are many ways to write any program.  In this lab we will use one formalism called a state machine.  The goal of the lab is to introduce you to the concept because it is a useful way to write many programs that involve real world interactions.  It is also a very useful technique for designing circuits (you'll do this in class and in lab later this semester).  This is not always the most appropriate choice (especially for relatively simple programs), but I want you to use it for this lab so you become familiar with it.

State Machine 1 (to be used in this lab): The die

Consider the image shown at the right.  It represents a "State Machine" with six states labeled S1 through S6.   In this diagram "PB" is an input that is true whenever the pushbutton on the E15 I/O board is pressed.  The state machine assumes our program is running continually in a loop.

For each time step:

This behavior for these state transitions is described in code below.

        // 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;
             case DIESTATE2: if (PB) myState = DIESTATE3;
             case DIESTATE3: if (PB) myState = DIESTATE4;
             case DIESTATE4: if (PB) myState = DIESTATE5;
             case DIESTATE5: if (PB) myState = DIESTATE6;
             case DIESTATE6: if (PB) myState = DIESTATE1;
             // The default state should never occur, but if it does, we go to state 1
             default:        myState=DIESTATE1;    // This should never happen!

 In this code:

At this point, we have only defined the state "transitions."  We also need to define the state outputs (or "behaviors" - what are the outputs of the program in each state).  This is done in the code below where LED_Die() is a function you must write that takes an integer as input.  If the input is not between 1 and 6, no LED's are lit; if it is one, the center LED is lit; if it is two, the corner LED's are lit (as in a die face)....  For each state, if the pushbutton is pressed, the die is blank.  If the pushbutton is released, it displays the current state:

        // 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);
             case DIESTATE2: if (PB) LED_Die(0);
                             else LED_Die(2);
             case DIESTATE3: if (PB) LED_Die(0);
                             else LED_Die(3);
             case DIESTATE4: if (PB) LED_Die(0);
                             else LED_Die(4);
             case DIESTATE5: if (PB) LED_Die(0);
                             else LED_Die(5);
             case DIESTATE6: if (PB) LED_Die(0);
                             else LED_Die(6);
             default:        LED_Die(0);  // This should never happen!

The code below (E15Lab2Die_2.c - right-click to download file) implements the state machine. 

 Download and run the code for the die, and verify that it works as expected.  Read it carefully and note:

Code guidelines:  Your code should be neat and well documented; it should be indented in a consistent and rational way.  There should be enough comments that another student in the class (who has not yet done the lab) could easily understand it.  In your printout, make sure that comments do not "wrap around" to the next line - this makes it very hard to read.  Either make your comments shorter (or on multiple lines), or print in "landscape" mode so wrap around is avoided.  If you have a diagram (e.g., a state diagram), you can include it in your lab report, and just refer to it in the comments (make sure it is clearly labeled in the report so the reference is obvious).

Task 1: A Stoplight.

The goal is to design a stoplight for which the signals should change according to the following table:

Input Values Light Setting
North-South East-West
0-5 Red Green
6-7 Red Yellow
8 Red Red
9-12 Green Red
13-14 Yellow Red
15 Red Red

Task 1a: Draw a state diagram with 16 states that implements the design above.  Note that this is fairly easy because there are no conditional state transitions.

Task 1b: Write a program that implements your state diagram and cycles through it at about 1 state per second (you'll have to experiment to get the proper delay - recall that there were delays in the code in the tutorial).  You only need one delay per loop (you can put it at the beginning).  Remember that integers have a maximum of 32767.

There should be two major distinct sections to your code: State Transitions and State Outputs.  This is not the only (and in some situations, not the best method), but I want you to stick to it for this lab.  Use the code guidelines given above.

Task 1c: At some intersections of a busy road and one that is not very busy, the light stays green on the busy road until a car shows up on the other road, at which time the light changes.  Let the East-West road be the busy road.  Draw a state diagram that stays in state 5 until the pushbutton is pressed, and then cycles until it returns to state 5.

Task 1d: Implement the state diagram from the previous subtask.  Connect to the traffic lights in Hicks 310 and demo to me (you only need the E15 I/O board, the power supply, and the small D-shaped board with the processor).  The traffic lights have a cable that connects to the 9-pin connector on the edge of the E15 I/O board.

The state diagrams for this task have been somewhat tedious to code for because there were 16 states.  If we wanted a longer cycle (more states), or different timing (different state transitions), this problem only gets worse.  Let's modify things a bit so that we only have 6 states as listed below:

Light Setting
North-South East-West
SRG Red Green
SRY Red Yellow
SRR0 Red Red
SGR Green Red
SYR Yellow Red
SRR1 Red Red

Now we will add a counter to the code that increments at every cycle.  As you transition from one state to the next, the counter is reset to 0; so as we enter a new state the counter is always equal to 0. 

So for example, we might stay in state SGR for four increments of the counter, at which time we transition to state SYR, and reset the counter to 0.  We can stay in state SYR until we get two increments of the counter, then we transition to state SRR1, etc...

A code shell is given in the file E15Lab2Traffic.c, and is shown below:

Task 1e:  Draw a state diagram that implements the "busy road" scenario (subtasks c and d).  Assume "count" is an input to each state, as well as the pushbutton.  Implement the same timing as before.  The variable "count" is also an output that should be reset to 0 as needed at state transitions.

Task 1f:  Implement it and demo to me.

Task 2 (Advanced & optional): A Dual Boot System.

Write code such that if the pushbutton is pressed when you apply power to the circuit it will run the "die" code, otherwise it runs the traffic light code.  Demo to me.

Task 3 (Advanced & optional): A Game.

Consider the following game:

I haven't thought this through completely, so if something is ambiguous (or impossible), adjust the rules slightly (but document your changes/decisions). 

You might also (but needn't) consider

Task 3a: Draw the state diagram.

Task 3b: Implement.

To Turn in:

The grading of each subtask is as follows.  It should be a single PDF uploaded to moodle with each task and subtask clearly labeled.

This is a minimal list, feel free to augment with material you think is necessary (but I'm not looking for anything beyond what I ask for).

Please contact me if you find any errors or other problems (e.g., something is unclearly stated) in this web page