Category Archives: C Programming

C Programming

Stellaris LM3S6965 PWM Tutorial

In this tutorial the Stellaris LM3S6965 Evaluation board will be used to demonstrate a simple PWM (Pulse Width Modulated) example.  This is part of a larger project I am working on, which is not covered in this tutorial but will be posted at a later date.

When carrying out any programming on the Stellaris LM3S series, I would highly recommend downloading the Peripheral Driver Library PDF, this contains details of all the functions used to control the on chip peripherals.  The current release at the time of writing is spmu019p.pdf and can be downloaded from here

You will also need to install StellarisWare which is the Texas Instruments library files for the Stellaris and also contains code examples.  Viewing the various libraries while in code composer can be very useful to fully understand what each function does.  The 2 files for the PWM are pwm.h and pwm.c, which can be found in the StellarisWare installation folder, in my case this C:/StellarisWare/driverlib/

The first thing that needs to be setup with the Stellaris is the system clock, the following code below uses the external crystal oscillating at 8MHz.

Next the PWM peripheral needs to be enabled, there are 3 PWM modules on the LM3S6965 evaluation board.  For this example PWM0 will be used, which is located on GPIO port F.

The next step is assign a pin type to the GPIO, there is a specific function to configure a pin or pins for use by the PWM peripheral.

PWM0 and GPIO pin 0 on port F is assigned, this combination was used for the PWM as it allows the onboard status LED to be controlled by varying the brightness, and will also allow a meter to be used to measure the frequency from the PWM.  The image below and left shows the I/O Break Pads, the image on the right the on board peripheral signals, both are extracts from the LM3S6965 evaluation board user guide.

Stellaris LM3S6965 PWM TutorialStellaris LM3S6965 PWM Tutorial

 

 

 

 

 

 

 

After the GPIO is setup the PWM can now be configured.  As stated before there are 3 PWM modules on this particular microprocessor, only 1 is being used in this example PWM0.  Each PWM generator module has a 16 bit counter, 2 PWM comparators, a PWM signal generator, a dead-band generator and an interrupt/ADC-trigger selector.  This program example will just produce a simple output using the up down counter.

PWMGenConfigure() is used to set the mode of operation for the PWM generator.  The counting mode, syncronization mode, and debug behaviour are all configured.  Once configured the generator is in a disabled state.  A code snippet of this function is shown below.

PWMGenPeriodSet() is used to set the period of the PWM generator.  Note the comment regarding the placement of this function with regards to PWMGenConfigure().

PWMPulseWidthSet() is used to set the width of the pulse for the specified PWM ouput.    Note the comment regarding the placement of this function with regards to PWMGenConfigure().

PWMGenEnable() is used to enable the timer/counter of the PWM generator.

PWMOutputState() enables or disables the PWM outputs.

In this example a frequency of approximately 24kHz was generated, with approximately a 50% duty cycle.  The image below shows a basic multimeter with a frequency counter, displaying a value which coincided with the example program, and 2 further images showing Oscilloscope traces with the PWM duty cycle at 50% and 15%.

Stellaris LM3S6965 PWM Tutorial

 

Image with PWMPulseWidthSet(PWM_BASE, PWM_OUT_0, 166);

Stellaris LM3S6965 PWM Tutorial

Image with PWMPulseWidthSet(PWM_BASE, PWM_OUT_0, 50);

Stellaris LM3S6965 PWM Tutorial

Example Code

The link below contains the zip file with the complete C code, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

Stellaris LM3S6965 PWM C code

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

MSP430 ADC Tutorial

In this MSP430 ADC tutorial the MSP430G2253 will be used as an example.  Texas Instruments ships the MSP430G2253 microprocessor with the latest Launchpad, the datasheet for the MSP430G2253 can be downloaded here

