Category Archives: MSP430

MSP430

MSP430 Timer PWM Tutorial

 

In this MSP430 timer PWM tutorial the basic workings of the on board timer peripheral will be explained, along with some C code examples which can be downloadable at the end of the tutorial.  Additionally the video below demonstrates the examples ‘A picture paints a thousand words, a video displays a thousand pictures’.

The MSP430G2253 will be used as it has two timers opposed to the MSP430G2231 which only has one timer, this will allow for different examples to be shown.  All the code in the MSP430 timer tutorial is written in Code Composer Studio (CCS) v5.5.  As the tutorial will be using the MSP430G2253 as the test microcontroller, downloading the datasheet for this maybe of use and can be found 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.

The MSP430G2253 has two 16 bit timers, Timer0 and Timer1 both are Timer_A variants with three capture/compare registers.  The MSP430 family guide lists two types of 16 bit timer, Timer_A and Timer_B.  For the most part they are very similar except Timer_A has up to three capture/compare registers, were as Timer_B has up to seven.  The MSP430G2253 also has a watchdog timer which can be used detect system malfunctions, but will not be covered in this tutorial. The feature list for Timer_A is shown below:

  • Asynchronous 16 bit timer/counter with four operating modes
  • Selectable configurable clock source
  • Up to three configurable counter/compare registers
  • Configurable as outputs for PWM
  • Asynchronous input and output latching
  • Interrupt vector register for fast decoding of all Timer_A interrupts

Asynchronous 16 Bit Timer

The 16 bit timer increments or decrements a value from the Timer_A register (TAR), every rising edge of the clock pulse.  The TAR value can be read or written with software, and an interrupt can be enabled to generate when it overflows.  If the timer is run asynchronous to the CPU clock, any reading from the TAR should occur while the timer is not running, as the result is likely to be unpredictable.

The four modes of operation for the timer are:

Stop – The timer is stopped

Up – The timer counts from zero to the value of TACCR0

Continuous – The timer counts from zero to 0FFFFh

Up/Down – The timer repeatedly counts from zero up to the value of TACCRO (+1) and then back down to zero.

Configurable Clock Source

The clock source for the timer can be from ACLK, SMCLK or from an external source via TACLK or INCLK (Device specific).  The clock source selected can be then divided by 1, 2, 4 or 8.

Counter Compare Registers

The capture/compare blocks inside Timer_A are all identical.  Any of the TACCRx blocks may be used to capture timer data or generate intervals.  When in capture mode the Capture Compare inputs CCIxA and CCIxB, can be connected to external pins or internal signals. They can be configured to capture on a rising, falling or both edges.  The compare mode is used to generate PWM output signals, or interrupts at specific time intervals.  Each capture/compare block has an output unit, which is used to to generate output signals like PWM.

Interrupt Vector Register

The Timer_A module has two interrupt vectors linked to it: TACCR0 interrupt vector TACCR0 Capture Compare Interrupt Flag (CCIFG) and Timer_A Interrupt Vector Register (TAIV) for all CCIFG flags and Timer_A Interrupt Flag (TAIFG).  The TACCR0 CCIFG has the highest priority of all the interrupts for Timer_A.  The TAIV is used to prioritise and combine the TACCR1 CCIFG, TACCR2 CCIFG and TAIFG flags.

Timer_A Registers

The Timer_A module is configured with software by setting the bits inside the various registers, which alter the timers parameters.  The image below list the various registers associated with the Timer_A module.

MSP430 Timer Tutorial Guide Timer_A Registers

Timer_A Control

This register determines where the clock is sourced from and how the clock is divided either by 1, 2, 4 or 8.  The timers control mode is also set here, whether it’s stopped, counts up, continuous or up/down.  The TAR , clock divider and count direction can also be reset with the TACLR bit being set.  Lastly the Timer_A interrupt enable/disable and interrupt pending flag are also found here.  A typical command for this register looks like this TA0CTL = TASSEL_2 + MC_1; or TA1CTL = TASSEL_2 + MC_1;

Timer_A Counter

The Timer_A registers or TAR holds the count of Timer_A.  A command using this register could look something like this depending on your application TAR = 4500-1;

Timer_A Capture/Compare 0

The Timer_A capture/compare register 0 or TACCR0, is used in two cases.  In compare mode this holds the value for comparison with the timer value in the TAR.  When in capture mode, the value in the TAR is copied into the TACCR0 when a capture is performed.  An example of the register code would be as follows TA0CCR0 = 200-1;. 

Timer_A Capture/Compare Control 0

The Timer_A capture/compare control register 0 or TACCTL0, is a 16 bit register used to determine how the TACCR0 is set-up.  The register controls whether the timer module is set to capture or compare.  The trigger edge for the capture mode can be set, as well as where the source originates from, either internal or external.  Asynchronous or synchronous operation can determined, as well as synchronised capture or compare input.  There are various output modes, which are used to determine the operation of PWM signals for example.  Also this register allows interrupts to enabled for the timer module.  An example of the register code would be as follows TA0CCTL0 = OUTMOD_7 + CCIE;.

