Translate
Showing posts with label mspgcc. Show all posts
Showing posts with label mspgcc. Show all posts
Sunday, July 15, 2018
MSP430f169 LCD development environment
Until now I always developed code for the Olimex board MSP430F169 LCD using an open source compiler (GNU) and using a parallel port->JTAG adapter to program the board and do some debug.
That requires a computer with parallel port.
The goal of this article is to see if is possible to use an USB->JTAG adapter or using the Spy-by-wire connection.
Saturday, July 14, 2018
MSP430 - Reading a digital encoder
Already exists a lot of documentation about this, but just for fun, I started from the scratch and did some analysis.
I did find very interesting issues about this "common" component.
I did find very interesting issues about this "common" component.
Friday, March 2, 2018
A personal CI system
In this article I'm describing how to set up and configure a basic CI (Continuos Integration) system that can be used for many things, based on an open source program called Jenkins.
Of course, for my projects to set up a CI to build them is just little bit overshooting, but surely is interesting and fun.
Sunday, April 19, 2015
MSP430 - generating a PWM signal
This article discuss some basic ways to generate a PWM signal using a MSP430.
A PWM signal is a digital signal with fixed frequency but varying duty cycle.
If the duty cycle of the PWM signal is varied with time, and the PWM signal is filtered, the output of the filter will be an analog signal.
There are mostly 3 ways to generate a PWM signal using a MSP430 :
Theory of operations
A PWM signal is a digital signal with fixed frequency but varying duty cycle.
If the duty cycle of the PWM signal is varied with time, and the PWM signal is filtered, the output of the filter will be an analog signal.
There are mostly 3 ways to generate a PWM signal using a MSP430 :
- loop
- timer
- interrupt
Loop
The easiest way to generate a PWM signal is to create an infinite loop and inside the loop, set a I/O pin ON or OFF, using a counter to determine when to change the ON vs. OFF time, comparing it to a "dutycycle" value. Also in the loop must be present a delay to determine the frequency of the signal.
The pro is obvious, is really easy to generate a PWM signal in this way.
But there are big cons with this method.
Let see some of them:
Two MSP430 subsystems are involved in generating a PWM signal with the timer, the clock subsystem and the timer subsystem.
The output pin of the PWM signal, is directly connected to the timer.
Once programmed the timer, the generation of the PWM signal doesn't require any additional software.
In this way, a timer is still involved, but instead to generate the PWM signal, it generate interrupts.
Any time the interrupt is fired, a piece of software provide to change the state of an I/O pin depending some counter values compared with a threshold, generating in this way the PWM signal.
The frequency of the signal is determined by the timer setting and the precision is depending by the number of "steps" of the counter.
For example, if we want a 100 Hz signal, we need to set up an interrupt timing "at least" set to fire every 1/(100 Hz * 2) i.e. 0.005 seconds.
It means that every 0.005 seconds we have an interrupt and change the state of the output, obtaining a square wave of 100 Hz.
But we want to control the duty cycle, and so we need to have a smaller interrupt time.
Let say we want to divide our 100 Hz in 10 "steps", so we need to set the timer to fire every 1/(100 Hz/10) = 0.001 seconds or 1 ms.
Every ms we have an interrupt and then we decide if having the output ON or OFF.
Our period is so divided in 10 1 ms steps, i.e. 0.001 * 10 = 0.1 sec. that converted is 100 Hz.
But only 10 steps is not good, so better to split the time more, at least 50 or 100.
Of course we have some limits depending the input clock and how long the interrupt function requires to operate.
So we have to play with the clock in order to have the micro go faster and really optimize the interrupt function.
The interrupt function must be executed in a time much shorter than 1 ms, and we need to decide if the output is high or low depending a counter value in that timeframe.
Here a flow chart to better explain the basics.
On the left a flow of the main code.
It simply initialize the system and enter in an infinite loop. Eventually is possible to have code to perform settings/change of the parameters in the loop.
On the right the flow of the timer interrupt.
Every time the interrupt is fired, it uses a counter compared with a threshold to determine if turn the signal ON or OFF and then update the counter restarting the timer.
To measure exactly how long on average the function last, a debug signal is used.
The code turn this debug signal ON just after started the interrupt and OFF just before to exit.
With an oscilloscope is then possible to measure how long the signal remain ON. That more or less would be the time used by the interrupt function.
Here a couple of pictures from my oscilloscope during some tests.
The pro is obvious, is really easy to generate a PWM signal in this way.
But there are big cons with this method.
Let see some of them:
- all the resources of the processor are devoted to generate the signal
- is extremely difficult to calculate a specific timing
- any extra operation added in the loop go to alter the frequency of the generated signal
- if interrupts are used the result signal is extremely instable
So the loop is not really something to consider for real use.
Timer
The second way to generate a PWM signal is to use a timer.
The MSP430 timer is capable to generate a PWM signal, it means that is possible to program a MSP430 timer specifically for the purpose to generate a PWM signal.
Because the signal in the end is generated by a piece of hardware, the result is extremely stable and precise.
Pro:
- very stable PWM signal
- extremely precise timing is possible
Cons:
- the timer is devoted only to the PWM signal generation since the I/O pin is connected to it
- only 1 PWM signal per timer is available
- setting up the timer can be complicated
Interrupt
The third alternative is to soft-generate the PWM, like in the loop solution, but using a timer interrupt instead a deal loop.
A generic timer interrupt is generated and every time the interrupt is fired, a function handle one or more I/O pins to generate the PWM signal.
Pro:
- stable PWM signal
- precise timing (but less than the full timer solution)
- possibility to have more than one PWM signals
- possibility to use the timer resource for other purposes
- easy to calculate the time
Cons:
- limited timing range
PWM generated by a timer
The output pin of the PWM signal, is directly connected to the timer.
Once programmed the timer, the generation of the PWM signal doesn't require any additional software.
Clock
The timer needs to be "fed" with a clock and there are different choices, depending the time required and the precision needed.PWM using a generic time interrupt
In this way, a timer is still involved, but instead to generate the PWM signal, it generate interrupts.
Any time the interrupt is fired, a piece of software provide to change the state of an I/O pin depending some counter values compared with a threshold, generating in this way the PWM signal.
The frequency of the signal is determined by the timer setting and the precision is depending by the number of "steps" of the counter.
For example, if we want a 100 Hz signal, we need to set up an interrupt timing "at least" set to fire every 1/(100 Hz * 2) i.e. 0.005 seconds.
It means that every 0.005 seconds we have an interrupt and change the state of the output, obtaining a square wave of 100 Hz.
But we want to control the duty cycle, and so we need to have a smaller interrupt time.
Let say we want to divide our 100 Hz in 10 "steps", so we need to set the timer to fire every 1/(100 Hz/10) = 0.001 seconds or 1 ms.
Every ms we have an interrupt and then we decide if having the output ON or OFF.
Our period is so divided in 10 1 ms steps, i.e. 0.001 * 10 = 0.1 sec. that converted is 100 Hz.
But only 10 steps is not good, so better to split the time more, at least 50 or 100.
Of course we have some limits depending the input clock and how long the interrupt function requires to operate.
So we have to play with the clock in order to have the micro go faster and really optimize the interrupt function.
Here a flow chart to better explain the basics.
On the left a flow of the main code.
It simply initialize the system and enter in an infinite loop. Eventually is possible to have code to perform settings/change of the parameters in the loop.
On the right the flow of the timer interrupt.
Every time the interrupt is fired, it uses a counter compared with a threshold to determine if turn the signal ON or OFF and then update the counter restarting the timer.
To measure exactly how long on average the function last, a debug signal is used.
The code turn this debug signal ON just after started the interrupt and OFF just before to exit.
With an oscilloscope is then possible to measure how long the signal remain ON. That more or less would be the time used by the interrupt function.
Here a couple of pictures from my oscilloscope during some tests.
![]() |
| Debug signal in the timer interrupt - DCO set for 16 Mhz selection. The irregular wave indicates different execution timing, approx 3.5 us average execution time |
![]() |
| PWM signal generated, 10 steps, approx 10Khz frequency - DCO set for 16 Mhz selection |
Saturday, April 11, 2015
MSP430 - setting up the clock
All the microcontrollers needs a clock signal to work.
The MSP430 family is not an exception and actually there are many choices when we talk about the clock.
It is important ALWAYS to have handy the LATEST MSP430 family document and the specific chipset documentation, for example the MSP430F20x2 family (an entry level).
Some schematics/pictures shown here are copied from the MSP430 family document.
Let see the MSP430 clock system
The first thing that come up from the picture above, is that we have three different clock signal generated:
The most important signal generated is the MCLK, the Main System Clock.
As the name imply, this is the clock signal used by the core of the MSP430 chipset, the CPU and basic signals (memory bus/I/O bus/ecc.).
The SMCLK signal is the Sub system clock.
It is normally connected to the peripherals, like the Timer, Watchdog and every peripheral that can require a clock.
The ACLK is an Auxiliary clock.
Sometime it can be necessary to have peripherals using different clocks. For example a UART can require a special timing if compared with the other peripherals or a specific timer needs a low and precise timing.
The Auxiliary clock cannot use the DCO oscillator. It can use only the crystal oscillator.
When the chip is turned ON, i.e. after a hard reset, the clock subsystem is set to generate an approx. 800 kHz signal on the MCLK and SMCLK pin.
This allows the chipset to be able to start to execute instructions. A default clock mechanism must be present otherwise it would be impossible to "program the clock subsystem" if no instructions can be executed.
By default, the source for the SMCLK is the same of the MCLK, the DCO generator.
There are four possible sources for the clock:
This clock runs around 12 kHz and it can be used when the chipset is put in low power mode.
It is reasonably precise.
If the precision of the clock is not an issue, there is no need to worry about using calibrated values for the DCO.
Because the tolerance of the components, each MSP430 needs a different set of resistor values to set up the clock for specific frequencies.
It would be a very time consuming task to use external resistors, figuring out what is the correct value for a specific frequency, but fortunately TI though about that.
Every MSP430 chip has a table containing the calibrated (values) for the internal resistor array.
Is enough to read the table and acquire the value for the setting needed.
It is also possible to re-write the table for specific needs, as described in this article.
To determine what setting is needed for specific frequency, requires to study the specific chipset datasheet.
For example, for the MSP430f2012 the datasheet has a table indicating what frequency, with quite a tolerance, correspond to different settings of some specific registers.
Looking at the table, the frequencies generated by the DCO have a quite big tolerance.
This why it could be necessary to re-calibrate the DCO values if a more precise frequency is needed.
As the name imply, these circuits allows to generate a frequency dependent by a crystal.
They are less flexible than the DCO but they can be very precise and stable.
At least one crystal oscillator is present on every MSP430 chipset.
Here some examples about how is possible to set up the MSP430 clock.
The examples are using the MSP430F2012.
The default setting is for a middle/low frequency, around 800kHz (800kHz to 1.5 MHz), but the DCO can reach the 16 MHz in some chipsets.
Unless specific needs, is not a good idea to set the DCO for the maximum frequency.
Mainly because more fast the chip run, more current use and more heat is generated, but also because higher is the generated frequency, lower is the stability and precision.
Is a good idea to use a an external crystal if high speed and precision is required.
To determine what frequency to use it is mandatory to read the data sheet of the specific component, because each device has an internal table with some values to use for the DCO.
Said so, a typical DCO setting for about 8 Mhz is this one.
DCOCTL = 0x60;
BCSCTL1 = 0xB3;
BCSCTL2 = 0x00;
BCSCTL3 = 0x0C;
The DCOCTL (Digitally Controlled Oscillator Control register) after a reset is set for:
The BCSCTL1 register (Basic Clock Control Register 1) after the reset has the value of 84 hex (1000 0100), i.e. :
When is necessary to count time for a clock, timer or watch, normally it is used a crystal of 32768-Hz (3.2768 kHz) because is easy to divide this frequency to obtain 1 second.
Of course we don't want the main clock system signal be so slow, this is the typical setting for the ACLK signal.
Let see what we need to be aware and what to do to have the basic clock set on that.
First of all some hardware is required.
Then the software.
We need to set up some chipset registers in order to have the clock up and running.
BCSCTL1 |= DIVA_3; /* ACLK/8 */
BCSCTL3 |= XCAP_3; /* 12.5pF cap */
Let see some details.
The BCSCTL1 register (Basic Clock Control Register 1) after the reset has the value of 84 hex (1000 0100), i.e. :
The MSP430 family is not an exception and actually there are many choices when we talk about the clock.
It is important ALWAYS to have handy the LATEST MSP430 family document and the specific chipset documentation, for example the MSP430F20x2 family (an entry level).
Some schematics/pictures shown here are copied from the MSP430 family document.
Let see the MSP430 clock system
The first thing that come up from the picture above, is that we have three different clock signal generated:
- MCLK
- SMCLK
- ACLK
MCLK
The most important signal generated is the MCLK, the Main System Clock.
As the name imply, this is the clock signal used by the core of the MSP430 chipset, the CPU and basic signals (memory bus/I/O bus/ecc.).
SMCLK
The SMCLK signal is the Sub system clock.
It is normally connected to the peripherals, like the Timer, Watchdog and every peripheral that can require a clock.
ACLK
The ACLK is an Auxiliary clock.
Sometime it can be necessary to have peripherals using different clocks. For example a UART can require a special timing if compared with the other peripherals or a specific timer needs a low and precise timing.
The Auxiliary clock cannot use the DCO oscillator. It can use only the crystal oscillator.
Clock sources
When the chip is turned ON, i.e. after a hard reset, the clock subsystem is set to generate an approx. 800 kHz signal on the MCLK and SMCLK pin.
This allows the chipset to be able to start to execute instructions. A default clock mechanism must be present otherwise it would be impossible to "program the clock subsystem" if no instructions can be executed.
By default, the source for the SMCLK is the same of the MCLK, the DCO generator.
There are four possible sources for the clock:
- Very low frequency clock
- DCO
- Crystal oscillator 1
- Crystal oscillator 2
Some chipset could have only one crystal oscillator, so is important to know what chipset you are using.
Very low frequency clock
This clock runs around 12 kHz and it can be used when the chipset is put in low power mode.
It is reasonably precise.
DCO
The DCO (Digitally Controlled Oscillator) is the default source of clock for the MCLK and SMCLK.
As the name imply, it is possible to set up this oscillator simply writing the setting in some registers.
Different frequencies can be generated simply changing some register settings.
There are Pro and Cons using the DCO.
There are Pro and Cons using the DCO.
Pro:
- flexible frequency generator
- doesn't require ANY external hardware
- fast
Cons:
- less stable and precise than crystal
- it require a tuning procedure
DCO calibrated values
The DCO uses resistors, external or internal, to set up a specific frequency.If the precision of the clock is not an issue, there is no need to worry about using calibrated values for the DCO.
Because the tolerance of the components, each MSP430 needs a different set of resistor values to set up the clock for specific frequencies.
It would be a very time consuming task to use external resistors, figuring out what is the correct value for a specific frequency, but fortunately TI though about that.
Every MSP430 chip has a table containing the calibrated (values) for the internal resistor array.
Is enough to read the table and acquire the value for the setting needed.
It is also possible to re-write the table for specific needs, as described in this article.
To determine what setting is needed for specific frequency, requires to study the specific chipset datasheet.
For example, for the MSP430f2012 the datasheet has a table indicating what frequency, with quite a tolerance, correspond to different settings of some specific registers.
Looking at the table, the frequencies generated by the DCO have a quite big tolerance.
This why it could be necessary to re-calibrate the DCO values if a more precise frequency is needed.
Crystal Oscillators
As the name imply, these circuits allows to generate a frequency dependent by a crystal.
They are less flexible than the DCO but they can be very precise and stable.
At least one crystal oscillator is present on every MSP430 chipset.
Programming examples
Here some examples about how is possible to set up the MSP430 clock.
The examples are using the MSP430F2012.
Select DCO for ~8 MHz
After a reset, the main source for the clock, especially MCLK, is the DCO.The default setting is for a middle/low frequency, around 800kHz (800kHz to 1.5 MHz), but the DCO can reach the 16 MHz in some chipsets.
Unless specific needs, is not a good idea to set the DCO for the maximum frequency.
Mainly because more fast the chip run, more current use and more heat is generated, but also because higher is the generated frequency, lower is the stability and precision.
Is a good idea to use a an external crystal if high speed and precision is required.
To determine what frequency to use it is mandatory to read the data sheet of the specific component, because each device has an internal table with some values to use for the DCO.
Said so, a typical DCO setting for about 8 Mhz is this one.
DCOCTL = 0x60;
BCSCTL1 = 0xB3;
BCSCTL2 = 0x00;
BCSCTL3 = 0x0C;
- Frequency select middle range (value from 0 to 7, set to 3)
- Modulator section = 0
The setting to 0x60, according to the table above, set the frequency between 6 MHz to 9MHz.
The BCSCTL1 register (Basic Clock Control Register 1) after the reset has the value of 84 hex (1000 0100), i.e. :
- Crystal Oscillator 2 disabled (OFF)
- Crystal low frequency mode
- ACLK signal divided by 1 (i.e. no division)
- DCO Resistor select = 4 (nominal frequency for DCO)
After the selection (BCSCTL1 = 0xB3 - 1011 0011):
- Crystal Oscillator 2 disabled (OFF)
- Crystal low frequency mode
- ACLK signal divided by 8
- DCO Resistor select = 3
The BCSCTL2 after the reset is set to zero and no change is made, meaning:
- source for MCLK = DCO
- no divider for MCLK (divider = 1)
- source for SMCLK = DCO
- no divider for SMCLK (divider = 1)
- use internal resistor for frequency selection
The BCSCTL3 after the reset is set to zero:
- Crystal oscillator 2 range 0 to 4 MHz (not used anyway)
- 3.2768 kHz crystal selected (not used anyway)
- 6 pf capacitor selected for crystal (not used anyway)
After the writing (0x0C - 0000 0011)
- Crystal oscillator 2 range 0 to 4 MHz (not used anyway)
- 3.2768 kHz crystal selected (not used anyway)
- 1 pf capacitor selected for crystal (not used anyway)
Note that the first two bits are only reading.
Classic watch generator
When is necessary to count time for a clock, timer or watch, normally it is used a crystal of 32768-Hz (3.2768 kHz) because is easy to divide this frequency to obtain 1 second.
Of course we don't want the main clock system signal be so slow, this is the typical setting for the ACLK signal.
Let see what we need to be aware and what to do to have the basic clock set on that.
First of all some hardware is required.
- connect the crystal
A 32768-Hz crystal need to be connected to the chipset (pin XIN and XOUT)
Usually this require also some capacitors other the crystal, but the chipset has them inside - setting the pins
Because the crystal is physically connected to some chip pins, we need to program the I/O subsystem accordingly.
i.e. we need to program the pins connected to the crystal to be rerouted to the clock subsystem.
By default, i.e. after a reset, assuming we are using an MSP430F2012, the XIN and XOUT pins are enabled, i.e. by default these pins are used for the crystal oscillator 1.
So no specific programming on the I/O subsystem is necessary to use a crystal.
Then the software.
We need to set up some chipset registers in order to have the clock up and running.
BCSCTL1 |= DIVA_3; /* ACLK/8 */
BCSCTL3 |= XCAP_3; /* 12.5pF cap */
Let see some details.
The BCSCTL1 register (Basic Clock Control Register 1) after the reset has the value of 84 hex (1000 0100), i.e. :
- Crystal Oscillator 2 disabled (OFF)
- Crystal low frequency mode
- ACLK signal divided by 1 (i.e. no division)
- Resistor select = 4 (nominal frequency for DCO)
So the register controls different parts of the clock subsystem.
The line BCSCTL1 |= DIVA_3; set only the DIVA bits, changing the original value from 0 to 3, setting the divisor of the ACLK signal to 8. i.e. the generated frequency of the ACLK will be divided by 8.
The BCSCTL3 register after the reset has the value of 00x (the first two bits are to indicate some fault condition so they can have random setting after a reset).
i.e.:
- Range for Crystal oscillator 2 : 0 to 1 MHz crystal
- 3.2768 kHz crystal on oscillator 1
- 1 pf internal capacitor
The bit 2 and 3 select an internal capacitor to be used with an external crystal.
In our example, we use a 12.5 pF internal capacitor so the selection is 3 (11) for these bits, forced with the line : BCSCTL3 |= XCAP_3;
This is enough to have the ACLK signal generated.
The ACLK signal will have a 32768 Hz / 8 = 4096 Hz.
The ACLK signal will have a 32768 Hz / 8 = 4096 Hz.
This value is easily used by the timer in order to generate precise and low periods.
Saturday, March 14, 2015
MSP430 GCC compiler
For the MSP430 family there are many different compiler out there.
One of the most used, especially on Linux machines, is the mspgcc.
This article explain how to install one of the versions of this compiler.
One of the most used, especially on Linux machines, is the mspgcc.
This article explain how to install one of the versions of this compiler.
Wednesday, November 12, 2014
MSP430 - How to use mspdebug
When using the MSP430 under Linux, in order to load the compiled code with mspgcc, exists a
utility called mspdebug.
Mspdebug is not part of the MSPGCC toolchain, so it must be downloaded and prepared separatedly.
Also the final placement could end not be in the toolchain path but on a more generic one.
Almost every distribution has it, so the easiest way to install it is from there.
In particular must be installed :
Then :
At the end of the process, the mspdebug program will be placed in /usr/local/bin directory.
Connect the LaunchPad to the host USB
Verify that the interface is seen by the system (the entry to check is highlighted) using lsusb.
steve@Oliver3:~$ lsusb
Bus 008 Device 023: ID 0781:a7c1 SanDisk Corp.
Bus 008 Device 001: ID 0000:0000
Bus 007 Device 018: ID 0451:f432 Texas Instruments, Inc.
Bus 007 Device 016: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Bus 007 Device 015: ID 06cd:0121 Keyspan USA-19hs serial adapter
Bus 007 Device 014: ID 17d0:0116
Bus 007 Device 003: ID 0409:0058 NEC Corp. HighSpeed Hub
Bus 007 Device 001: ID 0000:0000
Bus 005 Device 002: ID 04a9:2206 Canon, Inc. CanoScan N650U/N656U
Bus 005 Device 001: ID 0000:0000
Bus 004 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 004 Device 001: ID 0000:0000
Bus 003 Device 002: ID 138c:0001
Bus 003 Device 001: ID 0000:0000
Bus 002 Device 003: ID 0a81:0205 Chesen Electronics Corp. PS/2 Keyboard+Mouse Adapter
Bus 002 Device 001: ID 0000:0000
Bus 006 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000
Unless enabling the USB to a specific user, you need to be superuser to run mspdebug.
The interface to use is called rf2500.
Here a session opened with my main host (Ubuntu 8.04 LTS) and LaunchPad :
steve@Oliver3:~$ sudo mspdebug rf2500
MSPDebug version 0.9 - debugging tool for MSP430 MCUs
Copyright (C) 2009, 2010 Daniel Beer < daniel@tortek.co.nz>
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Trying to open interface 1 on 018
Initializing FET...
FET protocol version is 30066536
Configured for Spy-Bi-Wire
Set Vcc: 3000 mV
Device ID: 0xf201
Device: MSP430F2013
Code memory starts at 0xf800
Available commands:
= erase hexout mw read run sym
cgraph gdb isearch opt regs set
dis help md prog reset step
At this point is possible to work on the target, erasing the memory, loading test code and running the debugger.
Here a sequence of operations to debug the code manually, using the debugger.
It is assumed that the mspdebug program is launched from the directory containing the elf file to debug.
The bolded lines are the ones to digit.
Load the program to be debugged in the microcontroller (from mspdebug)
(mspdebug) prog name_program.elf
Start the remote (target) gdb
(mspdebug) gdb
Bound to port 2000. Now waiting for connection...
At this point open a new terminal and go to the directory where the source code and elf are.
The bolded lines are the ones to digit.
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=msp430"...
(gdb)
Attach the debugger to the target
(gdb) target remote localhost:2000
Remote debugging using localhost:2000
0x0000f800 in _reset_vector__ ()
At this point it is possible to debug the code using the gdb commands.
utility called mspdebug.
Installation
Mspdebug is not part of the MSPGCC toolchain, so it must be downloaded and prepared separatedly.
Also the final placement could end not be in the toolchain path but on a more generic one.
Almost every distribution has it, so the easiest way to install it is from there.
Alternatively, is possible to download the code from the mspdebug web site, then be sure to have installed the necessary libraries.
In particular must be installed :
- libncurses5-dev
- zlibc
- zlib1g-dev
- libx11-dev
- libusb-dev
- libreadline5-dev (or libreadline6-dev for newver version of Ubuntu)
Then :
- $ tar xvfz mspdebug-version.tar.gz
- $ cd mspdebug-version
- $ make
- $ sudo make install
At the end of the process, the mspdebug program will be placed in /usr/local/bin directory.
LaunchPad - Use
Preliminary
I'm describing the operations to use mspdebug with the LaunchPad.Connect the LaunchPad to the host USB
Verify that the interface is seen by the system (the entry to check is highlighted) using lsusb.
steve@Oliver3:~$ lsusb
Bus 008 Device 023: ID 0781:a7c1 SanDisk Corp.
Bus 008 Device 001: ID 0000:0000
Bus 007 Device 018: ID 0451:f432 Texas Instruments, Inc.
Bus 007 Device 016: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Bus 007 Device 015: ID 06cd:0121 Keyspan USA-19hs serial adapter
Bus 007 Device 014: ID 17d0:0116
Bus 007 Device 003: ID 0409:0058 NEC Corp. HighSpeed Hub
Bus 007 Device 001: ID 0000:0000
Bus 005 Device 002: ID 04a9:2206 Canon, Inc. CanoScan N650U/N656U
Bus 005 Device 001: ID 0000:0000
Bus 004 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 004 Device 001: ID 0000:0000
Bus 003 Device 002: ID 138c:0001
Bus 003 Device 001: ID 0000:0000
Bus 002 Device 003: ID 0a81:0205 Chesen Electronics Corp. PS/2 Keyboard+Mouse Adapter
Bus 002 Device 001: ID 0000:0000
Bus 006 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000
Unless enabling the USB to a specific user, you need to be superuser to run mspdebug.
The interface to use is called rf2500.
Here a session opened with my main host (Ubuntu 8.04 LTS) and LaunchPad :
steve@Oliver3:~$ sudo mspdebug rf2500
MSPDebug version 0.9 - debugging tool for MSP430 MCUs
Copyright (C) 2009, 2010 Daniel Beer < daniel@tortek.co.nz>
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Trying to open interface 1 on 018
Initializing FET...
FET protocol version is 30066536
Configured for Spy-Bi-Wire
Set Vcc: 3000 mV
Device ID: 0xf201
Device: MSP430F2013
Code memory starts at 0xf800
Available commands:
= erase hexout mw read run sym
cgraph gdb isearch opt regs set
dis help md prog reset step
At this point is possible to work on the target, erasing the memory, loading test code and running the debugger.
For example, just to load a program (ELF format) on the MSP430, simply digit from inside the mspdebug program :
prog name_program.elf
Debugger (manual)
Here a sequence of operations to debug the code manually, using the debugger.
It is assumed that the mspdebug program is launched from the directory containing the elf file to debug.
The bolded lines are the ones to digit.
Load the program to be debugged in the microcontroller (from mspdebug)
(mspdebug) prog name_program.elf
Start the remote (target) gdb
(mspdebug) gdb
Bound to port 2000. Now waiting for connection...
At this point open a new terminal and go to the directory where the source code and elf are.
The bolded lines are the ones to digit.
Start the debugger
$ msp430-gdb name_program.elfGNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=msp430"...
(gdb)
Attach the debugger to the target
(gdb) target remote localhost:2000
Remote debugging using localhost:2000
0x0000f800 in _reset_vector__ ()
At this point it is possible to debug the code using the gdb commands.
Saturday, December 21, 2013
Build fast a simple tachometer
The goal : measure the RPM of an home-made electric motor for a school experiment.
The first problem to solve is how to acquire the rotor revolutions, i.e. how to translate a movement in an electric signal.
Usually there are two methods :
The sensor can be a reed switch or, typically, a Hall sensor. The Hall sensor is better than the Reed switch because is not mechanical, so is not generating false signals and is faster.
If an Hall sensor is used, it must be unipolar.
There are two kind of Hall sensors, unipolar and bypolar.
The bypolar requires to "see" a change pole. i.e. a change from South pole to North pole and viceversa. Every change, triggers the change of the electric signal.
The unipolar sensor change the state of the electric signal every time a South pole is close to the sensor.
Here a graph to show the two kind of Hall sensors :
The upper part shows a bipolar Hall sensor.
When the South pole is close to the sensor, the output signal goes down. Only when the North pole is close to the sensor, the output signal goes back high.
The lower part of the graph shows a unipolar Hall sensor.
When the South pole is close to the sensor, the output goes down and it goes up as soon as the South pole is going away from the sensor.
Typically on the rotor is glued a reflective surface in a spot. A Infrared ray is sent toward the rotor and a circuit can detect the reflection of the infrared ray when bounced back from the reflective surface.
As alternative is possible to attach a disc with holes to the rotor and have a light beam (or infrared beam) interrupted by such disc.
A third optical alternative is to attach to the rotor a "black and white" pattern and illuminate it with a stroboscopic light.
Changing the frequency of the light until the pattern is "stable" (or visible as it would be stopped) will give the RPM.
We have a series of pulses generated by the sensor.
Let assume we are using the magnetic acquiring method, with a unipolar Hall sensor.
Depending how many magnets we have on the rotor we can have "n" pulses for every revolution.
i.e if we have two magnets on the rotor, we'll have two pulse every revolution. 4 magnets will generate 4 pulses and so on.
The "intuitive algorithm is quite easy. We need to count the number of pulses in a minute, then divide the number for the number of magnets and the result will be our RPM.
Unfortunately this method has a drawback. We need to wait a minute before to see the result and after that, we need to wait another minute before to see changes.
So we need to reduce the acquiring time and then estimate the RPM from the minor number of readings.
For example we can count the pulses for 1 second, then divide the number of pulses by the number of magnets. The number will represent the number of revolution for second. If we multiply that number for 60, will have the number of revolution per minute (1 minute = 60 seconds).
This can work well assuming the motor rotates at a constant rate and that rate is not too slow.
For very slow rotations, it is necessary to increase the counting time, maybe to two or three seconds (and then multiply accordingly)
The problem with that is the "visualization" of the measurement. More time to count the pulses means more time between the visualization of the result.
It is possible to build the tachometer in many different ways.
Of course today is more simple to use a microcontroller rather than use more "traditional" ways, like using counters, decoders and LED display.
Any microntroller family is more than suitable for this application, especially because the measurements to do are not critical.
A microcontroller is also better than "traditional logic" because it require less components and only changing the software is possible to change the type of measurement.
Mostly because is something I already have around, the idea is to use the Texas Instrument MSP430 family of microcontroller, specifically a board with already the MSP430F169 and a Philips LCD display.
This board has everything we need to build a tachometer and we can easily change the parameters, like the number of magnet on the rotor and the acquisition time.
The software will be build using the GNU Msp430 Gcc compiler.
In order to develop the RPM meter (or tachometer) some tools are necessary.
The software will be build under a Linux machine, using Code::Blocks as editor/IDE.
The compiler used is the open source version of the GNU Gcc for the MSP430 .
The debug system is based on the msp430-gdbserver.
An oscilloscope will be used to check the input signal from the Hall sensor.
The PC used to develop the code must have a traditional parallel port since the only GDB tool is parallel.
For the schematics, the FidoCad and Eagle programs will be used.
FidoCad allows to draw very simple schematics, Eagle is more sophisticate and can be used to produce a PCB (not necessary for this particular project though)
As introduced before, the main hardware is the Olimex board based on the MSP430F169.
What is needed is the Hall sensor. I choose a Honeywell SS400 series Unipolar Hall sensor (SS441A ).
The sensor will be connected to an I/O pins of the board, one capable to read the output signal from the sensor.
Since the board has plenty of available I/O Pins is not a problem.
Specifically will be used the Pin1.1 to read the signal from the Hall Sensor.
The P1.1 is capable to generate interrupts and it can be also connected to an internal timer in case a different measure approach is needed.
The sensor needs to be powered with a Vcc starting from 3.8 V. The Olimex board is operating at 3.3.V so an external regulator is needed and a 5V one is used. Because the MSP430F169 I/O pin are NOT 5V tolerant a resistor limiting the current is needed to avoid damage to the microcontroller.
The capacitors are the standard ones for the 78L05 regulators.
Here is possible to find the schematic of the Olimex board.
The software is a first simple draft to prove the concept and verify the hardware.
It is based on the original demo code coming with the board, modified for the specific needs.
The Hall sensor signal will be connected to an interrupt capable I/O in order to don't miss any "firing" of the signal.
One or more timers will be used for the time counting. The visualization will be placed in the main loop.
The algorithm is quite simple and based on two interrupts.
One interrupt is related to the I/O pin connected to the Hall sensor. Normally the signal is pulled up, so the interrupt is set to fire on the descending slope of the signal.
The interrupt function increment a counter every time the signal goes down.
The other interrupt is a timer.
A generic timer "fires" every "n" seconds (default is 1).
When the timer fires, the the counter is copied in a variable and the counter is set to zero.
A flag is set to one indicating the need to display the content.
In the main loop, the visualization loop check the variable updated by the visualization timer to show the result.
Some I/O are "forced" by the nature of the board.
Here the main ones used other than the ones pre-wired on the board :
P1.1 Hall sensor input
Pulled up, the pin goes to zero when a South Pole magnetic field is close to the sensor
P2.1 Status LED - toggle at every Hal sensor signal
The LED is toggled at every sensor magnetic event
P2.2 Status clock
The pin is toggled at every timer firing. If the timer is set for 1 second, the signal will have 2 second period.
2 seconds timer will generate a 4 seconds period on the pin and so on.
P2.3 Debug pin
Generic debug pin
The Olimex MSP430F169 LCD board has two crystal sources.
A 32Khz crystal and a 8 Mhz crystal.
For this application one of them should be OK since the low time involved.
The minimum period needed is about 1 second, so also the slower but precise 32Khz source should be OK as clock.
In order to minimize the timer interrupts generated, the 32 Khz crystal is used in order to generate a 1 second timer used for the measurement, the rest of the board continue to use the DCO as main source of the clock.
To set the 32Khz crystal :
DOCTL = 0x60
modulation off, DCOx and RSELx ~800kHz
BCSCTL1 = 0xB7
XT2OFF = 1 - XTS = 0 - DIVAx = 3 - RSELx = 7
BCSCTL2 = 0x00
SELMx = 0 - DIVMx = 0 - SELS = 0 - DIVSx = 0 = DCOR = 0
BCSCTL3 = 0x0C
XT2Sx = 0 - LFXT1Sx = 0 - XCAPx = 12.5pF - XT2Of = 0 - LFXT1OF = 0
With this setting the ACLK is of 4096 Hz, the MCLCK/SMCLK of ~800kHz
Note : using the 32Khz for the main clock (MCLK) the display is not working properly.
A generic timer is handling some sub-timers used to count the Hall sensor pulse and display the value.
The timer_A 0 will be used in the up mode.
The clock source for the timer will be ACLK, i.e. 4096 Hz.
The Timer_A will be set with a /8 so that the value 512 placed in the TACCR0 will generate an interrupt every 1 second.
TACTL = TASSEL_1 + ID_3 + MC_1; /* Uses ACLK, divide by 8, count in up mode */
TACCTL0 = CCIE; /* Use TACCR0 to generate interrupt */
TACCR0 = TMRVALUE; /* 1s */
Two choices are available :
The Set allows to set up some parameters, like the number of seconds for the counter/display value or the number of magnets
The Measure starts the measurement.
Requirements
The kind of motor built for the experiment is slow by definition, so the RPM meter (also called tachometer - http://en.wikipedia.org/wiki/Tachometer) must be capable to measure and display low revolutions per minute.
The other goal is to build the tool easily and in short time, possibly spending the less possible.
The other goal is to build the tool easily and in short time, possibly spending the less possible.
Acquiring Methods
The first problem to solve is how to acquire the rotor revolutions, i.e. how to translate a movement in an electric signal.
Usually there are two methods :
- magnetic
- optical
Magnetic
Since the rotor has already magnets glued on it, it is relatively easy to add a magnetic sensor capable to generate a pulse every time a magnet pass close to it.The sensor can be a reed switch or, typically, a Hall sensor. The Hall sensor is better than the Reed switch because is not mechanical, so is not generating false signals and is faster.
If an Hall sensor is used, it must be unipolar.
There are two kind of Hall sensors, unipolar and bypolar.
The bypolar requires to "see" a change pole. i.e. a change from South pole to North pole and viceversa. Every change, triggers the change of the electric signal.
The unipolar sensor change the state of the electric signal every time a South pole is close to the sensor.
Here a graph to show the two kind of Hall sensors :
When the South pole is close to the sensor, the output signal goes down. Only when the North pole is close to the sensor, the output signal goes back high.
The lower part of the graph shows a unipolar Hall sensor.
When the South pole is close to the sensor, the output goes down and it goes up as soon as the South pole is going away from the sensor.
Optical
The other common way to acquire the revolution, is optical.Typically on the rotor is glued a reflective surface in a spot. A Infrared ray is sent toward the rotor and a circuit can detect the reflection of the infrared ray when bounced back from the reflective surface.
As alternative is possible to attach a disc with holes to the rotor and have a light beam (or infrared beam) interrupted by such disc.
A third optical alternative is to attach to the rotor a "black and white" pattern and illuminate it with a stroboscopic light.
Changing the frequency of the light until the pattern is "stable" (or visible as it would be stopped) will give the RPM.
Measurement
We have a series of pulses generated by the sensor.
Let assume we are using the magnetic acquiring method, with a unipolar Hall sensor.
Depending how many magnets we have on the rotor we can have "n" pulses for every revolution.
i.e if we have two magnets on the rotor, we'll have two pulse every revolution. 4 magnets will generate 4 pulses and so on.
The "intuitive algorithm is quite easy. We need to count the number of pulses in a minute, then divide the number for the number of magnets and the result will be our RPM.
Unfortunately this method has a drawback. We need to wait a minute before to see the result and after that, we need to wait another minute before to see changes.
So we need to reduce the acquiring time and then estimate the RPM from the minor number of readings.
For example we can count the pulses for 1 second, then divide the number of pulses by the number of magnets. The number will represent the number of revolution for second. If we multiply that number for 60, will have the number of revolution per minute (1 minute = 60 seconds).
This can work well assuming the motor rotates at a constant rate and that rate is not too slow.
For very slow rotations, it is necessary to increase the counting time, maybe to two or three seconds (and then multiply accordingly)
The problem with that is the "visualization" of the measurement. More time to count the pulses means more time between the visualization of the result.
Building
It is possible to build the tachometer in many different ways.
Of course today is more simple to use a microcontroller rather than use more "traditional" ways, like using counters, decoders and LED display.
Any microntroller family is more than suitable for this application, especially because the measurements to do are not critical.
A microcontroller is also better than "traditional logic" because it require less components and only changing the software is possible to change the type of measurement.
Mostly because is something I already have around, the idea is to use the Texas Instrument MSP430 family of microcontroller, specifically a board with already the MSP430F169 and a Philips LCD display.
The software will be build using the GNU Msp430 Gcc compiler.
Note ! It is possible to use the software on different boards with few modifications.
For example the MSP430 Launchpad board is more than enough for this project.
Only two reasons did let me decide for the Olimex board :
For example the MSP430 Launchpad board is more than enough for this project.
Only two reasons did let me decide for the Olimex board :
- I already had this board around picking up dust
- This board has already a joystick and LCD display on it
Tools
In order to develop the RPM meter (or tachometer) some tools are necessary.
The software will be build under a Linux machine, using Code::Blocks as editor/IDE.
The compiler used is the open source version of the GNU Gcc for the MSP430 .
The debug system is based on the msp430-gdbserver.
An oscilloscope will be used to check the input signal from the Hall sensor.
The PC used to develop the code must have a traditional parallel port since the only GDB tool is parallel.
For the schematics, the FidoCad and Eagle programs will be used.
FidoCad allows to draw very simple schematics, Eagle is more sophisticate and can be used to produce a PCB (not necessary for this particular project though)
Hardware
As introduced before, the main hardware is the Olimex board based on the MSP430F169.
What is needed is the Hall sensor. I choose a Honeywell SS400 series Unipolar Hall sensor (SS441A ).
The sensor will be connected to an I/O pins of the board, one capable to read the output signal from the sensor.
Since the board has plenty of available I/O Pins is not a problem.
Specifically will be used the Pin1.1 to read the signal from the Hall Sensor.
The sensor needs to be powered with a Vcc starting from 3.8 V. The Olimex board is operating at 3.3.V so an external regulator is needed and a 5V one is used. Because the MSP430F169 I/O pin are NOT 5V tolerant a resistor limiting the current is needed to avoid damage to the microcontroller.
The capacitors are the standard ones for the 78L05 regulators.
Here is possible to find the schematic of the Olimex board.
Software
First draft
The software is a first simple draft to prove the concept and verify the hardware.
It is based on the original demo code coming with the board, modified for the specific needs.
The Hall sensor signal will be connected to an interrupt capable I/O in order to don't miss any "firing" of the signal.
One or more timers will be used for the time counting. The visualization will be placed in the main loop.
The algorithm is quite simple and based on two interrupts.
One interrupt is related to the I/O pin connected to the Hall sensor. Normally the signal is pulled up, so the interrupt is set to fire on the descending slope of the signal.
The interrupt function increment a counter every time the signal goes down.
The other interrupt is a timer.
A generic timer "fires" every "n" seconds (default is 1).
When the timer fires, the the counter is copied in a variable and the counter is set to zero.
A flag is set to one indicating the need to display the content.
In the main loop, the visualization loop check the variable updated by the visualization timer to show the result.
I/O Settings
Some I/O are "forced" by the nature of the board.
Here the main ones used other than the ones pre-wired on the board :
P1.1 Hall sensor input
Pulled up, the pin goes to zero when a South Pole magnetic field is close to the sensor
P2.1 Status LED - toggle at every Hal sensor signal
The LED is toggled at every sensor magnetic event
P2.2 Status clock
The pin is toggled at every timer firing. If the timer is set for 1 second, the signal will have 2 second period.
2 seconds timer will generate a 4 seconds period on the pin and so on.
P2.3 Debug pin
Generic debug pin
Clock settings
The Olimex MSP430F169 LCD board has two crystal sources.
A 32Khz crystal and a 8 Mhz crystal.
For this application one of them should be OK since the low time involved.
The minimum period needed is about 1 second, so also the slower but precise 32Khz source should be OK as clock.
In order to minimize the timer interrupts generated, the 32 Khz crystal is used in order to generate a 1 second timer used for the measurement, the rest of the board continue to use the DCO as main source of the clock.
To set the 32Khz crystal :
DOCTL = 0x60
modulation off, DCOx and RSELx ~800kHz
BCSCTL1 = 0xB7
XT2OFF = 1 - XTS = 0 - DIVAx = 3 - RSELx = 7
BCSCTL2 = 0x00
SELMx = 0 - DIVMx = 0 - SELS = 0 - DIVSx = 0 = DCOR = 0
BCSCTL3 = 0x0C
XT2Sx = 0 - LFXT1Sx = 0 - XCAPx = 12.5pF - XT2Of = 0 - LFXT1OF = 0
With this setting the ACLK is of 4096 Hz, the MCLCK/SMCLK of ~800kHz
Note : using the 32Khz for the main clock (MCLK) the display is not working properly.
Timer setting
A generic timer is handling some sub-timers used to count the Hall sensor pulse and display the value.
The timer_A 0 will be used in the up mode.
The clock source for the timer will be ACLK, i.e. 4096 Hz.
The Timer_A will be set with a /8 so that the value 512 placed in the TACCR0 will generate an interrupt every 1 second.
TACTL = TASSEL_1 + ID_3 + MC_1; /* Uses ACLK, divide by 8, count in up mode */
TACCTL0 = CCIE; /* Use TACCR0 to generate interrupt */
TACCR0 = TMRVALUE; /* 1s */
Menu
When the code starts, a menu appears.Two choices are available :
- Set
- Measure
The Set allows to set up some parameters, like the number of seconds for the counter/display value or the number of magnets
The Measure starts the measurement.
Friday, October 14, 2011
MSP430 - IAR vs mspgcc
Updated !
There are some differences between a C program developed with IAR and one developed for mspgcc.
This article will try to address these differences in order to port a MSP430 program developed for IAR into a mspgcc one and viceversa.
I'll try to keep update the article every time I found something or if I receive suggestions.
With the mspgcc (msp430-elf) version maintained by TI, there are further differences.
Include files
With IAR usually it was #include <msp43xxxxx.h> wherexxxx indicated the specific family.
With mspgcc is better to include the file io.h and set the cflags to the correct cpu.
For example :
In Code::Blocks, in order to add the correct mmcu flag :
For example, the demo program for the MSP430F169, used in the Olimex card, uses the notation :
P3OUT_bit.P3OUT_0 to address the bit 0 of the port 3.
With mspgcc the single bit need to be addressed differently.
If a single bit needs to be addressed, it is necessary to use the mask bits.
For example, to set the bit zero to 1or the port3 :
P3OUT |= 0x01;
To set it to zero :
P3OUT &= ~0x01;
Better to prepare some defines, something like this :
#define BIT_0 0x01
#define BIT_1 0x02
#define BIT_2 0x04
#define BIT_4 0x08
#define BIT_5 0x10
#define BIT_6 0x20
#define BIT_7 0x40
#define BIT_8 0x80
Include the file signals.h when it is used (#include <signals.h>)
There are some differences between a C program developed with IAR and one developed for mspgcc.
This article will try to address these differences in order to port a MSP430 program developed for IAR into a mspgcc one and viceversa.
I'll try to keep update the article every time I found something or if I receive suggestions.
With the mspgcc (msp430-elf) version maintained by TI, there are further differences.
Include files
Component
The main inclusion file necessary is related to the component used.With IAR usually it was #include <msp43xxxxx.h> wherexxxx indicated the specific family.
With mspgcc is better to include the file io.h and set the cflags to the correct cpu.
For example :
| IAR | mspgcc | msp430-elf |
Family MSP430 F 2012
#include <msp430x20x2.h>
|
#include <io.h>
set -mmcu=msp430x2012 in cflags
|
#include <msp430.h>
#include <legacymsp430.h>
set -mmcu=msp430f2012 in cflags
Be sure to have -I and -L in the CFLAGS with the path to the MSP430_TI/include |
In Code::Blocks, in order to add the correct mmcu flag :
- open Settings/Compiler and Debugger
- go in the tab Compiler Settings/Other options
- add the line -mmcu=msp430x2012 (or the specific mcu used)
Or, it is possible to find and include the correct header.
Looking in the file io.h is possible to see the correct inclusion.
Ports
Some programs with IAR uses different port notation.For example, the demo program for the MSP430F169, used in the Olimex card, uses the notation :
P3OUT_bit.P3OUT_0 to address the bit 0 of the port 3.
With mspgcc the single bit need to be addressed differently.
If a single bit needs to be addressed, it is necessary to use the mask bits.
For example, to set the bit zero to 1or the port3 :
P3OUT |= 0x01;
To set it to zero :
P3OUT &= ~0x01;
Better to prepare some defines, something like this :
#define BIT_0 0x01
#define BIT_1 0x02
#define BIT_2 0x04
#define BIT_4 0x08
#define BIT_5 0x10
#define BIT_6 0x20
#define BIT_7 0x40
#define BIT_8 0x80
and then use notation like :
P3OUT |= BIT_0
In IAR the interrupt function is a normal function with __interrupt as type.
mspgcc has a special function called interrupt.
Because of that under mspgcc no function prototypes are allowed for interrupt functions.
For example, for the Timerinterrupt function :
To enable the interrupts is possible to use the function eint() or _BIS_SR(GIE);
Interrupts
mspgcc has a special function called interrupt.
Because of that under mspgcc no function prototypes are allowed for interrupt functions.
For example, for the Timerinterrupt function :
| IAR | mspgcc | msp430-elf |
/* Timer A0 interrupt service routine */
__interrupt void Timer_A (void);
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A( void ) { ... } | // Timer A0 interrupt service routine interrupt(TIMERA0_VECTOR) Timer_A (void) { .... } |
// Timer A0 interrupt service routine
__attribute__((__interrupt__(TIMERA0_VECTOR)))void Timer_A (void)
{
.... } |
Include the file signals.h when it is used (#include <signals.h>)
Subscribe to:
Posts (Atom)












