DS3232M RTC demo program. Tested on the K64F (this example) and the KL25Z, but should work on any platform by changing the SDA and SCL pins. USB serial baud rate is 230400, tested on TeraTerm. Demo includes setting the DS3232's time, turning on and off the 32KHz and 1Hz outputs and accessing the DS3232's temperature. Also included are DS3232 user RAM access tests and user RAM CRC data calculations. Since user RAM is battery backed up, CRC routines are included to insure that the data stored in user RAM is intact.

Dependencies:   ds3232m mbed mbed-rtos

Revision:
0:8d18e427a06b
Child:
1:c891c3930f4e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Dec 08 23:11:15 2014 +0000
@@ -0,0 +1,298 @@
+#include "mbed.h"
+#include "ds3232m.h"                        //Maxim RTC
+
+Serial pc(USBTX, USBRX);
+
+#define SDA0        PTE25
+#define SCL0        PTE24
+ds3232m rtc(SDA0, SCL0, 400000);            //Maxim real time clock
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Time variables
+
+time_t ctTime;                              //time structure
+int DST = 1;                                //Daylight Saving Time (or as defined in .ini file)
+int TZone = -8;                             //Time Zone from UTC (or as defined in .ini file)
+char timebuf_hms[10];                       //local time format buffer - 21:16:43
+char timebuf_dMyy[14];                      //local time format buffer - 01-Apr-2014
+char timebuf_dow[1];                        //local time format buffer - 5
+int StartTime = 0;                          //time we powered up
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//Variables for USB Serial Port RX
+
+uint32_t pcRxQty = 0;                       //RX data counter/pointer
+char pcRxBuffer[128];                       //RX data buffer
+bool pcRxLine = false;                      //CR or LF detected (end of line)
+bool pcRxEOB = false;                       //RX buffer is full!!! cannot accept any more characters
+char inchar = 0;                            //RX input character
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// This function is called when a character goes into the RX buffer.
+
+#define DOUPONELINE "\033[1A"
+#define BS          0x08                    //ascii backspace
+#define CR          0x0d                    //ascii CR
+#define LF          0x0a                    //ascii LF
+
+void PcRxChar(char inchar) {
+    if(inchar == CR) pc.printf(" %c %c", BS, BS);   //NOTE: Bug in K64F has issue with CR and/or LF, these 2 lines are needed
+    if(inchar == LF) pc.printf(" %c %c", BS, BS);
+    if(inchar == BS) { 
+        if(pcRxQty == 0) {
+            pcRxBuffer[pcRxQty] = 0;
+        } else {
+            pc.printf("%c %c", BS, BS);
+            pcRxQty--;
+            pcRxBuffer[pcRxQty] = 0;
+        }
+    } else if((inchar == CR) || (inchar == LF)) { 
+        pcRxLine = true;
+        pc.printf("\r\n");
+    } else {
+        if(pcRxQty < (sizeof(pcRxBuffer) - 2)) {
+            pcRxBuffer[pcRxQty] = inchar;
+            pcRxQty++;
+            pcRxBuffer[pcRxQty] = 0;
+            pc.printf("%c", pcRxBuffer[pcRxQty - 1]);
+        } else {
+            pc.printf ("\r\n*** pcRxBuffer is full!!\r\n");
+            pcRxEOB = true;
+        }
+    }
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Read received chars from USB UART
+
+void PcRxIRQnoRTOS(void){
+
+#if defined(TARGET_KL25Z)
+    NVIC_DisableIRQ(UART0_IRQn);        // n=0, 1 or 2  Disable Rx interrupt on kl25z
+#endif
+#if defined(TARGET_K64F)
+    NVIC_DisableIRQ(UART0_RX_TX_IRQn);  // n=0, 1 or 2  Disable Rx interrupt on k64f
+#endif
+#if defined(TARGET_LPC1768)
+    LPC_UART0->IER = 0;                 //Disable Rx interrupt on mbed1768
+#endif
+    while (pc.readable()) {
+        inchar = pc.getc();             //<<<<< broken here!!!!     //read data from USB
+        PcRxChar(inchar);               //go process char
+
+    }
+#if defined(TARGET_KL25Z)
+    NVIC_EnableIRQ(UART0_IRQn);         // n=0, 1 or 2  Re-enable Rx interrupt on kl25z
+#endif
+#if defined(TARGET_K64F)
+    NVIC_EnableIRQ(UART0_RX_TX_IRQn);   // n=0, 1 or 2  Re-enable Rx interrupt on k64f
+#endif
+#if defined(TARGET_LPC1768)
+    LPC_UART0->IER = 1;                 //RE-enable Rx interrupt on mbed1768
+#endif
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//clear RxData buffer with all 00's
+
+void pcClrLineBuf() {
+    pcRxQty = 0;                                                            // data counter/pointer
+    for(int i = 0; i < (sizeof(pcRxBuffer) - 1); i++) pcRxBuffer[i] = 0;    // clear out rx buffer
+    pcRxLine = false;
+    pcRxEOB = false;
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Update time
+
+void UpdateTimeRegs() {
+    strftime(timebuf_dMyy, 14, "%d-%b-%Y", localtime(&ctTime));
+    strftime(timebuf_hms, 10, "%H:%M:%S", localtime(&ctTime));
+    strftime(timebuf_dow, 1, "%u", localtime(&ctTime));
+}
+
+void UpdateTime() {
+    ctTime = time(NULL) + ((TZone + DST) * 3600);   //timezone and dst offsets
+    UpdateTimeRegs();
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// display current local date and time
+
+void PrintDateTime() {
+    pc.printf("Date: %s   ", timebuf_dMyy);
+    pc.printf("Time: %s \r\n", timebuf_hms);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//Manually set the date and time
+
+ds3232m::Time_rtc rtc_m = {};
+struct tm t;
+
+bool SetRTC() {
+    pc.printf("Enter current date and time:\n");
+    pc.printf("MM DD YY HH MM SS[enter]\n");  
+    pcClrLineBuf(); 
+     
+    //wait for string above
+    do{
+        wait_ms(10);
+    } while((pcRxLine == false) && (pcRxEOB == false));
+    
+    //load up the time structure
+    t.tm_year = (2000 + ((pcRxBuffer[6] - '0') * 10) + pcRxBuffer[7] - '0');
+    t.tm_mon =  (((pcRxBuffer[0] - '0') * 10) + pcRxBuffer[1] - '0');
+    t.tm_mday = (((pcRxBuffer[3] - '0') * 10) + pcRxBuffer[4] - '0');
+    t.tm_hour = (((pcRxBuffer[9] - '0') * 10) + pcRxBuffer[10] - '0');
+    t.tm_min = (((pcRxBuffer[12] - '0') * 10) + pcRxBuffer[13] - '0');
+    t.tm_sec = (((pcRxBuffer[15] - '0') * 10) + pcRxBuffer[16] - '0');
+    
+    //adjust for tm structure required values
+    t.tm_year = t.tm_year - 1900;
+    t.tm_mon = t.tm_mon - 1;  
+    t.tm_wday = t.tm_wday & 7;
+    
+    //if error exists, exit without changing time
+    if(t.tm_year < 113) return(1);
+    if(t.tm_mon > 12) return(1); 
+    if(t.tm_mday > 31) return(1);  
+    if(t.tm_hour > 23) return(1); 
+    if(t.tm_min > 59) return(1); 
+    if(t.tm_sec > 59) return(1); 
+    
+    //set up the DS3232's RTC
+    rtc_m.sec = t.tm_sec;
+    rtc_m.min = t.tm_min;
+    rtc_m.hour = t.tm_hour;
+    rtc_m.wday = t.tm_wday;
+    rtc_m.date = t.tm_mday;
+    rtc_m.mon = t.tm_mon + 1;
+    rtc_m.year = t.tm_year + 1900;
+    rtc.setTime(rtc_m);    //(time structure)
+
+    //set the mbed's time
+    time_t ctTime = mktime(&t);
+    //reset system up time since it will be out of whack once the time is updated
+    StartTime = ctTime;                         //have to change sysuptime now
+    ctTime = ctTime - (TZone + DST) * 3600;     //take out local time
+    set_time(ctTime);
+    UpdateTime();
+    return(0);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Load the local mbed-RTC from that external DS3232 RTC
+
+void loadRTC() {
+    //get data from DS3232
+    rtc.getTime(rtc_m);
+    t.tm_sec = rtc_m.sec;
+    t.tm_min = rtc_m.min;
+    t.tm_hour = rtc_m.hour;
+    t.tm_mday = rtc_m.date;
+    t.tm_mon = rtc_m.mon - 1;
+    t.tm_year = rtc_m.year - 1900;
+            
+    //set the mbed's time
+    time_t ctTime = mktime(&t);
+    ctTime = ctTime - (TZone + DST) * 3600;     //take out local time
+    set_time(ctTime);
+    UpdateTime(); 
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Pull the temperature out of the DS3232 RTC
+
+void Get3232Temp() {
+    pc.printf("%c", BS);
+    if(rtc.startTempCycle() == true) {
+        pc.printf(" - DS3232M start converstion ok \r\n");
+    } else {
+        pc.printf(" - DS3232M start converstion BUSY!!! \r\n");
+    }
+        
+    //wait for DS3232 temperature conversion to finish
+    int i = 80;
+    for(i = 80; i > 0; i--) {
+        wait_ms(20);
+        if((rtc.checkTempBusy()) == true) break;
+    }
+        
+    //timed out or display temperature
+    if(i > 0) {
+        pc.printf(" - DS3232M Temperature: %.2f\r\n", rtc.getTemperature());
+    } else {
+        pc.printf("*** DS3232M Temperature timeout!!!!\r\n");
+    }
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+
+int main() {
+    pc.baud(230400);
+    ctTime = time(NULL);
+    StartTime = ctTime;                     //get time we started up
+    pc.printf("\r\n\r\nDS3232M demo  08-DEC-2014  K. Braun\r\n");
+    
+    //pc RX character callback interrupt
+    pc.printf("Initializing Serial Port Rx Interrupt...   \r\n");
+    pc.attach(&PcRxIRQnoRTOS, pc.RxIrq);
+    
+    pc.printf("Checking the mbed's RTC...\r\n");
+    wait_ms(1.5);
+    ctTime = time(NULL);
+    
+    //first, see if K64F's RTC already running
+    if((StartTime == ctTime) || (ctTime <= 1000000000)) {
+        loadRTC();
+        StartTime = ctTime;
+        
+        //now see if DS3232's clock needs to be set
+        if(ctTime <= 1000000000) {
+            pc.printf("*** Local RTC stopped, initializing the RTC.  !!CHECK BATTERY!!\r\n");
+            pc.printf("*** Note: Time is incorrect, needs to be updated!!!\r\n");
+            
+            //set up the DS3232's clock
+            if(SetRTC() != 0) pc.printf("Entry Error!!");
+            pcClrLineBuf();
+        }
+    } 
+    
+    //sync up the mbed's time with the DS3232's time    
+    loadRTC();
+    StartTime = ctTime;
+    pc.printf(" - RTC Start Time:   ");
+    PrintDateTime();
+    pc.printf(" - Day of Week: %s\r\n", timebuf_dow);  //day of the week
+        
+    //get the DS3232's temperature
+    Get3232Temp();
+    
+    int CheckTime = ctTime;
+    pc.printf("Hit 'A' or 'a' key to turn on/off the 32KHz output\r\n");
+    pc.printf("Hit 'B' or 'b' key to turn on/off the 1Hz output (1Hz pin needs pull-up)\r\n");
+    pc.printf("Hit 't' key to get the DS3232's temperature\r\n");
+    pc.printf("Hit any other key to change the RTC\r\n\r\n");
+    
+    //Ready!!
+    while (true) {
+        wait_ms(200);
+        UpdateTime();
+        if(CheckTime != ctTime) {
+            CheckTime = ctTime;
+            pc.printf("%s", DOUPONELINE);
+            PrintDateTime();
+        }
+        if(pcRxQty != 0) {
+            if(pcRxBuffer[0] == 'A') rtc.set32KhzOutput(true, false);   //turn on 32KHz output
+            if(pcRxBuffer[0] == 'a') rtc.set32KhzOutput(false, false);  //turn off 32KHz output
+            if(pcRxBuffer[0] == 'B') rtc.set1hzOutput(true, false);   //turn on 1Hz output
+            if(pcRxBuffer[0] == 'b') rtc.set1hzOutput(false, false);  //turn off 1Hz output
+            if(pcRxBuffer[0] == 't') Get3232Temp();  //display the DS3232's temperature
+            if((pcRxBuffer[0] != 'a') && (pcRxBuffer[0] != 'A') && (pcRxBuffer[0] != 'b') && (pcRxBuffer[0] != 'B') && (pcRxBuffer[0] != 't') && (SetRTC() != 0)) pc.printf("Entry Error!!");
+            pc.printf("\r\n\r\n");
+            pcClrLineBuf();
+        }
+    }
+}
\ No newline at end of file