Up Down counter using a transition table

Committer:
eencae
Date:
Thu Dec 10 14:22:22 2020 +0000
Revision:
1:1e34d5c96ecf
Parent:
0:7c0953072ecb
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eencae 0:7c0953072ecb 1 /*
eencae 0:7c0953072ecb 2
eencae 0:7c0953072ecb 3 2645_FSM_UpDown_Counter
eencae 0:7c0953072ecb 4
eencae 0:7c0953072ecb 5 Sample code from ELEC2645
eencae 0:7c0953072ecb 6
eencae 0:7c0953072ecb 7 Demonstrates how to implement a simple FSM up/down counter
eencae 0:7c0953072ecb 8
eencae 0:7c0953072ecb 9 (c) Craig A. Evans, University of Leeds, Jan 2016
eencae 0:7c0953072ecb 10 Updated Jan 2020
eencae 0:7c0953072ecb 11 Updated Dec 2020
eencae 0:7c0953072ecb 12
eencae 0:7c0953072ecb 13 */
eencae 0:7c0953072ecb 14
eencae 0:7c0953072ecb 15 #include "mbed.h"
eencae 0:7c0953072ecb 16 #include "platform/mbed_thread.h"
eencae 0:7c0953072ecb 17
eencae 0:7c0953072ecb 18 // defines directions as 0/1. Note UPPERCASE
eencae 0:7c0953072ecb 19 #define UP 0
eencae 0:7c0953072ecb 20 #define DOWN 1
eencae 0:7c0953072ecb 21
eencae 0:7c0953072ecb 22 // create a bus for writing to the output (LEDs) at once
eencae 0:7c0953072ecb 23 BusOut output(LED4,LED3,LED2,LED1);
eencae 0:7c0953072ecb 24 // Button A on board
eencae 0:7c0953072ecb 25 InterruptIn buttonA(p29);
eencae 0:7c0953072ecb 26
eencae 1:1e34d5c96ecf 27 // struct for state
eencae 1:1e34d5c96ecf 28 struct State {
eencae 1:1e34d5c96ecf 29 int output; // output value for current state
eencae 1:1e34d5c96ecf 30 int time; // wait time for state (ms)
eencae 1:1e34d5c96ecf 31 int next_state[2]; // next state (depending on direction 0 - UP, 1 - DOWN)
eencae 1:1e34d5c96ecf 32 };
eencae 1:1e34d5c96ecf 33
eencae 1:1e34d5c96ecf 34 // array of states in the FSM, each element is the output of the counter, wait time, next state(s)
eencae 1:1e34d5c96ecf 35 State g_fsm[4] = {
eencae 1:1e34d5c96ecf 36 {0b0001,500,{1,3}},
eencae 1:1e34d5c96ecf 37 {0b0010,500,{2,0}},
eencae 1:1e34d5c96ecf 38 {0b0100,500,{3,1}},
eencae 1:1e34d5c96ecf 39 {0b1000,500,{0,2}},
eencae 1:1e34d5c96ecf 40 };
eencae 0:7c0953072ecb 41
eencae 0:7c0953072ecb 42 // flag - must be volatile as changes within ISR
eencae 0:7c0953072ecb 43 // g_ prefix makes it easier to distinguish it as global
eencae 0:7c0953072ecb 44 volatile int g_buttonA_flag = 0;
eencae 0:7c0953072ecb 45
eencae 0:7c0953072ecb 46 // Button A interrupt service routine
eencae 0:7c0953072ecb 47 void buttonA_isr();
eencae 0:7c0953072ecb 48
eencae 0:7c0953072ecb 49 int main()
eencae 0:7c0953072ecb 50 {
eencae 0:7c0953072ecb 51 // Button A has a pull-down resistor, so the pin will be at 0 V by default
eencae 0:7c0953072ecb 52 // and rise to 3.3 V when pressed. We therefore need to look for a rising edge
eencae 0:7c0953072ecb 53 // on the pin to fire the interrupt
eencae 0:7c0953072ecb 54 buttonA.rise(&buttonA_isr);
eencae 0:7c0953072ecb 55 // since Button A has an external pull-down, we should disable to internal pull-down
eencae 0:7c0953072ecb 56 // resistor that is enabled by default using InterruptIn
eencae 0:7c0953072ecb 57 buttonA.mode(PullNone);
eencae 1:1e34d5c96ecf 58
eencae 0:7c0953072ecb 59 // set inital state
eencae 0:7c0953072ecb 60 int state = 0;
eencae 0:7c0953072ecb 61 // set initial direction
eencae 0:7c0953072ecb 62 int direction = UP;
eencae 0:7c0953072ecb 63
eencae 0:7c0953072ecb 64 while(1) { // loop forever
eencae 0:7c0953072ecb 65
eencae 0:7c0953072ecb 66 // check if flag i.e. interrupt has occured
eencae 0:7c0953072ecb 67 if (g_buttonA_flag) {
eencae 0:7c0953072ecb 68 g_buttonA_flag = 0; // if it has, clear the flag
eencae 0:7c0953072ecb 69 // swap direction when button has been pressed
eencae 1:1e34d5c96ecf 70 direction = ! direction;
eencae 0:7c0953072ecb 71 }
eencae 0:7c0953072ecb 72
eencae 1:1e34d5c96ecf 73 // set output of current state (use dot syntax to access struct members)
eencae 1:1e34d5c96ecf 74 output = g_fsm[state].output;
eencae 1:1e34d5c96ecf 75 // implement required delay
eencae 1:1e34d5c96ecf 76 thread_sleep_for(g_fsm[state].time);
eencae 1:1e34d5c96ecf 77 // set the next state depending on direction
eencae 1:1e34d5c96ecf 78 state = g_fsm[state].next_state[direction];
eencae 0:7c0953072ecb 79
eencae 0:7c0953072ecb 80 }
eencae 0:7c0953072ecb 81 }
eencae 0:7c0953072ecb 82
eencae 0:7c0953072ecb 83 // Button A event-triggered interrupt
eencae 0:7c0953072ecb 84 void buttonA_isr()
eencae 0:7c0953072ecb 85 {
eencae 0:7c0953072ecb 86 g_buttonA_flag = 1; // set flag in ISR
eencae 0:7c0953072ecb 87 }