Under "download files" there is an code example "Real-Time Clock Routines for the DS5000T" Its working when I use the small memory model, but not when I'm just changing to use the large memory model from the IDE. Then it just displays zeroes. I hope someone have a solution to that problem! Best regards PL Pang There is 8k memory on the ds5000t. I set the mcon = 30 from the command line, before download.
#include <stdio.h> #include <string.h> #include <absacc.h> #include <intrins.h> typedef unsigned char BYTE ; typedef unsigned int ULONG; #define ECE2 0x04 sfr MCON = 0xC6; sfr PCON = 0x87; sfr TCON = 0x88; sfr TMOD = 0x89; sfr TH1 = 0x8D; sfr SCON = 0x98; sbit EA = 0xAF; sbit TR1 = 0x8E; sbit TI = 0x99; sbit P2_7 = 0xA7; struct rtclock_st { unsigned char hsecs; unsigned char secs; unsigned char minutes; unsigned char hours; unsigned char day; unsigned char date; unsigned char month; unsigned char year; }; extern code char *day_of_week []; unsigned char rtc_read_byte (void); void rtc_write_byte ( unsigned char val); void rtclock_initialize (void); void rtclock_stop (void); void rtclock_get ( struct rtclock_st *rtc); void rtclock_set ( struct rtclock_st *rtc); #define INT_DISABLE EA = 0 #define INT_ENABLE EA = 1 #define INT_SAVE {unsigned char intsave = EA /* save ints */ #define INT_RESTORE EA = intsave;} /* restore ints */ #define RTC_READ XBYTE [0x0004] #define RTC_WRITE(b) XBYTE [0x0000 | ((b) & 0x0001)] static code char error_date [] = "Date Error"; code char *day_of_week [] = { "Sunday", ... "Saturday", error_date, error_date, error_date, }; unsigned char rtc_read_byte (void) { register unsigned char i; register unsigned char dat; MCON |= ECE2; dat = 0; for (i = 0; i < 8; i++) { dat >>= 1; dat &= 0x7F; dat |= (RTC_READ & 0x80); } MCON &= ~ECE2; return (dat); } void rtc_write_byte ( unsigned char val) { register unsigned char i;//register meget brugt var register unsigned char dummy; MCON |= ECE2; for (i = 0; i < 8; i++) { dummy = RTC_WRITE(val); /* ignore warnings */ val >>= 1; } MCON &= ~ECE2; } static void rtc_reset (void) { register unsigned char i; for (i = 0; i < 9; i++) { rtc_read_byte (); } } static void rtc_init (void) { register unsigned char i; register unsigned char dat; dat = 0xC5; for (i = 0; i < 4; i++) { rtc_write_byte (dat); dat ^= 0xFF; rtc_write_byte (dat); dat = _crol_ (dat,4); } } void rtclock_initialize (void) { register unsigned char rtbuf [8];// indfort register register unsigned char i; INT_SAVE; INT_DISABLE; rtc_reset (); INT_RESTORE; INT_SAVE; INT_DISABLE; rtc_init (); for (i = 0; i < 8; i++) { rtbuf [i] = rtc_read_byte (); } INT_RESTORE; if (((rtbuf [4] & 0x20) == 0x20) || /* if OSC is stopped */ ((rtbuf [3] & 0x80) == 0x80)) /* if time is 12 hour mode */ { rtbuf [4] &= ~0x20; rtbuf [3] &= ~0x80; INT_SAVE; INT_DISABLE; rtc_init (); for (i = 0; i < 8; i++) { rtc_write_byte (rtbuf [i]); } INT_RESTORE; } INT_SAVE; INT_DISABLE; rtc_reset (); INT_RESTORE; } #if 0 void rtclock_stop (void) { xdata unsigned char rtbuf [8]; register unsigned char i; INT_SAVE; INT_DISABLE; rtc_reset (); INT_RESTORE; INT_SAVE; INT_DISABLE; rtc_init (); for (i = 0; i < 8; i++) { rtbuf [i] = rtc_read_byte (); } INT_RESTORE; INT_SAVE; INT_DISABLE; rtc_reset (); INT_RESTORE; if ((rtbuf [4] & 0x20) == 0) /* if OSC is not stopped */ { rtbuf [4] |= 0x20; INT_SAVE; INT_DISABLE; rtc_init (); for (i = 0; i < 8; i++) { rtc_write_byte (rtbuf [i]); } INT_RESTORE; } INT_SAVE; INT_DISABLE; rtc_reset (); INT_RESTORE; } #endif void rtclock_get(struct rtclock_st *rtc) { unsigned char rtbuf [8]; register unsigned char i; INT_SAVE; INT_DISABLE; rtc_reset (); INT_RESTORE; INT_SAVE; INT_DISABLE; rtc_init (); for (i = 0; i < 8; i++) { rtbuf [i] = rtc_read_byte (); } INT_RESTORE; INT_SAVE; INT_DISABLE; rtc_reset (); INT_RESTORE; rtc->hsecs = (((rtbuf [0] & 0xF0) >> 4) * 10) + (rtbuf [0] & 0x0F);//bcd til hex rtc->secs = (((rtbuf [1] & 0x70) >> 4) * 10) + (rtbuf [1] & 0x0F); rtc->minutes = (((rtbuf [2] & 0x70) >> 4) * 10) + (rtbuf [2] & 0x0F); rtc->hours = (((rtbuf [3] & 0x30) >> 4) * 10) + (rtbuf [3] & 0x0F); rtc->day = (rtbuf [4] & 0x07); rtc->date = (((rtbuf [5] & 0x30) >> 4) * 10) + (rtbuf [5] & 0x0F); rtc->month = (((rtbuf [6] & 0x10) >> 4) * 10) + (rtbuf [6] & 0x0F); rtc->year = (((rtbuf [7] & 0xF0) >> 4) * 10) + (rtbuf [7] & 0x0F); } void rtclock_set ( struct rtclock_st *rtc) { unsigned char rtbuf [8]; register unsigned char i; rtbuf [0] = (((rtc->hsecs / 10) & 0x0F) << 4) | (rtc->hsecs % 10); rtbuf [1] = (((rtc->secs / 10) & 0x07) << 4) | (rtc->secs % 10); rtbuf [2] = (((rtc->minutes / 10) & 0x07) << 4) | (rtc->minutes % 10); rtbuf [3] = (((rtc->hours / 10) & 0x03) << 4) | (rtc->hours % 10); rtbuf [4] = (rtc->day & 7); rtbuf [5] = (((rtc->date / 10) & 0x03) << 4) | (rtc->date % 10); rtbuf [6] = (((rtc->month / 10) & 0x01) << 4) | (rtc->month % 10); rtbuf [7] = (((rtc->year / 10) & 0x0F) << 4) | (rtc->year % 10); INT_SAVE; INT_DISABLE; rtc_reset (); INT_RESTORE; INT_SAVE; INT_DISABLE; rtc_init (); for (i = 0; i < 8; i++) { rtc_write_byte (rtbuf [i]); } INT_RESTORE; INT_SAVE; INT_DISABLE; rtc_reset (); INT_RESTORE; } void main (void) { struct rtclock_st rtc; ULONG timeout = 10; TMOD |= 0x21; SCON = 0x50; TH1 = 253; TR1 = 1; TI = 1; PCON = 0x80; P2_7 = 0; while (1) { if (--timeout == 0) { rtclock_get (&rtc); timeout = 5; printf ("Tid: "); printf ("%02.2u:", (unsigned) rtc.hours); printf ("%02.2u:", (unsigned) rtc.minutes); printf ("%02.2u.", (unsigned) rtc.secs); printf ("%02.2u\n",(unsigned) rtc.hsecs); printf ("Dato: "); printf ("%02.2u/", (unsigned) rtc.date); printf ("%02.2u/", (unsigned) rtc.month); printf ("%02.2u ",(unsigned) rtc.year); printf ("%s\n", day_of_week [rtc.day]); } } }
It's right that the nonvolatile ram are divided as you describe first code and then xdata area. But if I address xdata outside that nv area (the partition adr. to the 32k range adr.) it will be access through the expanded bus. Do you have external RAM attached to the DS5000T? If so, then you can certainly access it as XDATA starting at 0000h. The problem is that you cannot access XDATA and the RTC at the same time (because setting the ECE2 bit changes where movx writes go). When you changed the program to large model, the rtc_read_byte and rtc_write_byte functions also changed to access the RTC and XDATA (for arguments and local variables) without switching the ECE2 bit. My suggestion is to change the types for variables in these functions to data. Furthermore, you'll have to copy the argument of rtc_write_byte to a local data variable. Jon
Thank you very much Jon and Stefan! RTC is working with large memory model now. I have a memory map can controller on xdata adr.0x0 - 0x80. Pih Lung