The first two features to understand in a microcontroller are timers and interruptions.
Indeed, without a timer nor interruptions, it's quite impossible to have an accurate timing in a program.
Let's see that in this tutorial and let's generate a timing of 1 second with the G2553 microcontroller.
The essential documents needed for any project with a MSP430 microcontroller are:
The main goal of a timer is to generate a counter and check if a particular number in this counter has been reached.
This is the job of the famous Capture Compare (CC) register.
This register compares a number set by the programmer (a human being generally) and trigger a signal when this value is reached.
So the CC will capture the number in the counter and compare it with the value set by the programmer.
This signal is generally caught by an Interrupt Service Routine (ISR) in order to achieve a specific task.
In our example, we will use this ISR to light a LED.
I don't know if we can do easiest than that!
A timer works only if there is something that can generate a tick.
This operation is made by an oscillator, that can be internal or external.
The main difference between an internal and an external oscillator (like a quartz) is that the internal is less accurate but easiest to handle with only software.
But we won't talk about external oscillators in this tutorial, only internal.
There are two internal oscillators in the MSP430:
These oscillators are used by the clocks.
In the MSP430G2553, there are 3 clocks:
In our example we will use the DCO with the SMCLK for our timer peripheral.
With the code below I set the bit 0 of the P1DIR register in order to have the LED ready to light.
I light it in the ISR by changing each time this bit from 0 to 1 and from 1 to 0.
It explains why the LED is blinking.
Then I set the bit 4 to high from the P1DIR and from the P1SEL registers in order to have the clock on this pin.
I set the DCO to have approximatively an oscillation of 1.5 MHz.
Then I divided it by 4 to have once again an approximation of 387 kHz.
More information in the datasheet page 29.
Finally I set the timer to have SCMCLK as clock, I use the MC_1 to have the timer repeatedly counts from 0 to the value of TACCR0 set to 24198.
More information in the user guide page 358.
With all that settings we have 1 second delay (on the video we can see 0.999 second with a logic analyzer).
In order to have a system with a low-power mode, we set it with LPM0_bits and we enable the Global Interrupt Enabled (GIE).
So each time the counter reach the value 24198, it will trigger an interruption.
This interruption is the function __interrupt void badprog_timer_a0() which will change the value of the P1OUT.P0 bit from 0 to 1 and 1 to 0 to have a LED blinking.
#include <msp430.h> /** * Main */ int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR &= 0x00; // P1DIR reset P1OUT &= 0x00; // P1OUT reset P1DIR |= (1 << 0); // P1DIR P1.0 -- LED P1DIR |= (1 << 4); // P1DIR P1.4 -- CLOCK P1SEL |= (1 << 4); // P1SEL P1.4 -- CLOCK DCOCTL |= 0xE0; // DC0 CTL = 1110 0000 BCSCTL1 |= 0x87; // BCS CTL1 = 1000 0111 BCSCTL2 |= DIVS_2; // SMCLK divided by 2^2=4 TACTL = TASSEL_2 + MC_1 + ID_3; // TA0 CTL = 1011 01000 CCTL0 = CCIE; // TA0 CCTL0 CCR0 = 24198; // TA0 CCR0 value is 24198 (0x5E86) __bis_SR_register(LPM0_bits + GIE); // LowPower0 + Global Interrupt Enabled } /** * Timer A0 interrupt service routine */ #pragma vector=TIMER0_A0_VECTOR __interrupt void badprog_timer_a0(void) { P1OUT ^= (1 << 0); }
If you understood this simply but useful code you got the basis of a the MSP430G2553 microcontroller.
You are now able to use a timer that uses a clock, that itself uses an oscillator.
Good job, you've made it!
Comments
sunny (not verified)
Friday, April 15, 2016 - 7:53am
Permalink
What is the use of P1SEL?
What is the use of P1SEL?
Mi-K
Sunday, April 24, 2016 - 11:15am
Permalink
Hello sunny,
Hello sunny,
P1SEL is used in order to select the function of a particular pin.
In our example, if you check the MSP430G2553 datasheet, in page 47 (table 18), you'll see the pin functions of the Pin 1.4.
And thus if you set the pins like that:
And others to 0, you'll have the SMCLK set on the pin P1.4.
Anonymous (not verified)
Wednesday, July 12, 2017 - 11:42pm
Permalink
BCSCTL1 |= 0x87;
BCSCTL1 |= 0x87;
Should not be 0x78 ?
Mi-K
Friday, July 14, 2017 - 11:59am
Permalink
Why?
Why?
phylab (not verified)
Thursday, August 10, 2017 - 3:15pm
Permalink
is this the same code that
is this the same code that can be used for msp430fg6426?
Mi-K
Thursday, August 10, 2017 - 3:17pm
Permalink
Hello phylab,
Hello phylab,
To check that you have to take a look at the datasheets of your MSP430 fg6426 microcontroller and compare them with the MSP430 G2553.
John (not verified)
Thursday, June 21, 2018 - 9:46am
Permalink
Hello,
Hello,
How did u get the value 24198 for 1 second? Could u please explain.
Kamaran Khan (not verified)
Monday, October 15, 2018 - 1:34am
Permalink
please find out Error in the
please find out Error in the following code
#include <MSP430.h>
#include <stdint.h>
uint8_t x;
int main (void)
{
WDTCTL= WDTPW | WDTHOLD;
x=0x00;
P2DIR=0xFF;
P2OUT=~BIT0;
TACCR0=49999;
TACCTL0=CCIE;
TACTL=MC_1 | ID_0 | TASSEL_2 |TACLR;
__enable_interrupt();
for(;;){
__bis_SR_register(LPM4_bits+GIE);
}
}
#pragma vector = TIMER_A0_VECTOR
__interrupt void TA0_ISR(void)
{
P2OUT ^=BIT0;
}
preetham (not verified)
Monday, August 19, 2019 - 9:26am
Permalink
how can I generate 20 mins
how can I generate 20 mins delay ?
Add new comment