Jump to content
Sign in to follow this  
username

WDT as RTC

Recommended Posts

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;

}
 
 

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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;
        }
    }
}

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...