The MSP430G series devices are supplied in a number of packages with different specification and peripherals, there are 2 types of ADC, ADC10 and ADC12.  The ADC10 is a 10bit analog to digital conversion and the ADC12 is a 12bit analog to digital conversion.  The MSP430G2253 only incorporates the ADC10, apart from having greater resolution the ADC12 does not differ that much from the ADC10. Suggested reading on the main differences between the 2 types of ADC is the MSP430x2xx Family User’s Guide, which at the time of writing is release SLAU144J here

Before reading further if you are having trouble understanding how the registers work, and how the C code updates the individual register settings?  It would be worth reading my MSP430 Programming Tutorial, Part 1 covers the basics and Part 2 gives clear examples.  You can find them here Part 1 and Part 2.

ADC10 Resolution

Firstly lets clarify what 10bit resolution is and how this maybe relevant to the accuracy of a project.  10bit means 2 to the power of 10, or 2x2x2x2x2x2x2x2x2x2x2 which equals 1024, the 1024 is the number of sample steps taken over a given range (in the case of microcontrollers it’s actually 0 to 1023).

So now we understand the term regarding bit size, we need to find the range.  The range is defined as what voltage range the ADC accepts, to find this we need to consult the datasheet for the MSP430G2253, an extracted image from the datasheet can be seen below.

MSP430 ADC Tutorial C Code Examples

So from this the voltage range for the ADC can be determined as 0-3 volts.  So now that we have the range and the number of sample steps, we can now determine the resolution of the ADC with some simple maths.  The ADC12 has also been shown to help illustrate the step size changes and how this affects accuracy.

MSP430 ADC Tutorial C Code Examples

So using an example we can see what this would mean in real terms, if 1.5V was fed into the ADC input.

MSP430 ADC Tutorial C Code Examples

Now the value of 512 or 2048 is the value that would be stored as a variable by the ADC, this can actually be seen in Code Composer Studio and will be demonstrated later on in this tutorial.

ADC10 Registers

The ADC10 module on the MSP430G devices is configured by the user through software. There are various registers used to change the way the ADC10 operates dependent on the application requirements.

MSP430 ADC Tutorial C Code Examples

ADC10 Analog Input Enable Register 0

This allows the user to enable the specific GPIO pin/s for analog input.  The command used for this register looks something like this ADC10AE0 |= 0x02;  (0x02 is selecting the ADC A1 or port P1.1).

ADC10 Analog Input Enable Register 1

This is not available on the MSP430G2253 device.

ADC10 Control Register 0

Control register 0 has various parameters that can be set which are listed below, the MSP430 Family Guide SLAU144J has a full list of all these parameters with more in depth descriptions.    The command used for this register looks something like this ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE;

SREFx – Select Reference.  There are varies parameter options that can be set for select reference.

ADC10SHTx – Sample and Hold Time.  This adjust how many clock cycles the sampling period will be.

ADC10SR – Sampling Rate.  Adjusts the sampling rate between ~200ksps or ~50ksps

REFOUT – Reference Output.  Reference voltage output to GPIO pin with Vref capability

REFBURST – Reference Burst.  Disables the internal reference voltage automatically when the ADC10 is not converting.

MSC – Multiple Sample Conversion.  Allows multiple samples to be taken automatically.

REF2_5V – Reference Generator Voltage. selectable between 1.5V and 2.5V

REFON – Reference Generator On.  Turns on the internal reference voltage.

ADC10ON – ADC10 On.  Turns on the ADC10

ADC10IE – Interrupt Enable.  Enables interrupts for the ADC10

ADC10IFG – Interrupt Flag.  Enables Interrupt flag for the ADC10

ENC – Enable Conversion.  Enables the conversion and can be used to stop a conversion by resetting ENC.

ADC10SC – Start Conversion.  Starts the conversion on the ADC10

ADC10 Control Register 1

Control register 1 has various parameters that can be set which are listed below, the MSP430 Family Guide SLAU144J has a full list of all these parameters with more in depth descriptions.    The command used for this register looks something like this ADC10CTL1 = INCH_10 + ADC10DIV_3 + CONSEQ_2;

INCHx – Input Channel Select.  This selects the GPIO pin/s used for the ADC input.

SHSx – Sample and Hold Source Select.

