' ********************
' ***** Symbols *****
' ********************
symbol LCD = 6
symbol BAUD = N2400
symbol Line1 = 128
symbol Line2 = 192
symbol Line3 = 148
symbol Line4 = 212
symbol carrier_on = 1 ' input pin state for carrier on
symbol carrier_off = 0 ' ditto off
symbol bit_time = w0 '(b0 b1)
symbol address = w0
symbol parity_test = w0
symbol temp_word = w1 '(b2 b3)
symbol ADVal = w0
symbol year = b4
symbol month = b5
symbol day = b6
symbol dofw = b7
symbol hours = b8
symbol mins = b9
symbol secs = b10
symbol bitA = b11
symbol bitB = b12
symbol i = b13
symbol tempL = b14
symbol nbits = b14
symbol tempH = b15
symbol rt_sec = b16
symbol rt_mins = b17
symbol rt_hours = b18
symbol rt_day = b19
symbol rt_date = b20
symbol rt_month = b21
symbol rt_year = b22
symbol parity = b23
symbol rx_parity = b24
symbol parity_result = b10
symbol parity_flag = b25
symbol press_adjust = 180
symbol samples = 10
' ***************************
' ***** Initialisation *****
' ***************************
init:
dirsB = 255 'setup Port-BG as outputs
Pause 500
SerOut LCD, BAUD,(254,1,254,14) 'Clear LCD
Pause 50 'Wait for screen to clear
high 5 'write protect eeprom
' *********************************
' *** Main loop - Display data ****
' *********************************
main:
gosub initialise ' all relevant variables
wait_for_start:
do
gosub receive_sec0
loop while bit_time <= 42
' Found SEC-00, denoted by start bit ~ 500mS
gosub wait_for_data
gosub read_year
gosub read_month
gosub read_day
gosub read_dofw
gosub read_hour
gosub read_mins
' gosub display_pressure
' gosub display_humidity
goto wait_for_start
wait_for_data: ' Now skip 16-bits to get to bit-17 the start of the data for YEAR
for i = 0 to 15
gosub receive_sec
next i
return
read_year:
year = 0
for i = 1 to 8
year = year * 2
gosub receive_sec
year = year + bitA AND $3F
next i
BCDTOASCII year,tempH, tempL
serout LCD,BAUD,(254,201,"-20",tempH, tempL)
return
read_month:
month = 0
for i = 1 to 5
month = month * 2
gosub receive_sec
month = month + bitA AND $1F
next i
BCDTOASCII month,tempH, tempL
serout LCD,BAUD,(254,198,"-",tempH, tempL)
return
read_day:
day = 0
for i = 1 to 6
day = day * 2
gosub receive_sec
day = day + bitA AND $3F
next i
BCDTOASCII day,tempH, tempL
serout LCD,BAUD,(254,196,tempH, tempL)
return
read_dofw:
dofw = 0
for i = 1 to 3
dofw = dofw * 2
gosub receive_sec
dofw = dofw + bitA AND $07
next i
serout LCD,BAUD,(254,192)
if dofw = $00 then serout LCD,BAUD,("Sun") endif
if dofw = $01 then serout LCD,BAUD,("Mon") endif
if dofw = $02 then serout LCD,BAUD,("Tue") endif
if dofw = $03 then serout LCD,BAUD,("Wed") endif
if dofw = $04 then serout LCD,BAUD,("Thu") endif
if dofw = $05 then serout LCD,BAUD,("Fri") endif
if dofw = $06 then serout LCD,BAUD,("Sat") endif
serout LCD,BAUD,(254,128)
return
read_hour:
hours = 0
for i = 1 to 6
hours = hours * 2
gosub receive_sec
hours = hours + bitA
next i
return
read_mins:
mins = 0
for i = 1 to 7
mins = mins * 2
gosub receive_sec
mins = mins + bitA
next i
parity = 0
' Now receive bits 52(1), 53(2), 54(3), 55(4), 56(5), 57(6), 58(7) and 59(8)
gosub receive_sec 'Skip BIT-52B
gosub receive_sec 'Skip BIT-53B
gosub receive_sec 'Get BIT-54B
parity = parity OR bitB
parity = parity * 2 ' shift parity bit in to parity word
gosub receive_sec 'Get BIT-55B
parity = parity OR bitB
parity = parity * 2' shift parity bit in to parity word
gosub receive_sec 'Get BIT-56B
parity = parity OR bitB
parity = parity * 2' shift parity bit in to parity word
gosub receive_sec 'Get BIT-57B
parity = parity OR bitB ' no shift neded for LSB bit in to parity word
'serout LCD,BAUD,("PB=",#parity)
' Parity variable now has the 4 parity bits in the lower nibble.
gosub receive_sec 'Get BIT-58B
gosub receive_sec 'Get BIT-59B
gosub read_RTC
if hours <= $23 AND mins <= $59 AND parity_flag <> "*" then
rx_parity = parity / 8 AND $01
parity_test = year
gosub test_parity
if parity_result = 1 then 'result is ODD
rx_parity = parity / 4 AND $01 ' Move the year parity bit down
parity_test = month * 256 + day
gosub test_parity
if parity_result = 1 then 'result is ODD
rx_parity = parity / 2 AND $01
parity_test = dofw
gosub test_parity
if parity_result = 1 then
rx_parity = parity AND $01
parity_test = hours * 256 + mins
gosub test_parity
if parity_result = 1 then
if hours = rt_hours AND mins = rt_mins then
gosub write_RTC
rx_parity = "*" ' Indicates all tests passed, RTC was updated
parity_flag = "*" ' Indicate on display that time was received correctly
endif
else
rx_parity = "i" ' Indicates all test passed but not yet on a 30-min boundary e.g. 00, 30 etc
endif
endif
endif
endif
endif
if rx_parity <> "*" AND rx_parity <> "i" then
rx_parity = "!"
endif
rx_parity = mins // 05 'Only allow time to be updated if on a 5-min boundary
if rx_parity = 0 then
parity_flag = "!"
endif
BCDTOASCII hours,tempH,tempL
serout LCD,BAUD,(254,128,tempH,tempL,":")
BCDTOASCII mins, tempH,tempL
serout LCD,BAUD,(tempH,tempL,"Hr")
gosub display_RTC
return
display_RTC:
gosub read_RTC
BCDTOASCII rt_hours, tempH, tempL
serout LCD,BAUD,(254,140,tempH, tempL,":")
BCDTOASCII rt_mins, tempH, tempL
serout LCD,BAUD,(tempH, tempL,"Hr",parity_flag,254,128)
return
test_parity:
nbits = 0
for i = 1 to 16
parity_result = parity_test AND %00000001
if parity_result = 1 then
nbits = nbits + 1
endif
parity_test = parity_test / 2
next i
parity_result = nbits + rx_parity AND $01
return
receive_sec0:
bitA = 0
bitB = 0
if pin0 = carrier_off then goto receive_sec0
bit_time = 0
do
pause 8 ' Ideally 10 but 8 takes account instruction delays, determined by a test of this section.
bit_time = bit_time + 1
loop while pin0 = carrier_on
gosub Flash_LED
return
receive_sec:
if pin0 = carrier_off then goto receive_sec
Pause 160
bitA = pin0 & $01
Pause 100
bitB = pin0 & $01
gosub Flash_LED
gosub display_RTC
Pause 275
return
initialise:
year = 0
month = 0
day = 0
dofw = 0
hours = 0
mins = 0
parity_flag = "!"
SerOut LCD,BAUD,(254,1)
Pause 400
return
'
' END initialise
Flash_LED:
High 3
Pause 40
Low 3
Return
write_RTC:
' Time has to be sent in BCD format to the clock
i2cslave %11010000, i2cslow, i2cbyte
'Format is 'secs,mins,hours,day, date,month,year, control - control byte is $10
rt_sec = 0
writei2c 0, (00,mins,hours,rt_day,rt_date,rt_month,rt_year,$10)
return
read_RTC:
' Format is secs,mins,hours,day,date,month,year
i2cslave %11010000, i2cslow, i2cbyte
readi2c 0, (rt_sec,rt_mins,rt_hours) ',rt_day,rt_date,rt_month,rt_year)
return
' END OF PROGRAMME
'