Craig Evans
/
2645_FSM_UpDown_Counter
Sample code from ELEC2645 Week 16 Lab Demonstrates how to implement a simple FSM up/down counter
Diff: main.cpp
- 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