ADC10DF – Data Format.  Straight binary or 2s compliment.

ISSH – Invert Signal Sample and Hold.

ADC10DIVx – Clock Divider.  Allows the chosen clock source used for the ADC to be divided down.

ADC10SSELx – Clock Source Select.  Allows the user to select which of the MSP430 clocks to be used for the ADC.

CONSEQx – Conversion Sequence Mode.  Allows difference conversion sequences on single or multiple channels.

ADC10BUSY – Busy.  Indicates an active sample or conversion operation.

ADC10 Memory

This is the conversion memory register.  The command used for this register looks something like this ADC_data = ADC10MEM;

ADC10 Data Transfer Control Register 0

Data transfer control (DTC) register 0, has various parameters for the control of the data transfer. The DTC automatically transfers conversion results from ADC10MEM to other on chip memory locations.  The command used for this register looks something like this ADC10DTC0 |= ADC10TB + ADC10CT;

ADC10 Data Transfer Control Register 1

Data transfer control register 1, defines the number of transfer in each block.  The command used for this register looks something like this ADC10DTC1 = 0x20; 

ADC10 Data Transfer Start Address

ADC10SAx – Start Address.  The command used for this register looks something like this ADC10SA = 0x0200;

Example 1

The code pasted below will perform a  single read from GPIO P1.3 and then assigns the value of ADC10MEM to a variable called ADC_value.

Example 1 Code

The link below contains the zip file with the full example 1 C code, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

Example 1 Code

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

Example 2

The code pasted below will perform a repeated read from GPIO P1.0 and then using the DTC, it will copy the value into an array.  The DTC automatically increments the address of the array.  The integer array containing the value is then added together and divided by 10 to give an average value, which is assigned to the variable avg_adc.

The image below shows a screen capture from the debug mode in code composer studio. By using a breakpoint and watching the expressions adc[10] and avg_adc, the values can be viewed changing (almost live) as the input to the ADC changes.  A light dependent resistor circuit was used as input to the ADC in this case.

MSP430 Launchpad ADC Tutorial

Example 2 Code

The link below contains the zip file with the full example 2 C code, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

Example 2 Code

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

Example 3

The 3rd example reads 3 separate GPIO pins repeatedly, these pins are p1.1, p1.2 and p1.3. The program was originally written to be used with an analog 3 axis accelerometer, so some of the variables are still named in this manner.  Most of the comments within the code have been removed to reduce the size of the snippet, however the fully commented code can be downloaded below.

Example 3 Code

The link below contains the zip file with the full example 3 C code, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

Example 3 Code

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

MSP430 State Machine Project Pt/2

In part 2 of this MSP430 state machine project, I will overview the state machine logic, as well as covering the C programming code.

State Machine

MSP430 State Machine Project C Code

The state machine diagram above illustrates the logic behind the state machines operation. The machine can only be in one state at a time, this is known as the current state. Changes from one state to another are brought about by an event, this brings about a transition into a new state or alters a parameter in the current state.

As can be seen from the diagram there are 5 states.  There are 8 events listed in top right of the image, 2 of these events (E_INC and E_DEC) do not trigger a state transition but alter a parameter in the states they are associated with.

The lines and arrows between each of the states shows the direction that a state can transition to i.e. in the diagram above we can see that the OFFSTATE cannot make a transition to the AUTOMATIC STATE.  Therefore the state diagram gives us a structure to follow, that can be hard coded into the C programming code ensuring the logical flow of the state machine is followed.

States

OFFSTATE – This is simply a state to indicate the system is off

ONSTATE – This is simply a state to indicate the system is on

BRIGHTNESS ADJ STATE – Allows the brightness of an LED to be increased and decreased

PRESETS MODE STATE – Allows the user to scroll through 3 preset LED brightness values

AUTOMATIC STATE – The brightness of the LED will be dependant on the brightness of the ambient light falling on the LDR

Events

E_OFF – This brings about a transition into the OFFSTATE

E_ON – This brings about a transition into the ONSTATE

