This article is a Finite state machines example.
Finite state machines is a powerful technique when we want to drive external devices connected to the peripherals of a microcontroller.For example driving a serial eeprom 93c46 connected to th SPI port of the microcontroller.
At this example we write C code for a system having four finite states.
we will blink a led "on" and "off" and we will send at Hyperterminal a message (via Uart)informing us for the next state of the led.
So the transtition states of our system are:
Led_off -------->Uart_on --------->Led_on---------->Uart_off-------->Led_off
The stable states of the system are: Led_off, Uart_on, Led_on, Uart_off.
At the event Uart_on , uart sent the message "I'll turn the led on", and at the event Uart_off, uart sent the message "I'll turn the led off".
Each one of the transition states (actions) of our system is represented by a C function:
void led_on ()
{
P1L_P1= 0;
}
void led_off ()
{
P1L_P1= 1;
}
void uart_on (void)
{
printf ( " I'll turn the led on \n" );
}
void uart_off (void) {
printf ( " I'll turn the led off \n" );
}
of course we need and a delay() function included at the C code.
The "trick" of the code is the enumeration data type!
We enumerate the stable states:
//STATES ENUMERATION
typedef enum { Led_off, Uart_on, Led_on, Uart_off } state;
and we enumerate the transition states:
//TRANSITION STATES ENUMERATION
typedef enum {Led_on__Uart_off, Uart_off_Led_off, Led_off_Uart_on, Uart_on_Led_on }event;
for examle Uart_off_Led_off means that the uart send the message "I'll turn the led off" and the next state will be led "off"...etc..
Next we make a two dimensional array combining transition state and next stable state:
action_and_next_state ar[4][2]= { { Uart_on_Led_on, uart_on }, { Led_on__Uart_off, led_off} ,{ Uart_off_Led_off, uart_off}, \
{ Led_off_Uart_on,led_on} };
Please,don't be scared about this array ! It includes only integers ! Remember: The name of a function is a pointer to the function, a simple unsigned integer number!
We have cast the elements of the array to a structure of type:
typedef struct s{
state next;
action todo;
}action_and_next_state;
action_and_next_state stateevaluation;
saving the action that we have to do in order to reach the next state.
The function that calculates the next state using the above enumeratios is the:
void statecalculation(int x)
{
stateevaluation= ar[courent][x]; // action_and_next_state stateevaluation;
courent= stateevaluation.next;
(stateevaluation).todo();
}
So, open Hyperterminal at 19,200 bauds , run the program and watch the led blinking at a slow rate and at Hyperterminal a message inforrming for the next state of the led.
In sort: You have a machine (a wash machine for example), the machine is at a state (rotates the clothes), an event is happened (you added cold water), the machine is doing an action (the machine heats the cold water) and the machine enters a new state (rotates clothes with added hot water).
The C code Result at Hyperterminal
Further reading:
http://www.cs.utah.edu/~germain/PPS/Topics/C_Language/enumerated_types.html
http://en.wikipedia.org/wiki/Finite-state_machine
http://www.objectmentor.com/resources/articles/umlfsm.pdf
|