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]); } } }
Thanks Stefan for your reply! I can't see any conflict between rtc variables and normal xdata variables. if address 0x32 mean 0x1832..(see _hkII.m51)I don't right undestand why RTC and the variable i xdata is the root of the problem. When I access the RTC register ece2 is high -> xdata ram disablet. I could see a problem if I read from RTC to xdata variables, but that is not the case. RTC read and write use register on-chip variables, they are availible when ece2 is high. I told the linker the startadr of xdata from: In BL51 locate dialog set xdata range: 0X1800-0X1fff (isn't here to tell the linker where to start the xdata memory? It doesn't help to change the range to 0x1860-0x1fff, to protect the rtc location) In startup.a51:XDATASTART EQU 1800H (startup.a51 is that always included or only if there's an assembler code modules in your app?)
_hkII.m51 mapfile: BL51 BANKED LINKER/LOCATER V5.03 07/09/2003 10:52:20 PAGE 1 BL51 BANKED LINKER/LOCATER V5.03, INVOKED BY: F:\KEIL\C51\BIN\BL51.EXE hkII.obj TO _hkII CODE (0X0-0X17FF) XDATA (0X0-0X80, 0X1800-0X1FFF) MEMORY MODEL: LARGE INPUT MODULES INCLUDED: hkII.obj (HKII) 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 * * * * * * * XDATA 0000H 0032H UNIT _XDATA_GROUP_ RTC locations but no overlaying with other variables! XDATA 0032H 0009H UNIT ?XD?RTCLOCK_INITIALIZE?HKII XDATA 003BH 0009H UNIT ?XD?_RTCLOCK_SET?HKII * * * * * * * C O D E M E M O R Y * * * * * * * OVERLAY MAP OF MODULE: _hkII (HKII) SEGMENT BIT_GROUP DATA_GROUP XDATA_GROUP +--> CALLED SEGMENT START LENGTH START LENGTH START LENGTH ------------------------------------------------------------------------------------------- ?C_C51STARTUP ----- ----- ----- ----- ----- ----- +--> ?PR?MAIN?HKII ?PR?MAIN?HKII ----- ----- ----- ----- 0000H 000AH +--> ?PR?_RTCLOCK_GET?HKII +--> ?CO?HKII +--> ?PR?PRINTF?PRINTF ?PR?_RTCLOCK_GET?HKII ----- ----- ----- ----- 000AH 0009H +--> ?PR?RTC_RESET?HKII +--> ?PR?RTC_INIT?HKII +--> ?PR?RTC_READ_BYTE?HKII ?PR?RTC_RESET?HKII ----- ----- ----- ----- ----- ----- +--> ?PR?RTC_READ_BYTE?HKII ?PR?RTC_INIT?HKII ----- ----- ----- ----- ----- ----- +--> ?PR?_RTC_WRITE_BYTE?HKII ?PR?_RTC_WRITE_BYTE?HKII ----- ----- ----- ----- 0013H 0001H ?PR?PRINTF?PRINTF 0020H.0 0001H.1 0008H 0005H 000AH 0028H +--> ?PR?PUTCHAR?PUTCHAR SYMBOL TABLE OF MODULE: _hkII (HKII) VALUE TYPE NAME ---------------------------------- ------- MODULE HKII C:0000H SYMBOL _ICE_DUMMY_ C:0481H PUBLIC _rtclock_set C:07D3H PUBLIC day_of_week B:00A8H.7 PUBLIC EA C:07F1H PUBLIC rtclock_initialize B:00A0H.7 PUBLIC P2_7 B:0098H.1 PUBLIC TI C:0368H PUBLIC main C:07C8H SYMBOL error_dateC:08C1H PUBLIC _rtc_write_byte C:0907H SYMBOL rtc_reset B:0088H.6 PUBLIC TR1 C:08E0H PUBLIC rtc_read_byte C:0878H SYMBOL rtc_init C:0592H PUBLIC _rtclock_get ------- PROC RTC_READ_BYTE ------- DO D:0006H SYMBOL i D:0007H SYMBOL dat ------- ENDDO ------- ENDPROC RTC_READ_BYTE ------- PROC _RTC_WRITE_BYTE D:0007H SYMBOL val ------- DO D:0006H SYMBOL i X:0013H SYMBOL dummy _RTC_WRITE_BYTE ------- PROC RTC_RESET ------- DO D:0005H SYMBOL i ------- ENDDO ------- ENDPROC RTC_RESET ------- PROC RTC_INIT ------- DO D:0004H SYMBOL i D:0005H SYMBOL dat ------- ENDPROC RTC_INIT ------- PROC RTCLOCK_INITIALIZE ------- DO X:0032H SYMBOL rtbuf D:0005H SYMBOL i RTCLOCK_INITIALIZE ------- PROC _RTCLOCK_GET D:0001H SYMBOL rtc ------- DO X:000AH SYMBOL rtbuf D:0005H SYMBOL i ------- DO X:0012H SYMBOL intsave X:0012H SYMBOL intsave X:0012H SYMBOL intsave ------- ENDDO ------- DO X:0012H SYMBOL intsave X:0012H SYMBOL intsave ------- ENDDO ------- DO X:0012H SYMBOL intsave ------- ENDDO ------- ENDDO ------- ENDPROC _RTCLOCK_GET ------- PROC _RTCLOCK_SET D:0001H SYMBOL rtc ------- DO X:003BH SYMBOL rtbuf D:0005H SYMBOL i ------- DO X:0043H SYMBOL intsave X:0043H SYMBOL intsave X:0043H SYMBOL intsave ------- ENDDO ------- DO X:0043H SYMBOL intsave X:0043H SYMBOL intsave ------- ENDDO ------- DO X:0043H SYMBOL intsave ------- ENDPROC _RTCLOCK_SET ------- PROC MAIN X:0000H SYMBOL rtc X:0008H SYMBOL timeout ------- ENDPROC MAIN ------- ENDMOD HKII Program Size: data=15.1 xdata=68 code=2334 LINK/LOCATE RUN COMPLETE. 2 WARNING(S), 0 ERROR(S)
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
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