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
  • According to the linker map, XDATA starts at 0000h. On the DS5000 devices I've used, CODE and XDATA share the same memory and there is partition which separates the two. Everything below the partition is CODE and everything above is XDATA.

    So, if the partition address is set to 0x1000, then CODE goes from 0000h to 0FFFh and XDATA goes from 1000h to the end of the device's memory.

    If you are putting your CODE on the chip and you're not using external ROM, then XDATA can't start at 0.

    Jon

Reply
  • According to the linker map, XDATA starts at 0000h. On the DS5000 devices I've used, CODE and XDATA share the same memory and there is partition which separates the two. Everything below the partition is CODE and everything above is XDATA.

    So, if the partition address is set to 0x1000, then CODE goes from 0000h to 0FFFh and XDATA goes from 1000h to the end of the device's memory.

    If you are putting your CODE on the chip and you're not using external ROM, then XDATA can't start at 0.

    Jon

Children
  • Thanks Jon for your 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. As far as I can see there is nothing wrong with xdata start at addr. 0.
    I tried to remove it xdata 0x0-0x80, but still the RTC is not working with the large memory model, only with the small.
    How can I force the rtclock_initialize and rtclock_set varibles to be placed in data instead of xdata in large mmodel?

    I'm using a DS5000T 32K now.

    BL51 BANKED LINKER/LOCATER V5.03                                                        07/29/2003  11:56:22  PAGE 1
    
    
    BL51 BANKED LINKER/LOCATER V5.03, INVOKED BY:
    F:\KEIL\C51\BIN\BL51.EXE hkII.obj, startup.obj TO _hkII CODE (0X0-0X5FFF) XDATA (0X6000-0X7FFF)
    
    
    MEMORY MODEL: SMALL OK
    
    
    INPUT MODULES INCLUDED:
      hkII.obj (HKII)
      startup.obj (?C_STARTUP)
      F:\KEIL\C51\LIB\C51S.LIB (?C?CLDPTR)
      F:\KEIL\C51\LIB\C51S.LIB (?C?CLDOPTR)
      F:\KEIL\C51\LIB\C51S.LIB (?C?CSTPTR)
      F:\KEIL\C51\LIB\C51S.LIB (?C?CSTOPTR)
      F:\KEIL\C51\LIB\C51S.LIB (PRINTF)
      F:\KEIL\C51\LIB\C51S.LIB (?C?PLDIIDATA)
      F:\KEIL\C51\LIB\C51S.LIB (?C?CCASE)
      F:\KEIL\C51\LIB\C51S.LIB (PUTCHAR)
    
    
    LINK MAP OF MODULE:  _hkII (HKII)
    
    
                TYPE    BASE      LENGTH    RELOCATION   SEGMENT NAME
                -----------------------------------------------------
    
                * * * * * * *   D A T A   M E M O R Y   * * * * * * *
                REG     0000H     0008H     ABSOLUTE     "REG BANK 0"
                DATA    0008H     0009H     UNIT         ?DT?RTCLOCK_INITIALIZE?HKII
                DATA    0011H     0009H     UNIT         ?DT?_RTCLOCK_SET?HKII
                        001AH     0006H                  *** GAP ***
                BIT     0020H.0   0001H.1   UNIT         _BIT_GROUP_
                        0021H.1   0000H.7                *** GAP ***
                DATA    0022H     001EH     UNIT         _DATA_GROUP_
                IDATA   0040H     0001H     UNIT         ?STACK
    
                * * * * * * *   C O D E   M E M O R Y   * * * * * * *
                CODE    0000H     0003H     ABSOLUTE
                CODE    0003H     035CH     UNIT         ?PR?PRINTF?PRINTF
                CODE    035FH     0107H     UNIT         ?PR?_RTCLOCK_SET?HKII
                CODE    0466H     00EAH     UNIT         ?PR?_RTCLOCK_GET?HKII
                CODE    0550H     00D9H     UNIT         ?PR?MAIN?HKII
                CODE    0629H     00B0H     UNIT         ?C?LIB_CODE
                CODE    06D9H     0098H     UNIT         ?CO?HKII
                CODE    0771H     0053H     UNIT         ?PR?RTCLOCK_INITIALIZE?HKII
                CODE    07C4H     002AH     UNIT         ?PR?RTC_INIT?HKII
                CODE    07EEH     0027H     UNIT         ?PR?PUTCHAR?PUTCHAR
                CODE    0815H     001DH     UNIT         ?PR?RTC_READ_BYTE?HKII
                CODE    0832H     001CH     UNIT         ?PR?_RTC_WRITE_BYTE?HKII
                CODE    084EH     0012H     UNIT         ?PR?RTC_RESET?HKII
                CODE    0860H     000CH     UNIT         ?C_C51STARTUP
    
    

    BL51 BANKED LINKER/LOCATER V5.03                                                        07/29/2003  12:30:01  PAGE 1
    
    
    BL51 BANKED LINKER/LOCATER V5.03, INVOKED BY:
    F:\KEIL\C51\BIN\BL51.EXE hkII.obj, startup.obj TO _hkII CODE (0X0-0X5FFF) XDATA (0X6000-0X7FFF)
    
    
    MEMORY MODEL: LARGE Bad
    
    
    INPUT MODULES INCLUDED:
      hkII.obj (HKII)
      startup.obj (?C_STARTUP)
      F:\KEIL\C51\LIB\C51L.LIB (?C?CLDPTR)
      F:\KEIL\C51\LIB\C51L.LIB (?C?CLDOPTR)
      F:\KEIL\C51\LIB\C51L.LIB (?C?CSTPTR)
      F:\KEIL\C51\LIB\C51L.LIB (?C?CSTOPTR)
      F:\KEIL\C51\LIB\C51L.LIB (?C?IILDX)
      F:\KEIL\C51\LIB\C51L.LIB (PRINTF)
      F:\KEIL\C51\LIB\C51L.LIB (?C?PLDIXDATA)
      F:\KEIL\C51\LIB\C51L.LIB (?C?PSTXDATA)
      F:\KEIL\C51\LIB\C51L.LIB (?C?CCASE)
      F:\KEIL\C51\LIB\C51L.LIB (PUTCHAR)
    
    
    LINK MAP OF MODULE:  _hkII (HKII)
    
    
                TYPE    BASE      LENGTH    RELOCATION   SEGMENT NAME
                -----------------------------------------------------
    
                * * * * * * *   D A T A   M E M O R Y   * * * * * * *
                REG     0000H     0008H     ABSOLUTE     "REG BANK 0"
                DATA    0008H     0005H     UNIT         _DATA_GROUP_
                        000DH     0013H                  *** GAP ***
                BIT     0020H.0   0001H.1   UNIT         _BIT_GROUP_
                        0021H.1   0000H.7                *** GAP ***
                IDATA   0022H     0001H     UNIT         ?STACK
    
                * * * * * * *  X D A T A   M E M O R Y  * * * * * * *
                        0000H     6000H                  *** GAP ***
                XDATA   6000H     0032H     UNIT         _XDATA_GROUP_
                XDATA   6032H     0009H     UNIT         ?XD?RTCLOCK_INITIALIZE?HKII
                XDATA   603BH     0009H     UNIT         ?XD?_RTCLOCK_SET?HKII
    
                * * * * * * *   C O D E   M E M O R Y   * * * * * * *
                CODE    0000H     0003H     ABSOLUTE
                CODE    0003H     0365H     UNIT         ?PR?PRINTF?PRINTF
                CODE    0368H     0119H     UNIT         ?PR?MAIN?HKII
                CODE    0481H     0111H     UNIT         ?PR?_RTCLOCK_SET?HKII
                CODE    0592H     00F1H     UNIT         ?PR?_RTCLOCK_GET?HKII
                CODE    0683H     00D6H     UNIT         ?C?LIB_CODE
                CODE    0759H     0098H     UNIT         ?CO?HKII
                CODE    07F1H     007BH     UNIT         ?PR?RTCLOCK_INITIALIZE?HKII
                CODE    086CH     002EH     UNIT         ?PR?RTC_INIT?HKII
                CODE    089AH     0027H     UNIT         ?PR?PUTCHAR?PUTCHAR
                CODE    08C1H     001FH     UNIT         ?PR?_RTC_WRITE_BYTE?HKII
                CODE    08E0H     001DH     UNIT         ?PR?RTC_READ_BYTE?HKII
                CODE    08FDH     0015H     UNIT         ?PR?RTC_RESET?HKII
                CODE    0912H     000CH     UNIT         ?C_C51STARTUP
    
    BL51 BANKED LINKER/LOCATER V5.03                                                      07/29/2003  12:30:01  PAGE 2
    
    

  • There are keywords to force a specific memory space:

    char xdata a;
    char data a;
    char idata a;
    char pdata a;
    char code a;

    Unfortunately I don't know anything about the DS5000 so I can't really help you with that.

    Stefan

  • 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