To get started with the MSP430, mspgcc, mspdebug and TI’s Launchpad board, I made a simple metronome. Press the button twice to set the LED period.
Timer0 increments a global tick counter. On button press an interrupt is fired and the current tick count is stored. After two button presses the LED period (in ticks) is stored. The LED is then toggled at this period.
As the MSP430 is all about low power, this could likely be done better with an extra timer and a low power mode. But, still a good exercise.
Download source and Makefile.
/************************************************************TI Launchpad MSP430 Simple Metronome.Press button twice to set speed. Joby Taffey ************************************************************/ #include #include /************************************************************/ #define LED_BIT (BIT0 | BIT6) // both LEDs#define LED_DIR P1DIR#define LED_OUT P1OUT #define SWITCH_BIT BIT3#define SWITCH_DIR P1DIR#define SWITCH_IE P1IE // interrupt enable#define SWITCH_ES P1IES // interrupt edge select /************************************************************/ static volatile uint16_t ticks = 0; // tick counterstatic volatile uint16_t lastPressTicks = 0; // tick count of last button pressstatic volatile uint16_t ledPeriodTicks = 0; // number of ticks between LED flashesstatic volatile uint16_t ledTimer = 0; // LED flash downcounter (ledPeriodTicks to 0) /************************************************************/ // Timer0 ISRinterrupt(TIMERA0_VECTOR) TIMERA0_ISR(void){ ticks++; if (ledPeriodTicks > 0) { if (ledTimer > 0) { ledTimer--; } else { ledTimer = ledPeriodTicks; LED_OUT ^= LED_BIT; } }} // Port1 ISRinterrupt(PORT1_VECTOR) P1_ISR(void){ if((P1IFG & BIT3) == SWITCH_BIT) // switch pressed { if (lastPressTicks == 0) // first press { lastPressTicks = ticks; LED_OUT |= LED_BIT; // Turn on LED } else { ledPeriodTicks = (ticks - lastPressTicks); ledTimer = ledPeriodTicks; lastPressTicks = 0; LED_OUT &= ~LED_BIT; // Turn off LED } } P1IFG = 0x00; // clear interrupt flags} /************************************************************/ int main(void){ // Stop watchdog timer WDTCTL = WDTPW + WDTHOLD; // Set ACLK to use internal VLO (12kHz) BCSCTL3 |= LFXT1S_2; // TimerA aux clock in UP mode TACTL = TASSEL_1 | MC_1; // Enable interrupt for TACCR0 match TACCTL0 = CCIE; // Set TACCR0, starts timer TACCR0 = 1; // setup switch interrupt SWITCH_DIR &= ~SWITCH_BIT; // as input SWITCH_ES |= 0x01; // interrupt on falling edge SWITCH_IE |= SWITCH_BIT; // interrupt enable // Setup LED pins LED_DIR |= LED_BIT; // Set LED pins as outputs LED_OUT &= ~LED_BIT;// Turn off both LEDs // Enable interrupts eint(); while(1) { // everything happens under interrupt } return 0;}