Timer_A Capture/Compare 1

The Timer_A capture/compare register 1 or TACCR1.  Has the same operation as TACCR0.  An example of the register code would be as follows TA0CCR1 = 200-1;. 

Timer_A Capture/Compare Control 1

The Timer_A capture/compare control register 1 or TACCTL1, is a 16 bit register used to determine how the TACCR1 is set-up.  Has the same operation as TACCTL0.  An example of the register code would be as follows TA0CCTL1 = OUTMOD_7;.

Timer_A Capture/Compare 2

The Timer_A capture/compare register 2 or TACCR2.  Has the same operation as TACCR0.  An example of the register code would be as follows TA0CCR2 = 200-1;. 

Timer_A Capture/Compare Control 2

The Timer_A capture/compare control register 2 or TACCTL2, is a 16 bit register used to determine how the TACCR2 is set-up.  Has the same operation as TACCTL0.  An example of the register code would be as follows TA0CCTL2 = CCIE;. 

Timer_A Interrupt Vector

The Timer_A interrupt vector register or TAIV, is used to prioritise and combine the remaining interrupt flags.  When reading the TAIV it will give the value of the current interrupt, as well as clearing that interrupts flag.

 

Timer Example 1

This first example demonstrates the use of one timer, which is used to flash the MSP430G2253 Launchpad LED’s on and off.  The code snippet below only shows the timer set-up and the interrupt handler, as these are the most relevant parts.

The code is fairly short and quite simple to walk through, in line 5 we first load the TA0CCR0 with the value 3000.  Line 6 turns the interrupt on for the TA0CCR0 when it overflows.  Line 7 sets the clock source to ACLK (12kHz) and the counter to count-up mode.  So the interrupt is generated every 250mS approximately.  Line 9 sets the MSP430 to low power mode and enables interrupts.  Lines 12 to 22 are the interrupt handler for Timer0_A, this interrupt automatically clears when called.  Inside the interrupt handler, the variable Control is used to ensure the green LED flashes once for every time the red LED flashes four times.  The closing brace marks the end of the main function.

Example 1 Code

The link below contains the zip file with the full example 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.

MSP430 Timer Tutorial Timer Example 1

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.

Timer Example 2

The second example demonstrates the use of two timers, which are used to output PWM signals on GPIO pins P1.2 and P2.1.  The timer set-up code and also the GPIO set-up code is shown below.  The clock was set to 8MHz for this example.

Before walking through the code, the image below is extracted from the MSP430G2253 datasheet, this shows GPIO pin P1.2 and it’s functions.  The line which is highlighted demonstrates P1.2 can be used as an input and output for Timer0_A.

MSP430 Timer Tutorial GPIO Pin Functions

Walking through the code starting with line 5, this sets GPIO pin P1.2 as an output.  Line 6 selects the function for GPIO pin P1.2, and in this case it is used for PWM.  Lines 7 and 8 perform the same operation, except they are for GPIO pin P2.1.  line 11 the TA0CCR0 is loaded with 200, this sets the PWM frequency to 40kHz approximately.  Line 12 sets the output mode to reset/set.  Line 13 sets the count value of TA0CCR1, which determines the PWM duty cycle, in this case 50%. Line 14 sets the clock used by the TA0CTL to SMCLK and the counter to count-up mode.  Lines 17 to 20 set-up Timer1_A in the same way as Timer0_A, except the frequency is set to 8kHz approximately.

The image below shows a capture from the oscilloscope for this code, GPIO pin P1.2 is shown on channel 1 and P2.1 is shown by channel 2.

MSP430 Timer Tutorial Dual PWM example

Example 2 Code

The link below contains the zip file with the full example 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.

MSP430 Timer Tutorial Timer Example 2

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.

Timer Example 3

The third example demonstrates the use of two timers, using PWM generated by Timer0_A and a timed interrupt on Timer1_A to alter the duty cycle.  The PWM output is configured to output on GPIO pin P1.6.  As with the previous code examples, only the timer set-up code is shown. The clock was set to 1MHz for this example.

Lines 5 to 8 in this example are almost identical to lines 5 to 8 in the example 2 code.  The main difference is the PWM frequency is set to 1kHz (clock set to 1MHz) and the duty cycle is initially set to 0.1%.  Lines 11 to 13 set-up Timer1_A, this has a count of 4000 so generates an interrupt every 4mS.  Line 15 sets the MSP430 to low power mode and enables interrupts.

