MSP430 - Interrupt on Input Change

Now has come the time to wrap up our little timer exercise.

What we still have to do:

  1. Figure out a way to select different timer delays.
  2. Find a way to reset the timer.
The second problem should be easy enough. In fact, if we do this right we will not need a RESET button.


RESET

Pin-16 of the MSP430G2553 is the RESET pin (active low). We can install a push button from pin-16 to GND (DVSS, pin-20) and a 100kΩ pull-up resistor from pin-16 to DVCC (pin-1). Pressing this push button will reset the mcu.


Interrupt on Input Change


We can use eight pins of PORT1 in order to select any one of eight timer delays. Of course, we would move the LED output to a pin on PORT2.

For simplicity, we will choose six pins on PORT1, P1.0 to P1.5 as timer delay choices and move the LED to P2.2 (pin-10).

Here is the modified program:

Code:
// Timer example with Interrupt on Input Change
// 2013.04.30 - MrChips

#include "io430.h"

#define ON 1
#define OFF 0
#define LED2 P2OUT_bit.P2
#define ONE_SECOND 512

// six possible timer delay settings
#define SET0  120    //  2 hours
#define SET1  240    //  4 hours
#define SET2  360    //  6 hours
#define SET3  480    //  8 hours
#define SET4  720    // 12 hours
#define SET5 1440    // 24 hours

// my variables
unsigned short minutes, minutes_setting, alarm;

void delay(unsigned long d)
{
  unsigned long i;
  for (i = 0; i < d; i++);
}

void init(void)
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;

  P1OUT = 0xFF;  // select internal pull-up resistors
  P1IE  = 0xFF;  // enable PORT1 interrupts
  P1IES = 0xFF;  // configure for high-to-low transition

  P2OUT = 0x00;
  P2DIR = 0xFF;

  minutes = 0;
  minutes_setting = 60;  // default is 1 hour
  alarm = OFF;

  // Set up 32768Hz crystal
  BCSCTL1 |= DIVA_3;    // divide by 8
  BCSCTL3 |= XCAP_3;    // select 12pF caps

  // initialize Timer0_A
  TA0CCR0 = 60*ONE_SECOND;         // set up terminal count for 60 seconds
  TA0CTL = TASSEL_1 + ID_3 + MC_1; // configure and start timer

  // enable interrupts
  // TA0CCTL0_bit.CCIE = 1;   // moved to myPORT1_ISR
  __enable_interrupt();    // set GIE in SR
  LPM3;                    // select low power mode 3
}

//-------------------------------------
//   ISR for PORT1 input change
//-------------------------------------

#pragma vector = PORT1_VECTOR
__interrupt void myPORT1_ISR(void)
{
   alarm = OFF;
   minutes = 0;
   TA0R = 0;
   TA0CCR0 = 60*ONE_SECOND;  // change timer to 60s
   TA0CCTL0_bit.CCIE = 1;    // enable timer interrupts

   // which button pressed?
   if      (P1IFG_bit.P0) minutes_setting = SET0;
   else if (P1IFG_bit.P1) minutes_setting = SET1;
   else if (P1IFG_bit.P2) minutes_setting = SET2;
   else if (P1IFG_bit.P3) minutes_setting = SET3;
   else if (P1IFG_bit.P4) minutes_setting = SET4;
   else if (P1IFG_bit.P5) minutes_setting = SET5;
   P1IFG = 0;
}

//-------------------------------------
//   ISR for Timer0_A
//-------------------------------------

#pragma vector = TIMER0_A0_VECTOR
__interrupt void myTimerISR(void)
{
  if (alarm)
  { // alarm triggered
     LED2 = ON;
     delay(1000);   // flash LED1 for 10ms
     LED2 = OFF;
  } // alarm triggered
  else
  { // alarm not triggered
     minutes++;

     if (minutes >= minutes_setting)
       { // trigger alarm
         alarm = ON;
         TA0CCR0 = ONE_SECOND;  // change timer delay to 1s
       } // trigger alarm

  } // alarm not triggered
}

//-------------------------------------
//   main program
//-------------------------------------

void main( void )
{
  init();
}
(Code has not yet been compiled and tested. Hopefully I will get around to it sometime today.)

When a push-button wired from one of the PORT1 input pins to GND (VDSS) is pressed myPORT1_ISR( ) is called. In this ISR we reset the alarm, minutes counter and restart the timer.

We have eliminated the need for a reset button.

Edit:

Usually, I write a program and then go for a walk, bike ride or have a shower. During that time I may come up with some different ideas.

Here is what I would change.

I would retain the RESET button. On RESET, I would not enable the timer interrupt. Only enable the timer interrupt when a set button is pressed. Hence on reset the alarm is disabled and mcu draws very little current.

Edit: I have move the timer interrupt enable to myPORT1_ISR( ).
On reset, only the input change will trigger an interrupt.

Blog entry information

Author
MrChips
Views
4,190
Last update

More entries in General

More entries from MrChips

Share this entry

Top