E_BRIADJ – This brings about a transition into the BRIGHTNESS ADJ STATE

E_PRESET – This brings about a transition into the PRESETS MODE STATE

E_AUTO – This brings about a transition into the AUTOMATIC STATE

E_INC – Allows the user to increase the brightness or change the preset levels, depending on which state the system is currently in

E_DEC – Allows the user to decrease the brightness or change the preset levels depending on which state the system is currently in

E_TIMEOUT – This brings about a transition into the ONSTATE and is a 15 second timeout

MSP430 State Machine C Code

In this section of the tutorial I will give a brief overview of the main parts of the code.  All of the code was written in either Eclipse or Texas Instruments Code Composer Studio v5.3 or above.

Variables

There are 2 types of enum value enum states and enum events, the enum states are prefixed with an ‘S’ and the enum events are prefixed with an ‘E’, this ensures that they are easily readable when coding.

There are also 10 global variables which is not ideal and global variables should be avoided when ever possible, at the time of writing this code I was not aware of a better solution and this method sufficed.

Most of these are self explanatory so I will cover the ones I believe are most relevant:

sysTick –  This uses the system timer to generate a timed pulse which is used like a system heart beat to bring control and order to the state machine and the user button polling.

ScrRefresh – As the LCD was interfaced with minimum pins, any feedback from the LCD to indicated it is busy was not possibly.  The LCD operates at a much slower frequency to the microcontroller.

briadjSys, presetSys and autoSys – The last 3 global variables are used as flags to determine the current state, they are toggled every time a transition is made from or to states S_BRIADJ, S_PRESET and S_AUTO.  Specific functions are run depending on the toggled values outside the StateM function, but within the infinite while loop.  These variables are necessary as the functions will then run even when the state changes to S_ON, which can be transitioned to after 15 seconds if the TimeOut function is called.

Functions

CheckButtons – This function contains if else statements, which are executed and return an event depending on which user button was pressed.  There is also some addtional checks using C operators to determine what state the state machine is in.  The CheckButtons function returns a value to the StateM function.  *Update*  This code is still valid but I have improved on a function to check the GPIO pins on the MSP430, by using switch case statements.  This is all covered in a new two part article on switch debouncing, located here.

StateM – The StateM function contains the main frame work for the state machine.  It uses switch case statements to determine which state the current state can make a transition to, when an event is passed to it.

The logic in this function defines how the state machine will operate.  Looking back to the state machine diagram it can be seen that the OFFSTATE can only make a transition into the ONSTATE.  Now looking at the first case in the code below, it can be seen that the only state S_OFF can move to is S_ON, which is brought about by the E_ON event.  The rest of the switch case code follows the same logical process and can be directly compared with the state diagram.

Right at the end of the StateM function are 2 if statements, these are used to run external functions called OnEnter, OnExit and Do.  These functions can be used to action any code when a transitions occurs between 2 states, or if the same state is selected.

counter – This function sets up and initialises the Timer 0 on the MSP430, the code is well commented so does not need a great deal of explanation.  When the timer has counted to the predefined value, an interrupt is generated, this is then used to set the sysTick variable to 1, the sysTick variable is then zeroed every time the StateM function is executed, which allows the user buttons to be polled.  There is also some additional counter timing functions carried out here for the TimeOut function.

TimeOut – The TimeOut function simply runs if a counter reaches a certain value, which is roughly 15 seconds.  The counter for this function is reset every time the user presses a button.  looking back at the CheckButtons function right at the top can be seen the logic for the E_TIMEOUT event.

setup_HW – This function contains the code used to stop the watchdog timer, set up the system clock, set up the ADC and finally some GPIO port settings.

automatic – This function is used to take the ADC value read from the LDR input.  It divides the value by 9, so it can be broken down into 10 values the user can then adjust the brightness on a scale of 1 to 10.

automatic_lcd – This function is used to update the LCD with the raw value being read directly from the ADC input, an external itoa function is used to convert the integer into a char string so it can be displayed correctly on the LCD.  The ScrRefresh variable is used to ensure the LCD is not updated too quickly, which would otherwise cause corruption of the LCD information.

