' ' logger.bas ' ' This program was written to go with an article about the ds1305 in ' the May, 2000 issue of the Encoder. ' www.seattlerobotics.org/encoder/200005/ds1305.html ' ' 04/30/00 kevinro@nwlink.com ' include "regs11.lib" include "ds1305.bas" include "sermem.bas" ' ' A few working variables ' declare i declare j declare k declare n declare LastSampleTime declare LastWriteTime ' ' Buffer is used as an I/O buffer and is 4 words long, ' or 8-bytes ' declare Buffer(4) const BUF_SECOND = 0 const BUF_MINUTE = 1 const BUF_HOUR = 2 const BUF_DAYINDEX = 3 const BUF_DAY = 4 const BUF_MONTH = 5 const BUF_YEAR = 6 const BUF_DATABYTE = 7 ' ' EEPROMPointer is stored in the non-volatile memory of the ds1305 part ' at address $20 ' declare EEPROMPointer const EP_OFFSET = $20 ' ' This program is designed to show you how to use the ds1305 time-keeper ' from Dallas Semiconductor. This program implements a simple little ' data logging device. ' ' main: pokeb baud, $30 pokeb sccr2, $0c ' ' Enable the A/D converter by turning on the charge pump ' pokeb OPTION, peekb(OPTION) OR $80 ' ' Set the A/D converter for continuous scan of channel ' 0 ' pokeb ADCTL, $20 gosub sermem_Init , 32 gosub ds1305_Init ' Write enable the serial EEPROM gosub sermem_BlockProt , 0 ' Write enable the part, turn off all interrupts, and enable ' the oscillator i = 0 gosub ds1305_Write_Block,$0f,addr(i),1 ' ' The next available EEPROMPointer is stored in nonvolatile RAM ' on the ds1620 ' gosub ds1305_Read_Block,EP_OFFSET,addr(EEPROMPointer),2 ' The EEPROM pointer will always be a multiple of 8, and should ' always be less than 8k in size. Just in case, mask it off. EEPROMPointer = EEPROMPointer AND $1FF8 ' Pre-initialize the state variables by reading the date gosub GetTimeDate LastWriteTime = peek(addr(Buffer)+1) do n = inkey() if n <> 0 then n = n AND $FF select n case 'S' ' Set date/time gosub SetDateTime endcase case 'D' ' Dump current data gosub DumpEEPROMData endcase case 'Z' ' Erase the entire EEPROM gosub sermem_Fill,0,0,8192 EEPROMPointer = 0 gosub ds1305_Write_Block,EP_OFFSET,addr(EEPROMPointer),2 endcase endselect endif ' ' Read the current time from the clock ' Based on the previous time, determine if a new ' value is to be read ' gosub GetTimeDate ' Report every second. This shows you that something ' is indeed happening if LastSampleTime <> peekb(addr(Buffer)+0) then pokeb addr(Buffer)+BUF_DATABYTE, usr(SampleData) LastSampleTime = peekb(addr(Buffer)+BUF_SECOND) gosub DumpBuffer ' Record a value only once a minute. This allows you ' to fill the EEPROM every 1024 minutes ' ' Change the LastWriteTime assignments to use the ' hours, days, months, etc, as you see fit. if LastWriteTime <> peek(addr(Buffer)+BUF_MINUTE) then LastWriteTime = peek(addr(Buffer)+BUF_MINUTE) gosub sermem_WriteBlock,EEPROMPointer,addr(Buffer),8 EEPROMPointer = (EEPROMPointer + 8) AND $1FFF gosub ds1305_Write_Block,$20,addr(EEPROMPointer),2 ' Printing the W tells you that a record was written outch 'W' endif print endif loop ' ' GetAByte waits until a single byte is available from the terminal. ' That byte is then returned on top of the stack. ' GetAByte: push 0 ' Create a local variable do place 0,inkey() loop while pick(0) = 0 push pop() AND $FF return ' ' GetNumberByte will get input from the ' GetBCDNumberByte: ' Call and get a byte, leave it on stack gosub GetAByte ' Return value is still on stack. Should be a number ' between 0 and 9 push maxu(minu(pop(),'9'),'0') - '0' outch pick(0)+'0' ' Call and get a byte, leave it on stack gosub GetAByte ' Return value is still on stack. Should be a number ' between 0 and 9 push maxu(minu(pop(),'9'),'0') - '0' outch pick(0)+'0' push (pop() AND $0F)+(lshft(lshft(lshft(lshft(pop())))) AND $F0) return HexFormatBytes: datab '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' DumpByteInHex: outch peekb((rshft(rshft(rshft(rshft(pick(0))))) AND $0F) + addr(HexFormatBytes)) outch peekb((pop() AND $0F) + addr(HexFormatBytes)) return ' ' Dump buffer prints out the data from the buffer. ' The data is printed in date/time order in the following ' format ' mm/dd hh:mm:ss v ' ' where v == the value recorded ' ' The other values are ignored for now. ' DumpBuffer: gosub DumpByteInHex, peekb(addr(Buffer)+BUF_MONTH) outch '/' gosub DumpByteInHex, peekb(addr(Buffer)+BUF_DAY) outch ' ' gosub DumpByteInHex, peekb(addr(Buffer)+BUF_HOUR) outch ':' gosub DumpByteInHex, peekb(addr(Buffer)+BUF_MINUTE) outch ':' gosub DumpByteInHex, peekb(addr(Buffer)+BUF_SECOND) outch ' ' gosub DumpByteInHex, peekb(addr(Buffer)+BUF_DATABYTE) return ' ' SetDateTime is used to set the clock. I did not do much in the ' way of parameter validation here, so if you mistype something ' you may end up with some truely strange time. ' ' When you hit 'S' on the terminal, it will wait for you to ' enter the time and date in SSMMHH (Seconds,Minutes,Hours) ' then DDMMYY (Days,Months,Years). The commented out ' print statements are just a little too big to fit into ' memory. ' SetDateTime: ' print "ssmmhh: "; pokeb addr(Buffer)+BUF_SECOND, usr(GetBCDNumberByte) pokeb addr(Buffer)+BUF_MINUTE, usr(GetBCDNumberByte) pokeb addr(Buffer)+BUF_HOUR, usr(GetBCDNumberByte) AND $3F ' This should be where the day of the week is entered, but ' we don't actually care for this program, so just make it Sunday pokeb addr(Buffer)+BUF_DAYINDEX, 1 ' print "ddmmyy: "; pokeb addr(Buffer)+BUF_DAY, usr(GetBCDNumberByte) pokeb addr(Buffer)+BUF_MONTH, usr(GetBCDNumberByte) pokeb addr(Buffer)+BUF_YEAR, usr(GetBCDNumberByte) gosub ds1305_Write_Block,0,addr(Buffer),7 return DumpEEPROMData: ' Dump the contents of the EEPROM for i = 0 to 8192-8 step 8 gosub sermem_ReadBlock,i,addr(Buffer),8 ' Only print records with a non zero date if peek(addr(Buffer)+BUF_DAY) <> 0 then outch '#' gosub DumpBuffer print endif next return GetTimeDate: gosub ds1305_Read_Block,0,addr(Buffer),7 return ' ' This routine samples the data byte to be written to each record ' SampleData: return peekb(adr1) end