5.1 Unit 5 State Machines
5.2 What is state? • You see a DPS officer approaching you. Are you happy? – It's late at night and your car broke down. – It's late at night and you've been partying a little too hard. • Your interpretation is based on more than just what your senses are telling you RIGHT NOW, but by what has happened in the past – The sum of all your previous experiences is what is known as state – Your 'state' determines your interpretation of your senses and thoughts • In a circuit, 'state' refers to all the bits being remembered (registers or memory) • In software, 'state' refers to all the variable values that are being used
5.3 State Machine Block Diagram • A system that utilizes state is often referred to as a state machine – A.k.a. Finite State Machine [FSM] • Most state machines can be embodied in the following form – Logic examines what's happening NOW (inputs) & in the PAST (state) to… • Produce outputs (actions you do now) • Update the state (which will be used in the future to change the decision) • Inputs will go away or change, so state needs to summarize/capture anything that might need to be remembered and used in the future Inputs Logic Outputs (A-to-D, Timer, Buttons) State (memory)
5.4 State Diagrams • Abstractly a state machine can be visualized and represented as a flow chart (or state diagram) – Circles or boxes represent state – Arrows show what input causes a transition – Outputs can be generated whenever you reach a particular state or based on the combination of state + input State Machine to check for two consecutive 1's on a digital input Input=1 Input=1 Input=1 Input=0 S0 S1 S2 Out=False Out=False out=True Input=0 On startup Input=0
5.5 Washing Machine State Diagram /RESET Stay in the initial state until there is enough COINS + DOOR Idle money (coins) and N=2 the door is closed COINS • DOOR Fill FULL WV = 1 FULL Agitate We move through the 5 MIN Motor = 1 states based on the conditions. Outputs 5 MIN / Reset_Timer=1 get asserted when the Drain machine is in that EMPTY DV = 1 state and the transition is true. EMPTY N > 0 N = N - 1 N = 0
5.6 Washing Machine State Diagram /RESET Move to the Fill state when there is enough COINS + DOOR Idle money (coins) and N=2 the door is closed COINS • DOOR Fill FULL WV = 1 FULL Agitate 5 MIN Motor = 1 5 MIN / Reset_Timer=1 Drain EMPTY DV = 1 EMPTY N > 0 N = N - 1 N = 0
5.7 Washing Machine State Diagram /RESET COINS + DOOR Idle Stay in the Fill state N=2 until it is full…also COINS • DOOR set the Water Valve Open output to be Fill FULL true WV = 1 FULL Agitate 5 MIN Motor = 1 5 MIN / Reset_Timer=1 Drain EMPTY DV = 1 EMPTY N > 0 N = N - 1 N = 0
5.8 Washing Machine State Diagram /RESET COINS + DOOR Idle N=2 COINS • DOOR Move to the Agitate state after it is full Fill FULL WV = 1 FULL Agitate 5 MIN Motor = 1 5 MIN / Reset_Timer=1 Drain EMPTY DV = 1 EMPTY N > 0 N = N - 1 N = 0
5.9 Software vs. Hardware • Software • Hardware – State = just a variable(s) – State = Register (D-Flip-Flops) – Logic = if statements to – Logic = AND/OR Gates to produce update the next state the next state & outputs • if(state == 0 && input == 1) { state = 1; } – Transitions triggered by clock – Transitions triggered by input signal or timers – More on this later in the – We'll start by implementing semester state machines in SW Inputs Outputs Logic (ADC, Timer, Buttons) State (memory)
5.10 Software Implementation • Store 'state' in some variable and assign numbers to represent state (0=Idle, 1=Fill, etc.) • Use a timer or just poll certain int main() int main() { { inputs and then make bool coins, door; bool coins, door; int currst = 0, nextst = 0, n = 2; int state = 0, n = 0; appropriate transitions while(1) while(1) { { /RESET _delay_ms(10); _delay_ms(10); coins = PIND & (1 << PD0); coins = PIND & (1 << PD0); COINS + DOOR Idle door = PIND & (1 << PD1); door = PIND & (1 << PD1); N=2 if(currst == 0){ if(state == 0){ COINS • DOOR if( coins && door ){ if( coins && door ){ Fill FULL WV = 1 Use nested 'if' nextst = 1; state = 1; FULL statements: } } Agitate outer 'if' selects 5 MIN } } Motor = 1 state then inner else if(state == 1){ else if(currst == 1){ 5 MIN / Reset_Timer=1 'if' statements ... ... Drain EMPTY DV = 1 examine inputs } } EMPTY ... ... N > 0 N = N - 1 } currst = nextst; // update state return 0; } N = 0 State Diagram for a } return 0; Washing Machine }
5.11 More Implementation Tips // input = PD0, output = PD7 • Continuously loop int main() { // be sure to init. state unsigned char state=0, nstate=0; • Each iteration: unsigned char input, output; – Poll inputs while(1) { _delay_ms(10); – Use if statement to decide current nstate = state; // stay by default input = PIND & (1 << PD0); state if(state == 0){ Select current state – In each state, update state PORTD &= ~(1 << PD7); if( input ){ nstate = 1; } appropriately based on desired } transitions from that state else if(state == 1){ Select input val. PORTD &= ~(1 << PD7); – Produce appropriate output from if( input ){ nstate = 2; } else { nstate = 0; } that state } else { // state == 2 PORTD |= (1 << PD7); if( !input ) { nstate = 0; } } state = nstate; // update state } return 0; }
5.12 State Machines as a Problem Solving Technique • Modeling a problem as a state machine is a powerful problem-solving tool • When you need to write a program, design HW, or solve a more abstract problem at least consider if it can be modeled with a state machine – Ask questions like: • What do I need to remember to interpret my inputs or produce my outputs? [e.g. Checking for two consecutive 1's] • Is there a distinct sequence of "steps" or "modes" that are used (each step/mode is a state) [e.g. Thermostat, washing machine, etc.]
5.13 Example: Ad-hoc Implementation // Ad-hoc implementation int main() • Consider a program that checks { while(1) two buttons { int i; if(checkInput(1) == 0){ – When button 1 is pressed, blink an for(i=0; i < 10; i++) { LED 10 times at 2 HZ blink(250); // on for 250, off for 250 if(checkInput(2) == 0) – When button 2 is pressed, blink an { break; LED 15 times at 5 HZ } } } • If during the blinking of one LED if(checkInput(2) == 0){ for(i=0; i < 15; i++) the other button is pressed, you { blink(100); // on for 100, off for 100 if(checkInput(1) == 0) should immediately stop the { break; current blink cycle and start the } } } blink cycle of the other button. // delays are in the blink() functions // so no delay needed here • After a blink cycle is complete and // Problem: what if button that caused // break from for loop is released right now no button is pressed, simply wait } return 0; and do nothing. }
5.14 Example: FSM implementation int main() { • Formulated as a state machine: int state = 0, cnt = 0; while(1) – Separate code to update state and { // Update the state then perform actions based on state if (checkInput(1) == 0) { state = 1; cnt = 0; • Tip: Avoid loops other than the } else if (checkInput(2) == 0) state = 2; cnt = 0; primary while and use state and } else if( (state == 1 && cnt == 10) || if statements, instead (state == 2 && cnt == 15 ) ) { state = 0; cnt = 0; } State1 BTN1 // Use state to determine actions (LED1 @ if(state == 1) { blink(250); // on for 250, off for 250 2Hz) CNT==10 && cnt++; State0 BTN1 ! BTN1 && ! BTN2 } else if(state == 2) { No Blinking CNT==15 && blink(100); // on for 100, off for 100 ! BTN1 && ! BTN2 cnt++; State2 } } (LED2 @ ! BTN1 && BTN2 return 0; BTN2 5Hz) } Assume if no transition it true, we intend to stay in the same state.
5.15 Operations at Different Rates (1) int main() • Consider a program to blink one { while(1) { LED at a rate of 2 Hz and another LED1_ON(); _delay_ms(250); at 5 Hz at the same time LED1_OFF(); _delay_ms(250); • Problem : Does the code to the LED2_ON(); _delay_ms(100); right work correctly? LED2_OFF(); _delay_ms(100); – No! When one LED blinks the other } will be off return 0; }
5.16 Operations at Different Rates (2) int main() { • Use separate state machines int cnt1 = 0, cnt2 = 0; // set initial state of LEDs as "on" running in parallel int s1 = 1, s2 = 1; LED1_ON(); • Given various rates of operations, LED2_ON(); find the GCD of the various rates while(1) { and loop with that delay, using cnt1++; if(cnt1 == 5) { counts to track time if(s1) { LED1_OFF(); s1 = 0; } else { LED1_ON(); s1 = 1; } cnt1 = 0; } cnt1 == 5 / Reset cnt1 LED1 ON LED1 OFF cnt2++; if(cnt2 == 2) cnt1++ cnt1++ { cnt1 == 5 / if(s2) { LED2_OFF(); s2 = 0; } Reset cnt1 else { LED2_ON(); s2 = 1; } cnt2 = 0; } cnt2 == 2 / Reset cnt2 LED2 ON LED2 OFF // Delay the minimum granularity _delay_ms(50); cnt2++ cnt2++ } cnt2 == 2 / return 0; Reset cnt2 }
Recommend
More recommend