MSP 430 Alarm Clock

Hi!

This is the code of my MSP430 based Alarm Clock. I have not added this until now, because it is a Kind of Spaghetti code i am writing.


If there are questions about the wiring, there is just a button and a piezo. For testing you dont Need a piezo. What you Need ia a seven Segment Display. You have to put the wires matching to your 7 Segment Display. You see the values i have calculated to match the Displayed numbers or letters. I will write this down a bit more clearly, but at first this must be enough.

Important: You must have soldered the clock Crystal to the launchpad for this. The code uses the 32kHz clock Crystal that Comes with the launchpad.

Here is the code:

#include //target is the 2553
int mm = 36, hh = 13, am = 37, ss = 0, ah = 13, al = 1, ma = 0, mp = 1337, np = 1337, changed = 0, a = 0, b = 0, c = 0, d = 0, sum = 0, count = 1, dot = 0, dotcount = 4, as = 0, delay = 0, debounce = 0, sekunde = 0, sleeptime = 0; //set up the variables
int frequency =64, pwmvalue = 2; //variables for the delaytimer and display roll timer
int dimm = 0, sleepmins = 0; //variables for ___ and sleep
const char zahl[23] = { 20, 190, 49, 50, 154, 82, 80, 182, 16, 18, 255, 144, 93, 120, 248, 209, 82, 81, 89, 85, 88, 251, 145}; //Values for the display
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, aus, A, l, o, n, f, s, e, t, C, b, -, P

#define BUTTONPIN BIT5 //The buttonpin
#define BUZZPIN BIT4 //The PiezoPin

//calculate each digits value for the time display without modulo and division because it is not recommended in sleep mode
inline void gettime(void){
if (mm<10) {a = mm; b = 0;} if (mm>=10) {a = mm-10; b = 1;}
if (mm>=20) {a = mm-20; b = 2;}
if (mm>=30) {a = mm-30; b = 3;}
if (mm>=40) {a = mm-40; b = 4;}
if (mm>=50) {a = mm-50; b = 5;}
if (hh<10) {c = hh; d = 10;} if (hh>=10) {c = hh-10; d = 1;}
if (hh>=20) {c = hh-20; d = 2;}
}

//calculate each digits value for the alarm time no modulo and division here too for sleep mode compatibility
void getalarm(void){
if (am<10) {a = am; b = 0;} if (am>=10) {a = am-10; b = 1;}
if (am>=20) {a = am-20; b = 2;}
if (am>=30) {a = am-30; b = 3;}
if (am>=40) {a = am-40; b = 4;}
if (am>=50) {a = am-50; b = 5;}
if (ah<10) {c = ah; d = 10;} if (ah>=10) {c = ah-10; d = 1;}
if (ah>=20) {c = ah-20; d = 2;}
}

//procedure for starting timers after sleep mode ( the „inline“ means that the compiler copies this code to the location where it is used. It does not jump to this position.
inline void starttimers(void) {
CCTL1 |= CCIE; //Timer CCR1 start via enabling interrupt for it
CCTL2 |= CCIE; //Timer CCR2 start via enabling interrupt for it
TACCR1 = TAR + frequency; //set a valid new jumppoint for it
if (TACCR1 > TACCR0) {TACCR1 = frequency;} // set it to the frequency value if the result is higher than CCR0
TACCR2 = TAR + pwmvalue; //set a valid new jumppoint for it
if (TACCR2 > TACCR0) {TACCR2 = pwmvalue;} // set it to the frequency value if the result is higher than CCR0
P1OUT = 0x00; P2OUT &= 0x1F; //Set all display pins to OFF by
}

