// 2010 Kenneth Finnegan | |
// http://kennethfinnegan.blogspot.com/ | |
// Two color blink clock running on MSP430 controller | |
#include "msp430G2101.h" | |
#define BLINK_ON 3000 | |
#define BLINK_OFF 1500 | |
#define BLINK_SPACE 6000 | |
volatile unsigned char time[4]; | |
volatile unsigned char mode; | |
// FUNCTIONS | |
void displayNum (int c); | |
void displayTime(void); | |
void displayTwiddle(void); | |
void pause (int c); | |
void main(void) { | |
WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog Timer | |
BCSCTL3 = (BCSCTL3 & ~(XCAP0 | XCAP1)) | XCAP_1; // 6pF xtal | |
BCSCTL2 = 0xF8; // MCLK:LFXT1CLK/8 SMCLK:LFXT1CLK | |
P1DIR = 0x41; | |
P1OUT = 0x0F; // pull up resistors | |
P1REN = 0x0E; // pull up resistors enable | |
P1IE = 0x08; // Setup P1.3 for interrupt | |
P1IES = 0x08; // High -> Low transistion | |
P1IFG &= ~0x08; // Clear int flag | |
CCTL0 = CCIE; | |
CCR0 = 0; | |
TACCR0 = 0x7FFF; // Period of 32767 + 1 | |
TACTL = 0x0211; // Timer_A: SMCLK, UP MODE, TAIE | |
while(1) { | |
mode = 0; | |
_BIS_SR(LPM1_bits + GIE); | |
switch (mode) { | |
case 0x06: // display time | |
displayTime(); | |
break; | |
case 0x04: // display hours | |
if (time[3]) displayTwiddle(); | |
pause(BLINK_SPACE); | |
displayNum(time[2]); | |
break; | |
case 0x02: // increment minutes | |
displayNum(time[1]); | |
break; | |
} | |
} | |
} | |
#pragma vector=TIMERA0_VECTOR | |
__interrupt void Timer_A (void) { | |
//P1OUT ^= 1; | |
time[0] = (time[0] + 1) % 60; | |
if (time[0] == 0) { // new minute | |
time[1] = (time[1] + 1) % 60; | |
if (time[1] == 0) { // new hour | |
time[2] = (time[2] + 1) % 12; | |
time[2] = time[2]?time[2]:12; | |
if (time[2] == 12) { // new AM/PM | |
time[3] = !time[3]; | |
} | |
} | |
} | |
} | |
#pragma vector=PORT1_VECTOR | |
__interrupt void Port_1 (void) { | |
mode = P1IN & 0x06; | |
LPM1_EXIT; // Wake up the main loop | |
switch (mode) { // Needs debounce! | |
case 0x04: | |
time[2] = (time[2] + 1) % 12; | |
time[2] = time[2]?time[2]:12; | |
if (time[2] == 12) { // new AM/PM | |
time[3] = !time[3]; | |
} | |
break; | |
case 0x02: | |
time[1] = (time[1] + 1) % 60; | |
time[0] = 0; | |
break; | |
} | |
P1IFG = 0; // Clear int flag | |
} | |
void displayTime(void) { | |
if (time[3]) { // twiddle on PM | |
displayTwiddle(); | |
} | |
pause(BLINK_SPACE); | |
displayNum(time[2]); | |
pause(BLINK_SPACE); | |
displayNum(time[1]); | |
} | |
void displayNum (int c) { | |
int i; | |
for (i=c/10; i; i--) { | |
P1OUT |= 0x40; | |
pause(BLINK_ON); | |
P1OUT &= ~0x40; | |
pause(BLINK_OFF); | |
} | |
if ((c%10) > 4) { | |
P1OUT |= 0x41; | |
pause(BLINK_ON); | |
P1OUT &= ~0x41; | |
pause(BLINK_OFF); | |
} | |
for (i=c%5; i; i--) { | |
P1OUT |= 0x1; | |
pause(BLINK_ON); | |
P1OUT &= ~0x1; | |
pause(BLINK_OFF); | |
} | |
P1OUT &= ~(0x41); | |
} | |
void displayTwiddle(void) { | |
int i; | |
for (i=0; i<2; i++) { | |
P1OUT |= 0x40; | |
P1OUT &= ~(0x01); | |
pause(BLINK_ON); | |
P1OUT |= 0x01; | |
P1OUT &= ~(0x40); | |
pause(BLINK_ON); | |
} | |
P1OUT &= ~(0x41); | |
} | |
void pause (int c) { | |
volatile unsigned int t = c; | |
do { t--;} while (t); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment