Sample code from ELEC2645 Week 16 Lab Demonstrates how to implement a simple FSM up/down counter

Dependencies:   mbed

Revision:
0:c5278b91719f
Child:
1:fb324de02b7f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Jan 07 10:00:24 2016 +0000
@@ -0,0 +1,163 @@
+/*
+
+2645_FSM_UpDown_Counter
+
+Sample code from ELEC2645 Week 16 Lab
+
+Demonstrates how to implement a simple FSM up/down counter
+
+(c) Craig A. Evans, University of Leeds, Jan 2016
+
+*/
+
+#include "mbed.h"
+
+// pre-processor directives
+
+// defines directions as 0/1. Note UPPERCASE
+#define UP 0
+#define DOWN 1
+
+// K64F on-board LEDs
+DigitalOut r_led(LED_RED);
+DigitalOut g_led(LED_GREEN);
+DigitalOut b_led(LED_BLUE);
+// K64F on-board switches
+InterruptIn sw2(SW2);
+InterruptIn sw3(SW3);
+
+// LEDs to display counter output
+// connect up external LEDs to these pins with appropriate current-limiting resistor
+BusOut output(PTB2,PTB3,PTB10,PTB11);
+
+// array of states in the FSM, each element is the output of the counter
+int fsm[4] = {1,2,4,8};
+
+// flag - must be volatile as changes within ISR
+// g_ prefix makes it easier to distinguish it as global
+volatile int g_sw2_flag = 0;
+
+// function prototypes
+// error function hangs flashing an LED
+void error();
+// set-up the on-board LEDs and switches
+void init_K64F();
+// SW2 interrupt service routine
+void sw2_isr();
+
+int main()
+{
+    // initialise on-board LED and switches
+    init_K64F();
+    
+    // SW2 has a pull-up resistor, so the pin will be at 3.3 V by default
+    // and fall to 0 V when pressed. We therefore need to look for a falling edge
+    // on the pin to fire the interrupt
+    sw2.fall(&sw2_isr);
+    
+    // set inital state
+    int state = 0;
+    // set initial direction
+    int direction = UP;
+
+    while(1) {  // loop forever
+    
+        // check if flag i.e. interrupt has occured
+        if (g_sw2_flag) {
+            g_sw2_flag = 0;  // if it has, clear the flag
+
+            // swap direction when button has been pressed
+            // (could just use ! but want this to be explicit to aid understanding)
+            if (direction == UP) {
+                direction = DOWN;    
+            }
+            else {
+                direction = UP;
+            }
+        }
+    
+        output = fsm[state];  // output current state
+
+        // check which state we are in and see which the next state should be next depending on direction
+        switch(state) {
+            case 0:
+                switch(direction) {
+                    case UP:
+                        state = 1;
+                        break;
+                    case DOWN:
+                        state = 3;
+                        break;
+                }
+                break;
+            case 1:
+                switch(direction) {
+                    case UP:
+                        state = 2;
+                        break;
+                    case DOWN:
+                        state = 0;
+                        break;
+                }
+                break;
+            case 2:
+                switch(direction) {
+                    case UP:
+                        state = 3;
+                        break;
+                    case DOWN:
+                        state = 1;
+                        break;
+                }
+                break;
+            case 3:
+                switch(direction) {
+                    case UP:
+                        state = 0;
+                        break;
+                    case DOWN:
+                        state = 2;
+                        break;
+                }
+                break;
+            default:  // default case
+                error();  //invalid state - call error routine
+                // or could jump to starting state i.e. state = 0
+                break;
+        }
+
+    wait(0.2); // small delay
+
+
+    }
+}
+
+void init_K64F()
+{
+    // on-board LEDs are active-low, so set pin high to turn them off.
+    r_led = 1;
+    g_led = 1;
+    b_led = 1;
+
+    // since the on-board switches have external pull-ups, we should disable the internal pull-down
+    // resistors that are enabled by default using InterruptIn
+    sw2.mode(PullNone);
+    sw3.mode(PullNone);
+
+}
+
+void error()
+{
+    while(1) {  // if error, hang while flashing error message
+        r_led = 0;
+        wait(0.2);
+        r_led = 1;
+        wait(0.2);
+    }
+}
+
+// SW2 event-triggered interrupt
+void sw2_isr()
+{
+    g_sw2_flag = 1;   // set flag in ISR
+}
\ No newline at end of file