void main(void)
{
BCSCTL1 = CALBC1_16MHZ; // clock speed at 16mHz
DCOCTL = CALDCO_16MHZ; // DCO Clock 16mHz
BCSCTL1 |= DIVA_3;
BCSCTL3 |= XCAP_3; // clock divider 8

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1OUT = 0x0; // Drop all outputs to zero by default
P2OUT = 0x0; //Drop all outputs of port 2 too
P1DIR = 0xFF; // set port1 all pins as output
P2DIR = 0x1F;

TACTL |= TASSEL_1 | MC_1 | ID_3; // use ACLC, up mode, divider 8
CCTL0 |= CCIE; // CCR0 timer enabled
CCTL1 |= CCIE; // CCR1 interrupt enabled
CCTL2 |= CCIE;
TACCR0 = 30720; // CCR0 set to 1 minute
TACCR1 = frequency; // CCR1 set to the frequency variable value
TACCR2 = pwmvalue;
P2OUT &= ~BUTTONPIN; // Bit 5 von Port 2 als Pullupresistor schalten fuer den Button
P2REN |= BUTTONPIN; // Resistor fuer Button einschalten
P2IE |= BUTTONPIN; // Interrupt einschalten
P2IFG &= ~BUTTONPIN; // Interruptflag clear
_enable_interrupt(); // enable interrupts
for(;;){
//menue selection
switch (mp) {
case 1: delay = 3*8; gettime(); mp = 2; break;
case 2: if (sum == 1){gettime(); sum = 0;};np = 0; break;
case 3: dot = 0; delay = 2*8; a = 10; b = 10; c = 12; d = 11; mp = 4; np = 13; break; //show „Al“ and goto mp 13
case 4: break;
case 5: delay = 2*8; a = 10; b = 15; c = 15; d = 13; mp = 6; np = 0; break; //show „off“ and goto mp 0
case 6: break;
case 7: delay = 2*8; a = 10; b = 18; c = 17; d = 16; mp = 8; np = 17; break; //show „set“ and goto mp 0
case 8: break;
case 9: delay = 2*8; a = 19; b = 13; c = 12; d = 19; mp = 10; np = 23; break; //show alarm time and goto mp 1
case 10: break;
case 11: mp = 29; break;
case 12: mp = 0; break;
case 13: ma = 1; delay = 2*8; a = 10; b = 10; c = 14; d = 13; al = 1; mp = 14; np = 15; break;
case 14: break;
case 15: delay = 2*8; getalarm(); mp = 16; np = 1; break; //show alarm time and goto mp 1
case 16: break;
case 17: ma = 3; delay = 4*8; getalarm(); mp = 18; np = 19; break; //show alarm time and goto mp 1
case 18: if (sum == 1){getalarm(); sum = 0;}; break;
case 19: ma = 4; delay = 4*8; getalarm(); mp = 20; np = 3; break; //show alarm time and goto mp 1
case 20: if (sum == 1){getalarm(); sum = 0;}; break;
case 23: ma = 5; delay = 4*8; gettime(); mp = 24; np = 25; break; //show alarm time and goto mp 1
case 24: if (sum == 1){gettime(); sum = 0;}; break;
case 25: ma = 6; delay = 4*8; gettime(); mp = 26; np = 27; break; //show alarm time and goto mp 1
case 26: if (sum == 1){gettime(); sum = 0;}; break;
case 27: if (changed == 0) {mp = 1; np = 0;} ma = 0; break;
case 28: mm++; //increase minute counter
changed = 0;
if (mm>59){hh++; mm = 0;}; //reset minutes and increase hours if 60 minutes are over
if (hh>23){hh = 0;}; //reset hours if 24 hours are over
TAR = 0; TACCR1 = TAR + frequency; TACCR2 = TAR + pwmvalue; mp = 1; break;
case 29: delay = 2*8; gettime(); mp = 30; break;
case 30: delay =2; if (sum == 1){gettime(); sum = 0;};np = 0; break;
case 31: mp = 0; break;
case 40: ma = 7; delay = 30*8; gettime(); mp = 41; np = 42; break;
case 41: break;
case 42: ma = 7; delay = 60*8; gettime(); sleeptime = 1; mp = 43; np = 1; break;
case 43: break;
case 44: delay = 4*8; a = 10; b = 22; c = 12; d = 16; sleeptime = 2; mp = 45; np = 0; break;
case 45: break;
//bootup display tns-labs
case 1337: delay = 2*8; a = 21; b = 16; c = 14; d = 18; mp = 1338; np = 1339; break; //show „set“ and goto mp 0
case 1338: break;
case 1339: delay = 2*8; a = 16; b = 20; c = 11; d = 12; mp = 1340; np = 1337; break; //show „set“ and goto mp 0
case 1340: break;
default: mp = 0; break;
}
if (mp == 0) {CCTL2 &= ~CCIE; P1OUT = 0x00; P2OUT &= ~0x1F; P2OUT &=~BUZZPIN; ma = 0; _BIS_SR(LPM3_bits + GIE);}
}
}

//Button interrupt service routine
#pragma vector=PORT2_VECTOR
__interrupt void Port_2 (void)
{
LPM3_EXIT; //wakeup from LPM3
P2IE &= ~BUTTONPIN;
if (mp>1337){gettime(); mp = 1; np=1;};
starttimers();
debounce = 2;
switch (ma){
case 0: mp++; break;
case 3: ah++; //increase hour counter
if (ah>23){ah = 0;}; //reset hours if 24 hours are over
delay = 2*8; sum = 1; break;
case 4: am++; //increase minute counter
if (am>59){am = 0;}; //reset minutes and increase hours if 60 minutes are over
delay = 2*8; sum = 1; break;
case 5: hh++;//increase hour counter
changed = 1;
if (hh>23){hh = 0;}; //reset hours if 24 hours are over
delay = 2*8; sum = 1; break;
case 6: mm++;//increase minute counter
changed = 1;
if (mm>59){mm = 0;}; //reset minutes and increase hours if 60 minutes are over
delay = 2*8; sum = 1; break;
case 7: mp = 44; ma = 8; sleepmins = 6; break;
case 8: mp = 5; ma = 0; break;
}
}