main – The main function obviously contains the programming code and is essential to any C program, this is the last function I will over with a code excerpt as it ties together the functions previously discussed.

There are some hardware set up functions run at the start of main.  Then there is an infinite while loop, a characteristic of any embedded system.  The first if statement ensures the sysTick variable is equal to 1, and then if this is true the next if statement ensures a user button has been pressed.

The StateM function is, which calls the CheckButtons function, which then returns an event to the StateM function.  Once the StateM function is complete, the sysTick and LongDelay variables are both reset to 0.

The last 3 if statements ensure that the LED’s are controlled continuously even when the state machine is not running, the three variables being used as flags are all reset upon entering the S_OFF state.

Finally the TimeOut function is called and counter checked.

OnEnter – This function is called at the end of the StateM function, and is passed the next state value as an integer. Using a switch case statement the OnEnter function then runs any code specified for that new state upon entering.

Do – This function is also called at the end of the StateM function, and is passed the current state (which now has the same value as the next state) value as an integer. Using a switch case statement the Do function then runs any code specified for the current state to run.

bri_adj – Function is called by the Do function when in S_BRIADJ state, it displays information on the LCD depending on the brightness value, which is determined by the increase and decrease user buttons.

preset_modes – This is very similar to bri_adj function except it is called when in the S_PRESET state.

soft_PWM – Function loads a software PWM based on switch case statements, which determine the brightness of the output LED’s.

preset_level – Almost the same as the soft_PWM function, but fewer cases.

Complete State Machine C Code

The link below contains the zip file with the full state machine C code covered in this second  tutorial, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

MSP430 State Machine C Code

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

State Machine Tutorial Pt/3

State Machine tutorial part 3.

In this third part of the state machine tutorial some improvements to the C programming code shown in part 2 will be made, the code is still based on the state machine diagram shown in part 1.

Removing the Global Variable

The first improvement will remove the global variable Current_State, using this as a local variable in the main function.  Firstly we have to declare the function prototype for the StateMachine function as follows:

The main function needs to change, so the function call for StateMachine function reflects the change in the function prototype, so it has 2 parameters.

Addtionally a local variable to main is declared enum states Current_State = S_OFF;

Now the StateMachine function has 2 parameters,  enum events event and enum states Current_State;

The enum events event parameter relates to the returned value from the ReadKeyInput function, this is called by the StateMachine function as per the previous code example.

The enum states Current_State parameter returns the value of the Next_State variable inside the StateMachine function.  There is a return Next_State; statement at the end of the StateMachine function, the only other change is to the StateMachine function declaration as with the function prototype ensuring the parameters match.

LookUp Table Structure Improvement

A lookup table contains predefined values, and is often used as it saves valuable clock cycles that would otherwise be spent carrying out a calculation.  In this instance the lookup table is used to simplify the functions called, when a transition from or to a state and when the same state is selected.

There will be individual functions available for execution when entering, exiting and while-in a state.  This makes for a cleaner layout and removes the additional switch case statements in the UponEnter, UponExit and ActionWhileInState functions.  Pointers are used to bring this about as well as a typedef statement.  The code excerpt below shows the 9 additional function prototypes that will be used.

The next step is to set-up the typedef and pointer that will be used with the lookup table.

The line starting with typedef is a typedef for a function pointer, the function this pointer points to expects no parameters and not returning anything to be exact.

The 3 lines that follow are the function pointers, one for each state.  These hold arrays of data that correspond to each state, and point to individual functions that will be actioned when a state transition or the same state is selected.

The third piece of code relevant to this lookup table is found at the bottom of the StateMachine function.

There are 3 function calls at the end of the StateMachine function;

UponExit[Current_State]();  UponEnter[Next_State]();  ActionWhileInState[Current_State]();

So for example the line UponExit[Current_State](); calls the function pointer UponExit[Current_State]();  points to either;

