This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to use the realtime clock on the DS5000T with large memory model

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

Parents
  • 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

Reply
  • 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

Children