// Port 1 interrupt service routine (CCR0 triggered)
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A(void)
{
if (ma<3){ if (mp != 27){ //should not change time when in time set mode mm++; //increase second counter // if (ss>59){mm++; ss = 0;};
if (mm>59){hh++; mm = 0;}; //reset minutes and increase hours if 60 minutes are over
if (hh>23){hh = 0;}; //reset hours if 24 hours are over
TACCR1 = TAR + frequency;
if (TACCR1 > TACCR0) {TACCR1 = frequency;}
sum = 1;
if (am==mm && ah==hh && al==1) {LPM3_EXIT;
CCTL1 |= CCIE;
CCTL2 |= CCIE;
TACCR1 = TAR + frequency;
if (TACCR1 > TACCR0) {TACCR1 = frequency;}
TACCR2 = TAR + pwmvalue;
if (TACCR2 > TACCR0) {TACCR2 = pwmvalue;}
P1OUT = 0x00; P2OUT &= 0x1F;
np = 40;
}
}
}
//if(mp==0 && delay == 0 && debounce == 0) {CCTL1 &= ~CCIE;};
if (sleepmins > 0) {sleepmins–;}
if (sleepmins == 0 && sleeptime == 2) {LPM3_EXIT; starttimers(); mp = 40;}
}
// Timer_A1 Interrupt Vector (TAIV) handler
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A1(void)
{
switch( TAIV )
{
case 2: //this is the counter for timing jobs CCR1
if (debounce == 1) {P2IE |= BUTTONPIN; P2IFG &= ~BUTTONPIN; debounce = 0;} //Button bei Erreichen von 1 aktiv schalten
if (debounce > 1) {debounce–;} //debouncewert reduzieren
if (delay > 0) {delay–;} // used for display timing
if (delay == 0) {
switch(mp){
case 6: al = 0; sleeptime = 0; break;
}
mp = np;
}
if (dotcount == 0) {switch (dot){
case 0: dot = 16;
break;
default: dot = 0; P2OUT &= ~BUTTONPIN; break;
}
dotcount = 4;
};
dotcount–;
switch (mp){
case 2: break;
case 16: dot = 16; break;
case 18: break;
case 20: break;
case 24: break;
case 26: break;
case 27: dot = 16; break;
case 30: break;
case 41: break;
case 43: break;
default: dot = 0; break;
}
TACCR1 = TAR+frequency; // Add Offset to CCR1
if (TACCR1 > TACCR0) {TACCR1 = frequency;}
break;
case 4: //this is the counter for the display digit rolling CCR2
P1OUT = 0xFF;
P2OUT &= ~0x1F;
switch(count)
{case 1:
switch (ma) {
case 3: switch (dot) {
case 16: P1OUT = zahl[d]; P2OUT |= 0x04;break;
default: P2OUT &= ~0x1F;break;
};
break;
case 5: switch (dot) {
case 16: P1OUT = zahl[d]; P2OUT |= 0x04;break;
default: P2OUT &= ~0x1F;break;
};
break;
default: P1OUT = zahl[d]; P2OUT |= 0x04;break;
}
count = 2;
break;
case 2:
switch (ma) {
case 3: switch (dot) {
case 16: P1OUT = zahl[c];P2OUT |= 0x02;break;
default: P2OUT &= ~0x1F;break;
};
break;
case 5: switch (dot) {
case 16: P1OUT = zahl[c];P2OUT |= 0x02;break;
default: P2OUT &= ~0x1F;break;
};
break;
default: P1OUT = zahl[c]-dot;P2OUT |= 0x02;break;
}
count = 3; break;
case 3:
switch (ma) {
case 4: switch (dot) {
case 16: P1OUT = zahl[b];P2OUT |= 0x01;break;
default: P2OUT &= ~0x1F;break;
};
break;
case 6: switch (dot) {
case 16: P1OUT = zahl[b];P2OUT |= 0x01;break;
default: P2OUT &= ~0x1F;break;
};
break;
default: P1OUT = zahl[b]-dot;P2OUT |= 0x01;break;
}
count = 4; break;
case 4: P1OUT = zahl[a];
switch (ma) {
case 4: switch (dot) {
case 16: P2OUT |= 0x08;break;
default: P2OUT &= ~0x1F;break;
};
break;
case 6: switch (dot) {
case 16: P2OUT |= 0x08;break;
default: P2OUT &= ~0x1F;break;
};
break;
default: P2OUT |= 0x08;break;
}
count = 1; break;}
if (sleeptime==1) {if (dot == 16){P2OUT ^= BUZZPIN;}
if (dot == 0) {P2OUT &=~ BUZZPIN;}};
TACCR2 = TAR + pwmvalue;
if (TACCR2 > TACCR0) {TACCR2 = pwmvalue;}
break;
case 10: break;
}
}

2 Gedanken zu „MSP 430 Alarm Clock

    1. steffen Beitragsautor

      Sorry, but i have not made a wiring Diagram, because connecting the sevensegment is very easy and you only need the sevensegment an additional button.

      Antworten

Kommentar verfassen