State_Exit_OFF if Current_State is 0  enum states { S_OFF == 0

State_Exit_ON if Current_State is 1  enum states { S_ON == 1

State_Exit_PROCESS if Current_State is 2  enum states { S_PROCESS == 2

There is also an additional else statement that allows ActionWhileInState function, to only be called if the Next_State is equal to the Current_State.

The process that is happening here can be illustrated in a simple table, showing the function/s called depending on the state transition:

State Machine Project Tutorial C Code

State Machine output

The image below is a screen capture of the console window in Eclipse, this shows the output from the state machine code as numbers are entered from the keyboard.  As shown in the diagram when a transition occurs the UponExit and UponEnter functions are called, but if the same number is entered on the keyboard, then no transition occurs and the ActionWhileInState function is only called.

State Machine Project Tutorial C Code

Complete State Machine C Code

The link below contains the zip file with the full state machine C code covered in this third tutorial, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

State Machine v1.2

I would also like to take this opportunity to give a big thanks to Roadrunner84 from the www.43oh.com forums, he has been very helpful and clearly possess a great understanding of the C language.

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

State Machine Tutorial Pt/2

State Machine tutorial part 2 of 3.

Is this part the C programming code for the basic state machine diagram shown in part 1. All the code presented here was written using the open source software Eclipse IDE, this can be downloaded from here.

Starting at the top of the code and working down, all the main elements will be explained. The complete code can be downloaded at the bottom of this article.

Variables

Firstly we need to define the variables for the state machine. Enum is used instead of another variable type, as it allows a type with a restricted set of values.  So we therefore have enum states and enum events, each with their own set of restricted values, what can also be noted is the states and events correspond directly with those found in the state machine diagram in part 1.  The code excerpt below shows the code for the variables.

There is one global variable used in this basic example, Current_State which is used to store the current state machine state outside the state machine function.  The Current_State variable is set to the S_OFF state from the beginning, this enables a predictable outcome when the program is first run.  This variable can be seen in the code extract below.

Function Prototypes

These are used to provide the compiler with the name and arguments of the functions used in the program, they must appear before the function is used in the program.  Each of these functions will be explained in more detail further down this tutorial.

 Main Function

This is where the main program code to be executed is written.  The main is quite short and consists of a continuous while loop, which contains the StateMachine function call.

 ReadKeyInput Function

The ReadKeyInput function takes a value entered by a user and then passes this to the StateMachine function.  The ReadKeyInput function uses a local char variable called input, the scanf function forms part of the C library functions and allows user input via the keyboard which is stored in the char variable input.  The variable is then used in the switch case statement, to return an event type pending on the user input.  The code snippet below shows the entire ReadKeyInput function.

 StateMachine Function

This as it’s name suggests contains the main state machine structure, based around a switch case statement.  When an event is passed to this function by the ReadKeyInput function, firstly a local variable called Next_State is assigned the value held in the variable Current_State, the switch case is then used using the Current_State variable.  So if S_OFF is the value assigned to the Current_State variable, the switch case will open the first case in the sequence which is S_OFF.

Now if the user has entered the number 2 on the keyboard, the event E_ON will be generate by the ReadKeyInput function, this will therefore match up with the event logic inside the nested switch case statement contained within the S_OFF case inside the StateMachine function.  Then the Next_State variable will be assigned the S_ON state.  If key numbers 1 or 2 are pressed E_OFF or E_START will be generated by the ReadKeyInput function, neither of these are valid arguments for the nested switch case statement contained within the S_OFF case, so there will be no change of state and the code performs as per the state machine diagram.  The same logic follows for the S_ON and S_PROCESS cases inside the StateMachine function.  The StateMachine function code can be seen below.

The final piece of code at the bottom of the StateMachine function allows some additional functionality, firstly the if (Next_State != Current_State) uses the ‘not equal to’ operator, so if there is a state transition, some code can be executed when exiting the current state and entering the next state.

The last statement if ( event != E_MAX) ActionWhileInState( Current_State ); runs the ActionWhileInState function as long as the event is not equal to E_MAX.

UponEnter Function

This function allows custom code to used to execute when entering a new state, the function uses a switch case which is passed the Next_State variable value.  The function can be seen below in the code excerpt.

ActionWhileInState Function

This function allows custom code to used to execute while in the current state, the function uses a switch case which is passed the Current_State variable value.  The function can be seen below in the code excerpt.

UponExit Function

This function allows custom code to used to execute when exiting the current state, the function uses a switch case which is passed the Current_State variable value.  The function can be seen below in the code excerpt.

State Machine output

The image below is a screen capture of the console window in Eclipse, this shows the output from the state machine code as numbers are entered from the keyboard.  As shown in the diagram when a transition occurs the UponExit and UponEnter functions are called, as well as the ActionWhileInState function.  If the same number is entered on the keyboard, then no transition occurs and the ActionWhileInState function is only called.  Also the number 4 was entered at the very end, but no transition occurred as this is not a valid argument.

State Machine Project Tutorial C Code

Complete State Machine C Code

The link below contains the zip file with the full state machine C code, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

State Machine Zip

Further improvements can still be made to this code but this forms a good starting point in understanding the state machine structure.  In part 3 of this tutorial some of the code improvements will be shown.

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

State Machine Tutorial Pt/1

State Machine tutorial part 1 is the first post in a series of 3.

A state machine or as it is also known a finite state machine (FSM), is a model used to design computer programs and sequential logic circuits. The machine can only be in one state at a time, this is known as the current state.  Changes from one state to another are brought about by an event or certain condition, this brings about a transition into a new state.

State machines are found in many devices, some we come across in our every day lives, for example a microwave oven, dishwasher and washing machine. All three of these devices have a standby state where they are waiting for input from a user, the devices will then switch to an active state performing some task, when the task is completed an event is triggered (usually determined by a timer), the device will switch to a new state or possibly back to standby and the user may be alerted by the transition to the new state.

State machines can be very simply with just a few states, or have many different states with many transitions between them.

So to sum up, a state machine is a device that stores the status of something at a particular time, can operate on an input to change the status and/or cause an action or output to take place for any given change.

Further reading on state machines can be found here

Basic State Machine Example

Over the next few tutorials a basic state machine will be explained, using C code that is portable and gives a good basic structure which can be built upon.  This can then be used used to form simple microcontroller embedded systems.  A further example will also be shown based on the Texas Instruments MSP430G223x device, which allows human interaction with a basic interface.

State Machine Project Tutorial C Code

The image above shows a basic state machine diagram, with the following specification:

  • There are 3 states S_OFF, S_ON and S_PROCESS.  The states are prefixed with an ‘S’ as I find this makes the code easier to understand later.
  • There are 3 events E_OFF, E_ON and E_START.  Again these are prefixed but with an ‘E’.
  • There are 4 transitions shown by the green arrows, these also indicate the direction which determines how the state machine structure functions.

S_OFF has 3 transitions attached to it’s state.  It can only move to the S_ON state via the E_ON event, the other 2 transitions are triggered by the E_OFF event, which causes a transition from either S_ON or S_PROCESS into the S_OFF state.    So it is not possible for the S_OFF state to move to the S_PROCESS state.

S_ON has 3 transitions attached to it’s state.  The E_ON event causes a transition from the S_OFF state into the S_ON state.  The E_OFF event causes a transition from the S_ON state into the S_OFF state, and the E_START event brings about a transition to the S_PROCESS state.

S_PROCESS has 2 transitions attached to it’s state.  It can only move to the S_OFF state via the E_OFF event.  The other transition is from the S_ON state via the E_START event.  So it is not possible for the S_PROCESS state to move to the S_ON state.

This example should illustrate the basic mechanism of a state machines logical process, it also aims to show the power of a state machine diagram which can be very useful when constructing the code around the system.

State machines inherently promote good design techniques, so when designing an application think about the states and events you will use.

In the next part of this tutorial we will dive into the C programming code using this basic example for the system.

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.