username 198 Posted April 14, 2013 Share Posted April 14, 2013 Normally the first thing many of us hobbyists do is disable the WDT. However, considering the very limited amount of timers on the msp430 value line series, this is quite wasteful. Heres a simple application of the WDT as a basic RTC because godforbid we use the WDT as a WDT. in order for this to be accurate, you need an external crystal of 32.768khz #include "stdint.h" uint8_t counts=0; uint8_t secs=0; uint8_t mins=0; uint8_t hours=0; void rtc_setup() { WDTCTL = WDT_ADLY_16; // WDT 0.015625ms or 64 Hz IE1 |= WDTIE; // Enable WDT interrupt __enable_interrupt(); } // Watchdog Timer interrupt service routine #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void) { counts++; // Interrupts every 1/64s if(counts>63) { counts=0; secs++; } if(secs>59) { mins++; secs=0; } if(mins>59) { hours =hours%12 +1; mins=0; } } void get_time(char * buffer) // format hours:mins:secs { uint8_t local_data=hours; buffer[0]= local_data/10 + '0'; local_data %=10; buffer[1]= local_data + '0'; buffer[2]= ':'; local_data =mins; buffer[3]= local_data/10 +'0'; local_data %=10; buffer[4]= local_data +'0'; buffer[5]= ':'; local_data = secs; buffer[6] = local_data/10 + '0'; local_data %= 10; buffer[7]= local_data +'0'; buffer[8]=0; } GeekDoc and yyrkoon 2 Quote Link to post Share on other sites
ike 53 Posted April 14, 2013 Share Posted April 14, 2013 Cool, but why don't you use WDT_ADLY_1000 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL) /* 1000ms " */ . And where did you explicitly setup ACLK to use xtal generator, where did you setup xtal generator to add 12pF and where did you check xtal lock? #include "stdint.h" uint8_t secs=0; uint8_t mins=0; uint8_t hours=0; void rtc_setup() { WDTCTL = WDT_ADLY_1000; // WDT 1000ms BCSCTL3 = XCAP_3; /* XIN/XOUT Cap : 12.5 pF */ do{ IFG1 &= ~OFIFG; // Clear OSCFault flag __delay_cycles(100); }while (IFG1 & OFIFG); IE1 |= WDTIE; // Enable WDT interrupt _enable_interrupts(); } // Watchdog Timer interrupt service routine #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void){ secs++; if(secs>59){ mins++; secs=0; } if(mins>59) { hours++; hours =hours%24 +1; mins=0; } } void get_time(char * buffer) // format hours:mins:secs { uint8_t local_data=hours; buffer[0]= local_data/10 + '0'; local_data %=10; buffer[1]= local_data + '0'; buffer[2]= ':'; local_data =mins; buffer[3]= local_data/10 +'0'; local_data %=10; buffer[4]= local_data +'0'; buffer[5]= ':'; local_data = secs; buffer[6] = local_data/10 + '0'; local_data %= 10; buffer[7]= local_data +'0'; buffer[8]=0; } *this code is not tested. It's just written in this edit box. I hope that someone will test it. Quote Link to post Share on other sites
roadrunner84 466 Posted April 14, 2013 Share Posted April 14, 2013 I used the wdt for timekeeping in my binary watch project. Since I didn't need second resolution, I reduced the wdt interval to 2 seconds. Quote Link to post Share on other sites
username 198 Posted April 14, 2013 Author Share Posted April 14, 2013 Cool, but why don't you use WDT_ADLY_1000 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL) /* 1000ms " */ . And where did you explicitly setup ACLK to use xtal generator, where did you setup xtal generator to add 12pF and where did you check xtal lock? XIN & XOUT are the default functionality of P2.6 & P2.7 if i'm not mistaken. By default, ACLK is set to XIN & XOUT. Furthermore, the 12pF is not necessary depending on the crystal. Finally, I didn't need 1000ms tick so I used 15.6ms. Less interrupts -> less overhead. yyrkoon 1 Quote Link to post Share on other sites
oPossum 1,083 Posted April 15, 2013 Share Posted April 15, 2013 A 1000 ms (1 second) period would be fewer interrupts than a 15.625 ms period. Once per second vs 64 times per second. The test for limits of seconds/minutes/hours can be nested for a bit more efficiency as shown here: http://forum.43oh.com/topic/1957-software-real-time-clock-rtc-two-methods/ The limit only has to be tested when the corresponding variable is incremented. if(++counts > 63) { counts = 0; if(++secs > 59) { secs = 0; if(++mins > 59) { mins = 0; if(++hours > 12) hours = 1; } } } username, ike and GeekDoc 3 Quote Link to post Share on other sites
username 198 Posted April 15, 2013 Author Share Posted April 15, 2013 Thanks for the link & the tips. My bad, I read Ike's post too quickly. For some reason I thought he meant 1ms ticks :? . ~16ms was nice in order to schedule other system events. 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.