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.
First of all
The essential documents needed for any project with a MSP430 microcontroller are:
- datasheet –> http://www.ti.com/lit/ds/symlink/msp430g2553.pdf
- user guide –> http://www.ti.com/lit/ug/slau144j/slau144j.pdf
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:
- VLO –> Very Low Oscillator
- DCO –> Digital Controller Oscillator
These oscillators are used by the clocks.
In the MSP430G2553, there are 3 clocks:
- MCLK –> Master clock (used by the CPU with high speed oscillators)
- SMCLK –> Sub Main clock (used by peripherals with high speed oscillators)
- ACLK –> Auxiliary clock (used by peripherals with low speed oscillators)
In our example we will use the DCO with the SMCLK for our timer peripheral.
Peripherals
Port
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.
Oscillator
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.
Timer
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).
Low-power mode and interruption
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.
Code
#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);
}
Conclusion
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.