gwdeveloper 275 Posted October 23, 2011 Share Posted October 23, 2011 I saw this project hit Hackaday http://hackaday.com/2011/10/13/build-a-binary-wall-clock-for-just-a-few-bucks/ a few weeks ago and was inspired to make my own with a Launchpad. So, last night I got out the leds, resistors and a launchpad and made it happen. I'm only using one button to increment minutes and just setting the time via the debugger for now. I know others on here have made a binary clock (@sugaraddict), but I did this one with nothing but the LP, resistors and LEDs using all I/O of a G2553 and no shift registers. [attachment=0]binary_rtc.png[/attachment] /****************************************************************/ /* Greg Whitmore */ /* greg@gwdeveloper.net */ /* www.gwdeveloper.net */ /****************************************************************/ /* released under the "Use at your own risk" license */ /* use it how you want, where you want and have fun */ /* debugging the code. */ /* MSP430G2553 Real Time Binary Clock */ /****************************************************************/ #include int sec, min, hour; int minOnesPlace, minTensPlace, hourOnesPlace, hourTensPlace; void BCS_init(void); void WDT_init(void); void GPIO_init(void); void TA0_init(void); void main(void) { BCS_init(); WDT_init(); GPIO_init(); TA0_init(); __enable_interrupt(); // Set global interrupt enable // set initial time sec = 0; min = 30; hour = 4; while (1) { LPM3; // enter lowest power module with ACLK active if (sec > 59) // check seconds; increase minutes if needed { sec = 0; min++; } if (min > 59) // check minutes; increase hours if needed { min = 0; hour++; } if (hour == 24) // check 24 hour clock; rollover if needed { hour = 0; } // split minutes and hours to ones and tens place values minOnesPlace = min % 10; switch(minOnesPlace) { case 0: P1OUT &= ~(BIT4 + BIT5 + BIT6+ BIT7); break; case 1: P1OUT |= BIT4; P1OUT &= ~(BIT5 + BIT6 + BIT7); break; case 2: P1OUT |= BIT5; P1OUT &= ~(BIT4 + BIT6 + BIT7); break; case 3: P1OUT |= (BIT4 + BIT5); P1OUT &= ~(BIT6 + BIT7); break; case 4: P1OUT |= BIT6; P1OUT &= ~(BIT4 + BIT5 + BIT7); break; case 5: P1OUT |= (BIT4 + BIT6); P1OUT &= ~(BIT5 + BIT7); break; case 6: P1OUT |= (BIT5 + BIT6); P1OUT &= ~(BIT4 + BIT7); break; case 7: P1OUT |= (BIT4 + BIT5 + BIT6); P1OUT &= ~(BIT7); break; case 8: P1OUT |= BIT7; P1OUT &= ~(BIT4 + BIT5 + BIT6); break; case 9: P1OUT |= (BIT4 + BIT7); P1OUT &= ~(BIT5 + BIT6); break; default: break; } minTensPlace = (min / 10) % 10; switch(minTensPlace) { case 0: P1OUT &= ~(BIT0 + BIT1 + BIT2); break; case 1: P1OUT |= BIT2; P1OUT &= ~(BIT0 + BIT1); break; case 2: P1OUT |= BIT1; P1OUT &= ~(BIT0 + BIT2); break; case 3: P1OUT |= (BIT2 + BIT1); P1OUT &= ~(BIT0); break; case 4: P1OUT |= BIT0; P1OUT &= ~(BIT2 + BIT1); break; case 5: P1OUT |= (BIT2 + BIT0); P1OUT &= ~(BIT1); break; default: break; } hourOnesPlace = hour % 10; switch(hourOnesPlace) { case 0: P2OUT &= ~(BIT2 + BIT3 + BIT4 + BIT5); break; case 1: P2OUT |= BIT2; P2OUT &= ~(BIT3 + BIT4 + BIT5); break; case 2: P2OUT |= BIT3; P2OUT &= ~(BIT2 + BIT4 + BIT5); break; case 3: P2OUT |= (BIT2 + BIT3); P2OUT &= ~(BIT4 + BIT5); break; case 4: P2OUT |= BIT4; P2OUT &= ~(BIT2 + BIT3 + BIT5); break; case 5: P2OUT |= (BIT2 + BIT4); P2OUT &= ~(BIT3 + BIT5); break; case 6: P2OUT |= (BIT3 + BIT4); P2OUT &= ~(BIT2 + BIT5); break; case 7: P2OUT |= (BIT2 + BIT3 + BIT4); P2OUT &= ~(BIT5); break; case 8: P2OUT |= BIT5; P2OUT &= ~(BIT2 + BIT3 + BIT4); break; case 9: P2OUT |= (BIT2 + BIT5); P2OUT &= ~(BIT3 + BIT4); break; default: break; } hourTensPlace = (hour / 10) % 10; switch(hourTensPlace) { case 0: P2OUT |= (BIT0 + BIT1); break; case 1: P2OUT |= BIT1; P2OUT &= ~(BIT0); break; case 2: P2OUT |= BIT0; P2OUT &= ~(BIT1); break; default: break; } } } // clock init for 32.768kHz operation from XT1 void BCS_init(void) { BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0; // dco; /1; /1 if (CALBC1_1MHZ != 0xFF) { DCOCTL = 0x00; BCSCTL1 = CALBC1_1MHZ; // calibrated 1MHz DCOCTL = CALDCO_1MHZ; } BCSCTL1 |= XT2OFF + DIVA_0; // XT2 off; /1 BCSCTL3 = XT2S_0 + LFXT1S_0 + XCAP_1; // 32.768kHz crystal; ~6pf load } // wdt init as interval timer; used for debouncing S1 void WDT_init(void) { WDTCTL = WDTPW + WDTTMSEL + WDTSSEL + WDTIS1; // interval timer; aclk IFG1 &= ~(WDTIFG); // clear WDT flags IE1 |= WDTIE; // enable WDT interrupt } // gpio init void GPIO_init(void) { // setup push button; edge interrupt; clear port 1 flags P1OUT = BIT3; P1REN = BIT3; P1IES = BIT3; P1IE = BIT3; P1IFG = 0; // led outputs P1DIR = BIT0 + BIT1 + BIT2 + BIT4 + BIT5 + BIT6 + BIT7; P2DIR = BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5; P2OUT = 0; } void TA0_init(void) { TA0CCTL0 = CM_0 + CCIS_0 + OUTMOD_5 + CCIE; // no capture; CCI0A; PWM reset TA0CCR0 = 32767; TA0CTL = TASSEL_1 + ID_0 + MC_1; // aclk source; /1; up mode } // push button ISR #pragma vector=PORT1_VECTOR __interrupt void add_time_isr(void) { P1IFG &= ~BIT3; P1IE &= ~BIT3; // wdt interval as debouncer IFG1 &= ~WDTIFG; WDTCTL = (WDTCTL & 7) + WDTCNTCL + WDTPW + WDTTMSEL; IE1 |= WDTIE; // increase minute counter min++; } // timerA isr; interrupt every 1 sec #pragma vector=TIMER0_A0_VECTOR __interrupt void ta_1sec_isr(void) { sec++; // increase seconds counter LPM3_EXIT; } // wdt isr clear port 1 interrupt flags #pragma vector=WDT_VECTOR __interrupt void wdt_isr(void) { IE1 &= ~WDTIE; P1IFG &= ~BIT3; P1IE |= BIT3; } Not sure of the final accuracy as the battery I was using to test it overnight, died. bluehash 1 Quote Link to post Share on other sites
bluehash 1,581 Posted October 23, 2011 Share Posted October 23, 2011 o_O Thanks! Having different colors for hours/minutes would nice. Quote Link to post Share on other sites
SugarAddict 227 Posted October 23, 2011 Share Posted October 23, 2011 I ended up using usb to power my clock... The two AA setup I had at first only lasted 6 days before dying with as much power saving as I could muster... If you're using the XT1 then you shouldn't have much accuracy problem. Mine has run for three weeks before I moved it and it was still spot on. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.