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.

MSP430 State Machine Project Pt/1

MSP430 state machine project tutorial demonstrates a simple state machine, with a human interface consisting of 4 buttons, an LCD and some interfacing electronics.

A video demonstrating the state machine code can be seen below.

This project write up uses a state machine based in the C language, the state machine model is based on some code discussed in a three part state machine tutorial I have already written.  The first part of this tutorial can be found here and all the state machine tutorial parts can be found in the C Programming category of this website.

The project itself is a good learning tool as it not only suing the concept of a state machine, but also incorporates the ADC and Timer on the MSP430 Launchpad.

The Initial Concept

The project was undertaken as part of a course and was designed to teach the basic concept of a state machine, as well as designing a human interface with control switches and and LCD.

As a proof of concept the idea of system would be to control the brightness of 2 lights, one via a manual adjust, which would have preset values for brightness, and the other would be adjusted automatically dependant on the ambient light.  The lights in this case would be LED’s not ideal but serve the purpose for the demonstration, their brightness would be adjusted via PWM (Pulse Width Modulation).  An LDR (Light Dependant Resistor) would be used to detect the ambient light, and interfaced to the ADC (Analog to Digital Converter) on MSP430.  There would also be a 16×2 LCD interfaced in parallel mode to the MSP430 launchpad.  A basic block diagram of the system can be seen below.

MSP430 State Machine Project Tutorial C Code

Hardware

I will start by over viewing the connections to the MSP430.  The MSP430G2231 was originally used but as the project went on, memory became an issue as did the number of available GPIO ports, so the MSP430G2432 was an obvious choice as the memory is extended from 2kb to 8kb and an extra 6 GPIO.  The image below illustrates the pinout configuration for the launchpad.

MSP430 State Machine Project Tutorial C Code

16×2 LCD

As can be seen in the pinout configuration the LCD uses 6 pins, the pins for the LCD are based around an external tutorial which includes all the necessary C code.  This tutorial can be found by following this link.

This is a 16*2 dot matrix character display, using the Hitachi HD44780U controller. This controller has been around for many years, which means there is a wealth of information. There are several websites with API’s aiding in the interfacing of the LCD to a MSP430, along with the one previously mentioned.
The LCD uses an 8 bit parallel interface, but fortunately can also be used in 4 bit mode which still requires 6 pins.
It was also necessary to provide the LCD with a 5V supply and a potentiometer to adjust the contrast on the display, this was a very simple circuit and was constructed on a piece of vero board.

The C code for the LCD has been placed into a library in the final state machine code, all the code can be downloaded as a zip file at the end of this article.

Tack Switch Board

The tack switch boarded consisted of 3 tack switches and some debounce components constructed on a piece of vero board.  When a switch is depressed, the connected GPIO pin on the launchpad will be pulled low.  The 4th button used was S2 on the launchpad board, this served as an on/off button.  An image of the tack switch circuit and also the finished vero board can be seen below.

MSP430 State Machine Project Tutorial C Code

MSP430 State Machine Project Tutorial C Code

LDR and Interface Circuit

The LDR are non linear devices which makes them less than ideal for detecting small changes in light and then interfacing to the ADC of a microcontroller.  They are found in many devices, a common use is in garden solar lights that switch on when a preset lux level is reached, in this case the LDR is being used as a simple switch.  For the purpose of this project the output from the LDR would need to be converted to suit ADC on MSP430 launchpad.  The ADC has an input range from 0V to 3V.  The circuit was first simulated in OrCad, it incorporates 3 opamps and 2 adjustable potentiometers so fine adjustments can be made depending on the ambient light conditions.  There was also a small amount of linearisation added to the LDR as a result of this circuit design.  The final interface circuit schematic can be seen below.

MSP430 State Machine Project Tutorial C Code

LDR Circuit final construction on vero board can be seen in the next image.

MSP430 State Machine Project Tutorial C Code

LED Demo Board

The LED board is a very simply construction, using a pair of transistors acting as switches to drive the LED’s.  The circuit schematic and final board construction can be seen in the following 2 images.

MSP430 State Machine Project Tutorial C Code

 

MSP430 State Machine Project Tutorial C Code

So the final system looks like this, a bit ‘Heath Robinson’ but proof of concept remember!

MSP430 State Machine Project Tutorial C Code

I had intended this to be a one page article but the images have extended it more than I anticipated, so in part 2 I will cover the state machine structure and C programming 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.