Now has come the time to wrap up our little timer exercise.
What we still have to do:
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 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 moved the timer interrupt enable to myPORT1_ISR( ).
On reset, only the input change will trigger an interrupt.
PREVIOUS NEXT
MSP430 Tutorial - Index
What we still have to do:
- Figure out a way to select different timer delays.
- Find a way to reset the timer.
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();
}
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 moved the timer interrupt enable to myPORT1_ISR( ).
On reset, only the input change will trigger an interrupt.
PREVIOUS NEXT
MSP430 Tutorial - Index