Craig Evans
/
ELEC2645_UpDown_Counter_Transition_Table_2021
Up Down counter using a transition table
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 /* 00002 00003 2645_FSM_UpDown_Counter 00004 00005 Sample code from ELEC2645 00006 00007 Demonstrates how to implement a simple FSM up/down counter 00008 00009 (c) Craig A. Evans, University of Leeds, Jan 2016 00010 Updated Jan 2020 00011 Updated Dec 2020 00012 00013 */ 00014 00015 #include "mbed.h" 00016 #include "platform/mbed_thread.h" 00017 00018 // defines directions as 0/1. Note UPPERCASE 00019 #define UP 0 00020 #define DOWN 1 00021 00022 // create a bus for writing to the output (LEDs) at once 00023 BusOut output(LED4,LED3,LED2,LED1); 00024 // Button A on board 00025 InterruptIn buttonA(p29); 00026 00027 // struct for state 00028 struct State { 00029 int output; // output value for current state 00030 int time; // wait time for state (ms) 00031 int next_state[2]; // next state (depending on direction 0 - UP, 1 - DOWN) 00032 }; 00033 00034 // array of states in the FSM, each element is the output of the counter, wait time, next state(s) 00035 State g_fsm[4] = { 00036 {0b0001,500,{1,3}}, 00037 {0b0010,500,{2,0}}, 00038 {0b0100,500,{3,1}}, 00039 {0b1000,500,{0,2}}, 00040 }; 00041 00042 // flag - must be volatile as changes within ISR 00043 // g_ prefix makes it easier to distinguish it as global 00044 volatile int g_buttonA_flag = 0; 00045 00046 // Button A interrupt service routine 00047 void buttonA_isr(); 00048 00049 int main() 00050 { 00051 // Button A has a pull-down resistor, so the pin will be at 0 V by default 00052 // and rise to 3.3 V when pressed. We therefore need to look for a rising edge 00053 // on the pin to fire the interrupt 00054 buttonA.rise(&buttonA_isr); 00055 // since Button A has an external pull-down, we should disable to internal pull-down 00056 // resistor that is enabled by default using InterruptIn 00057 buttonA.mode(PullNone); 00058 00059 // set inital state 00060 int state = 0; 00061 // set initial direction 00062 int direction = UP; 00063 00064 while(1) { // loop forever 00065 00066 // check if flag i.e. interrupt has occured 00067 if (g_buttonA_flag) { 00068 g_buttonA_flag = 0; // if it has, clear the flag 00069 // swap direction when button has been pressed 00070 direction = ! direction; 00071 } 00072 00073 // set output of current state (use dot syntax to access struct members) 00074 output = g_fsm[state].output; 00075 // implement required delay 00076 thread_sleep_for(g_fsm[state].time); 00077 // set the next state depending on direction 00078 state = g_fsm[state].next_state[direction]; 00079 00080 } 00081 } 00082 00083 // Button A event-triggered interrupt 00084 void buttonA_isr() 00085 { 00086 g_buttonA_flag = 1; // set flag in ISR 00087 }
Generated on Tue Jul 19 2022 23:32:33 by 1.7.2