'
' 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