Lines 18 to 25 are the interrupt handler for Timer1_A, as with the first example this interrupt automatically clears when called.  Inside the interrupt the value stored in TA0CCR1 is added to the variable IncDec_PWM which is multiplied by 2 every time the interrupt handler is called.  IncDec_PWM is a global variable and assigned the value 1.  This equates to the value in TA0CCR1 being incremented or decremented by 2, therefore the duty cycle changes by 2 or (0.2%) every time the interrupt handler is called.  This equates to a transition time of approximately two seconds from high to low and low to high.  The final if statement inside the interrupt handler reverses the direction of the duty cycle, causing the LED to decrease in brightness until a value greater than 998 is reached, and increase in value when a value less than 2 is reached.

Example 3 Code

The link below contains the zip file with the full example 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.

MSP430 Timer Tutorial Timer Example 3

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.

There is also one more additional example for the timer, which demonstrates the capture mode.  This is actually part of a another tutorial based around switch debouncing, the timer is used to capture the undesired pulses generated by a noisy switch.  You can find the additional code by browsing to the end of my Switch Debouncing Tutorial Pt/1.

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.

Microcontroller GPIO Protection Tutorial

Microcontroller GPIO protection is an essential element of any circuit design.

GPIO ports generally have maximum voltage and current ratings, if these are exceeded it can result in the microcontroller being damaged or completely destroyed.

Therefore it is important to use external circuitry to protect the ports from excessive voltage, or excessive current being sourced from a pin.

The principles used in this post are for the MSP430G2231, however they can be applied to Arduino, Raspberry Pi and other microcontrollers, by taking into account the voltage and current specifications for each microcontroller, then changing the zener diode and resistor value accordingly.

Over Voltage Protection

This is fairly easy to achieve with some basic external components, to explain this a simple example will be used based on the Texas Instruments MSP430G2231.  The maximum ratings for the integrated circuit need to be determined, this information can be obtained from the devices datasheet, MSP430G2231 datasheet can be found here.

The image below shows an extract from the MSP430G2231 datasheet, the maximum voltage rating can clearly be seen as 4.1V, there is also a cautionary warning which should be noted.

Microcontroller GPIO Protection Tutorial

Now lets assume we are using one of the ports as an ADC input for a sensor, the voltage range for the ADC input on the MSP430G range is 0V to 3V.  So now we know the operating range and the maximum voltage, we can design some simple interface circuitry to ensure the microcontroller is protected.

The schematic diagram below shows a basic circuit which could be used to protect against over voltage.

The main components here that provide the over voltage protection, are D1 and R3.  D1 is a 3V3 Zener diode, which clamps the voltage if it exceeds 3.3V.  R3 has a dual purpose firstly if the voltage exceeds 3.3V the excess voltage will be dropped across the resistor, as the diode will have 3.3V across it i.e. over voltage is 5V, R3 will have 1.7V across it and D1 will have the remaining 3.3V across it.  R3 also acts as a current limit resistor, and Ohm’s Law can be used to calculate the maximum current with a known voltage.  Something to note here is the zener diode will take approximately 5mA of current in normal operation, this is less than ideal for battery operated applications.

Microcontroller GPIO Protection Tutorial

The other components R1, R2 and the opamp are here to simulate a dummy sensor input.  However by designing a circuit using a single rail to rail opamp, the output of the opamp cannot exceed it’s rail to rail voltage, so with a supply of 0 to 3.3V the output cannot exceed 3.3V.  Therefore using a rail to rail opamp in a configuration similar to the one shown, can eliminate the need for the zener diode altogether.

Over Current Protection

Over current protection as with over voltage protection, is quite simple to achieve.  Again it is best to consult the datasheet for the device to determine the current ratings, as can be seen below in an extract from the MSP430G2231 datasheet.

Microcontroller GPIO Protection Tutorial

So the maximum recommended current that can be sourced or sunk is 6mA, and the total maximum current for all ports is 48mA (MSP430G2231 has 10 GPIO pins in total).  There are some further graphs shown in the datasheet, these show that it is possible to source 8mA from a GPIO pin, but the voltage on this pin will drop to approximately 2.7V as a result of the high current.  I would not recommend placing a load which draws 8mA, especially not on more than 1 pin, I always try to keep the current drawn from a GPIO around 1mA in most circumstances.  We can also see the voltage from the GPIO pins will be 3V.

By placing a resistor directly connected to the GPIO pin before any additional circuitry, we can limit the amount of current being sourced from the pin.  This resistor can be calculated by taking the 3V provided by the GPIO pin, lets assume we want to limit the current to 1mA, this gives us a value of 3kΩ the nearest standard value (going up) is therefore 3.3kΩ. This calculation can also be reversed and used to prevent excessive currents being sunk by the microcontroller.

3V rated at 1mA is not going to give much scope for driving external circuitry i.e. an LED or a relay, so it is best to use this to drive a transistor, using the transistor as a switch.

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.