Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of 2645_FSM_UpDown_Counter by
main.cpp@0:c5278b91719f, 2016-01-07 (annotated)
- Committer:
- eencae
- Date:
- Thu Jan 07 10:00:24 2016 +0000
- Revision:
- 0:c5278b91719f
- Child:
- 1:d5ac6f4a196d
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
eencae | 0:c5278b91719f | 1 | /* |
eencae | 0:c5278b91719f | 2 | |
eencae | 0:c5278b91719f | 3 | 2645_FSM_UpDown_Counter |
eencae | 0:c5278b91719f | 4 | |
eencae | 0:c5278b91719f | 5 | Sample code from ELEC2645 Week 16 Lab |
eencae | 0:c5278b91719f | 6 | |
eencae | 0:c5278b91719f | 7 | Demonstrates how to implement a simple FSM up/down counter |
eencae | 0:c5278b91719f | 8 | |
eencae | 0:c5278b91719f | 9 | (c) Craig A. Evans, University of Leeds, Jan 2016 |
eencae | 0:c5278b91719f | 10 | |
eencae | 0:c5278b91719f | 11 | */ |
eencae | 0:c5278b91719f | 12 | |
eencae | 0:c5278b91719f | 13 | #include "mbed.h" |
eencae | 0:c5278b91719f | 14 | |
eencae | 0:c5278b91719f | 15 | // pre-processor directives |
eencae | 0:c5278b91719f | 16 | |
eencae | 0:c5278b91719f | 17 | // defines directions as 0/1. Note UPPERCASE |
eencae | 0:c5278b91719f | 18 | #define UP 0 |
eencae | 0:c5278b91719f | 19 | #define DOWN 1 |
eencae | 0:c5278b91719f | 20 | |
eencae | 0:c5278b91719f | 21 | // K64F on-board LEDs |
eencae | 0:c5278b91719f | 22 | DigitalOut r_led(LED_RED); |
eencae | 0:c5278b91719f | 23 | DigitalOut g_led(LED_GREEN); |
eencae | 0:c5278b91719f | 24 | DigitalOut b_led(LED_BLUE); |
eencae | 0:c5278b91719f | 25 | // K64F on-board switches |
eencae | 0:c5278b91719f | 26 | InterruptIn sw2(SW2); |
eencae | 0:c5278b91719f | 27 | InterruptIn sw3(SW3); |
eencae | 0:c5278b91719f | 28 | |
eencae | 0:c5278b91719f | 29 | // LEDs to display counter output |
eencae | 0:c5278b91719f | 30 | // connect up external LEDs to these pins with appropriate current-limiting resistor |
eencae | 0:c5278b91719f | 31 | BusOut output(PTB2,PTB3,PTB10,PTB11); |
eencae | 0:c5278b91719f | 32 | |
eencae | 0:c5278b91719f | 33 | // array of states in the FSM, each element is the output of the counter |
eencae | 0:c5278b91719f | 34 | int fsm[4] = {1,2,4,8}; |
eencae | 0:c5278b91719f | 35 | |
eencae | 0:c5278b91719f | 36 | // flag - must be volatile as changes within ISR |
eencae | 0:c5278b91719f | 37 | // g_ prefix makes it easier to distinguish it as global |
eencae | 0:c5278b91719f | 38 | volatile int g_sw2_flag = 0; |
eencae | 0:c5278b91719f | 39 | |
eencae | 0:c5278b91719f | 40 | // function prototypes |
eencae | 0:c5278b91719f | 41 | // error function hangs flashing an LED |
eencae | 0:c5278b91719f | 42 | void error(); |
eencae | 0:c5278b91719f | 43 | // set-up the on-board LEDs and switches |
eencae | 0:c5278b91719f | 44 | void init_K64F(); |
eencae | 0:c5278b91719f | 45 | // SW2 interrupt service routine |
eencae | 0:c5278b91719f | 46 | void sw2_isr(); |
eencae | 0:c5278b91719f | 47 | |
eencae | 0:c5278b91719f | 48 | int main() |
eencae | 0:c5278b91719f | 49 | { |
eencae | 0:c5278b91719f | 50 | // initialise on-board LED and switches |
eencae | 0:c5278b91719f | 51 | init_K64F(); |
eencae | 0:c5278b91719f | 52 | |
eencae | 0:c5278b91719f | 53 | // SW2 has a pull-up resistor, so the pin will be at 3.3 V by default |
eencae | 0:c5278b91719f | 54 | // and fall to 0 V when pressed. We therefore need to look for a falling edge |
eencae | 0:c5278b91719f | 55 | // on the pin to fire the interrupt |
eencae | 0:c5278b91719f | 56 | sw2.fall(&sw2_isr); |
eencae | 0:c5278b91719f | 57 | |
eencae | 0:c5278b91719f | 58 | // set inital state |
eencae | 0:c5278b91719f | 59 | int state = 0; |
eencae | 0:c5278b91719f | 60 | // set initial direction |
eencae | 0:c5278b91719f | 61 | int direction = UP; |
eencae | 0:c5278b91719f | 62 | |
eencae | 0:c5278b91719f | 63 | while(1) { // loop forever |
eencae | 0:c5278b91719f | 64 | |
eencae | 0:c5278b91719f | 65 | // check if flag i.e. interrupt has occured |
eencae | 0:c5278b91719f | 66 | if (g_sw2_flag) { |
eencae | 0:c5278b91719f | 67 | g_sw2_flag = 0; // if it has, clear the flag |
eencae | 0:c5278b91719f | 68 | |
eencae | 0:c5278b91719f | 69 | // swap direction when button has been pressed |
eencae | 0:c5278b91719f | 70 | // (could just use ! but want this to be explicit to aid understanding) |
eencae | 0:c5278b91719f | 71 | if (direction == UP) { |
eencae | 0:c5278b91719f | 72 | direction = DOWN; |
eencae | 0:c5278b91719f | 73 | } |
eencae | 0:c5278b91719f | 74 | else { |
eencae | 0:c5278b91719f | 75 | direction = UP; |
eencae | 0:c5278b91719f | 76 | } |
eencae | 0:c5278b91719f | 77 | } |
eencae | 0:c5278b91719f | 78 | |
eencae | 0:c5278b91719f | 79 | output = fsm[state]; // output current state |
eencae | 0:c5278b91719f | 80 | |
eencae | 0:c5278b91719f | 81 | // check which state we are in and see which the next state should be next depending on direction |
eencae | 0:c5278b91719f | 82 | switch(state) { |
eencae | 0:c5278b91719f | 83 | case 0: |
eencae | 0:c5278b91719f | 84 | switch(direction) { |
eencae | 0:c5278b91719f | 85 | case UP: |
eencae | 0:c5278b91719f | 86 | state = 1; |
eencae | 0:c5278b91719f | 87 | break; |
eencae | 0:c5278b91719f | 88 | case DOWN: |
eencae | 0:c5278b91719f | 89 | state = 3; |
eencae | 0:c5278b91719f | 90 | break; |
eencae | 0:c5278b91719f | 91 | } |
eencae | 0:c5278b91719f | 92 | break; |
eencae | 0:c5278b91719f | 93 | case 1: |
eencae | 0:c5278b91719f | 94 | switch(direction) { |
eencae | 0:c5278b91719f | 95 | case UP: |
eencae | 0:c5278b91719f | 96 | state = 2; |
eencae | 0:c5278b91719f | 97 | break; |
eencae | 0:c5278b91719f | 98 | case DOWN: |
eencae | 0:c5278b91719f | 99 | state = 0; |
eencae | 0:c5278b91719f | 100 | break; |
eencae | 0:c5278b91719f | 101 | } |
eencae | 0:c5278b91719f | 102 | break; |
eencae | 0:c5278b91719f | 103 | case 2: |
eencae | 0:c5278b91719f | 104 | switch(direction) { |
eencae | 0:c5278b91719f | 105 | case UP: |
eencae | 0:c5278b91719f | 106 | state = 3; |
eencae | 0:c5278b91719f | 107 | break; |
eencae | 0:c5278b91719f | 108 | case DOWN: |
eencae | 0:c5278b91719f | 109 | state = 1; |
eencae | 0:c5278b91719f | 110 | break; |
eencae | 0:c5278b91719f | 111 | } |
eencae | 0:c5278b91719f | 112 | break; |
eencae | 0:c5278b91719f | 113 | case 3: |
eencae | 0:c5278b91719f | 114 | switch(direction) { |
eencae | 0:c5278b91719f | 115 | case UP: |
eencae | 0:c5278b91719f | 116 | state = 0; |
eencae | 0:c5278b91719f | 117 | break; |
eencae | 0:c5278b91719f | 118 | case DOWN: |
eencae | 0:c5278b91719f | 119 | state = 2; |
eencae | 0:c5278b91719f | 120 | break; |
eencae | 0:c5278b91719f | 121 | } |
eencae | 0:c5278b91719f | 122 | break; |
eencae | 0:c5278b91719f | 123 | default: // default case |
eencae | 0:c5278b91719f | 124 | error(); //invalid state - call error routine |
eencae | 0:c5278b91719f | 125 | // or could jump to starting state i.e. state = 0 |
eencae | 0:c5278b91719f | 126 | break; |
eencae | 0:c5278b91719f | 127 | } |
eencae | 0:c5278b91719f | 128 | |
eencae | 0:c5278b91719f | 129 | wait(0.2); // small delay |
eencae | 0:c5278b91719f | 130 | |
eencae | 0:c5278b91719f | 131 | |
eencae | 0:c5278b91719f | 132 | } |
eencae | 0:c5278b91719f | 133 | } |
eencae | 0:c5278b91719f | 134 | |
eencae | 0:c5278b91719f | 135 | void init_K64F() |
eencae | 0:c5278b91719f | 136 | { |
eencae | 0:c5278b91719f | 137 | // on-board LEDs are active-low, so set pin high to turn them off. |
eencae | 0:c5278b91719f | 138 | r_led = 1; |
eencae | 0:c5278b91719f | 139 | g_led = 1; |
eencae | 0:c5278b91719f | 140 | b_led = 1; |
eencae | 0:c5278b91719f | 141 | |
eencae | 0:c5278b91719f | 142 | // since the on-board switches have external pull-ups, we should disable the internal pull-down |
eencae | 0:c5278b91719f | 143 | // resistors that are enabled by default using InterruptIn |
eencae | 0:c5278b91719f | 144 | sw2.mode(PullNone); |
eencae | 0:c5278b91719f | 145 | sw3.mode(PullNone); |
eencae | 0:c5278b91719f | 146 | |
eencae | 0:c5278b91719f | 147 | } |
eencae | 0:c5278b91719f | 148 | |
eencae | 0:c5278b91719f | 149 | void error() |
eencae | 0:c5278b91719f | 150 | { |
eencae | 0:c5278b91719f | 151 | while(1) { // if error, hang while flashing error message |
eencae | 0:c5278b91719f | 152 | r_led = 0; |
eencae | 0:c5278b91719f | 153 | wait(0.2); |
eencae | 0:c5278b91719f | 154 | r_led = 1; |
eencae | 0:c5278b91719f | 155 | wait(0.2); |
eencae | 0:c5278b91719f | 156 | } |
eencae | 0:c5278b91719f | 157 | } |
eencae | 0:c5278b91719f | 158 | |
eencae | 0:c5278b91719f | 159 | // SW2 event-triggered interrupt |
eencae | 0:c5278b91719f | 160 | void sw2_isr() |
eencae | 0:c5278b91719f | 161 | { |
eencae | 0:c5278b91719f | 162 | g_sw2_flag = 1; // set flag in ISR |
eencae | 0:c5278b91719f | 163 | } |