;----------------------------------------------------------------data section begin
; R0 specially reserved for data to Recv pointer!!!
; R1 hold the pointer to write
; R2 for temp1
; R3 for temp2
; R4 for light control now
; R5 !!!
; R6 !!!
; R7 specially reserved for delay micro.!!!
; P0 valve .........now is displayer
; P1 body-detector input
; P2 DS18B20 DQ read/write
;; flag-bit zone(00h~10h at addr:20H~21H) max of 16
done bit 00h ;flag bit:recieved=1
acceptted bit 01h ;msg acceptted
alive bit 02h ;alive declaration continue
reporting bit 03h ;data ready to send
chaos bit 04h ;out of order :frame
bad bit 05h ;checksum failure
corrupt bit 06h ;argument not matched
dirt bit 07h ;buffer is dirty
mutexb bit 08h ;buffer access muturally
iddleS bit 09h ;call iddle state
rebooS bit 0ah ;call reboot state
checkS bit 0bh ;call system complete check then report
lookS bit 0ch ;call look presence info.
rtemprS bit 0dh ;call read temperature
wvalveS bit 0eh ;call write valve data
FLAG1 bit 0fh ;DS18B20 presence?
DQ bit P2.7 ;DS18B20 slaves bus
;; workplace
bit1 equ 27h
bit2 equ 28h
bit3 equ 29h
bit4 equ 2ah
;; buffer for serial
seq equ 2bh ;the next frame.no waiting to receive: max value is 255
leng equ 2ch ;the command defined msg's total length
sum equ 2dh ;checksum of the msg
cmd equ 2eh ; max of 1 bytes
arg equ 2fh ;(2fh~3eh) max of 15 bytes*********************first byte must bits-addr
buf equ 3fh
tmp equ 40h ;
;; approp-data zone(40h~6fh) max of 48 bytes available
sn equ 41h ;41h~4fh for total 15 rooms(experimental)
tempr equ 50h ;050h~05dh, for Room 0~14, 1 bytes for each room
pdata equ 5eh ;05eh~05fh, for Room 0~14, presence state
vdata equ 60h ;060h~06eh, control data for valve, 1 byte for each room
roomp equ 6eh ;for switch pointer between temperature and sn-code
;----------------------------------------------------------------data section end
org 0000h
ljmp initial
;org 0003h
; ljmp isrEX0
org 000bh
ljmp isrT0
;org 0013h
; ljmp isrEX1
;org 001bh
; ljmp isrET1
org 0023h
ljmp isrES
;org 002bh
; ljmp isrT2
org 0030h
;;------------------I.S.R----------------------------------------------------------
isrT0: ;dead-loop resolve
inc sp
inc sp ;force executing next instruction following "jxb x,$"
CLR TR0
MOV TL0,#0FFH
MOV TH0,#0FFH;auto reload,auto disable
reti
isrT1: nop
reti
isrES: ; no other interrupt enable(hard-garantee), so no worry about nestted-interrupt
jnb RI,doTi
;; doRi
clr RI
MOV A,#0
XRL A,seq ;seq=0?
JNZ seq1
seq0: MOV A,SBUF
XRL A,#SYN ;buf=syn?
JZ isSyn
setb chaos
jmp err
isSyn: clr acceptted;msg is invalid..
mov seq,#0
mov leng,#0
clr done
setb mutexb ;termless lock bufferrrrrrrrrrrrrrrrrrrrrrrr
mov R0,#cmd ;buffer pointer:R0
mov R1,#tempr
inc seq ;seq=1
JMP say
seq1: mov A,#1
xrl A,seq ;seq=1?
jnz seq2
mov A,SBUF
orl A,#0fh
xrl A,#0fh ;buf=cmd? (COMMAND高四位为0)
jz isCmd
setb corrupt
jmp err
isCmd: LCALL parse ;msg length will be set here!!!!!!!!!!
jnb corrupt,z49
jmp err
z49: inc seq
jmp say
seq2: mov A,leng ;mens to restrict msg length
clr C
subb A,seq ;seq<leng?
jz stop ;seq=leng
jc err ;seq>leng
mov @R0,SBUF ;augument filled one by one
jnb corrupt,z58
jmp err
z58: inc R0
inc seq
jmp say
stop: ;lcall cheksum ;checksum verification required
;mov A,sum
;jz accept
;setb bad
;jmp err
accept: mov seq,#0
setb acceptted ;msg acceptted!!!
jnb mutexb,err ;what's odd!
clr mutexb ;unlock bufferrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
jmp say
err: ;reset & release all
setb dirt
reti
doTi: clr TI
jb reporting,report
jnb alive,say
inc DPTR
mov A,#0
movc A,@A+DPTR
MOV SBUF,A
xrl A,#0ah ;is a "\n" to send?
jnz Nend
clr alive
Nend: reti
report: inc R1
mov sbuf,@R1
mov A,R1 ;copy
xrl A,#(tempr+8) ;end?
jnz Nove
clr reporting
Nove: reti
say: ;say sth.:-)
mov P0,SBUF
reti
;;------------------function---------------------------------------------------------
parse: ;process different command in frame(used only in isr)
mov A,#0ah ;readPresenceCmd
xrl A,SBUF
jz do1
mov A,#0bh ;readtemprCmd
xrl A,SBUF
jz do2
mov A,#0ch ;conrolCmd(write)
xrl A,SBUF
jz do3
mov A,#0dh ;iddleCmd
xrl A,SBUF
jz do4
mov A,#0eh ;rebootCmd
xrl A,SBUF
jz do5
mov A,#0fh ;checkCmd
;else
cor: setb corrupt
ret
do1: mov leng,#5 ;1 bytes: room map for body-sensor
setb lookS
inc R0
jmp z176
do2: mov leng,#2 ;1 syn,1 comd (experimental)
setb rtemprS
inc R0
jmp z176
do3: mov leng,#5 ;
setb wvalveS
inc R0
jmp z176
;;system command
do4: setb iddleS
jmp z176
do5: setb rebooS
jmp z176
do6: setb checkS
jmp z176
z176: mov cmd,SBUF ;save a copy of cmd(for rescue-mode...)
RET
cheksum:
nop
ret
;;------------------I.N.I.T-----------------------------------------------
initial:;;hw support initial
mov SCON,#0d0h
mov TMOD,#22h
mov TL1,#0fdh
mov TH1,#0fdh
MOV TL0,#0FFH
MOV TH0,#0FFH ;dead-loop resolution ready
setb TR1
setb ES
setb ET0
mov PCON,#00h
data_init:
mov SP,#70h ;for call's parameters
mov 20h,#0
mov 21h,#0 ;clear bit string
mov R0,#cmd
mov seq,#0
mov R1,#tempr
;;ready to start~~
setb EA
;;-------------------M.A.I.N-----------------------------------------
main: jnb done,next0
cpl P3.3 ;task completed!
mov r7,#0ffh
loop: nop
nop
djnz r7,loop
cpl P3.3
mov r7,#0ffh
loop2: nop
nop
djnz r7,loop2
;for debug;;
next0: jb alive,next ;I'm alive!
mov DPTR,#msg
mov A,#0
MOVC A,@A+DPTR
MOV SBUF,A
setb alive
;so, down-msg should not too often...otherwise, task will be always at "start"
next: jnb dirt,next2
jmp data_init
next2: jnb acceptted,rela
clr acceptted
;reboot state engaged 10 seconds after msg incoming
jnb rebooS,idd
clr rebooS
clr P1.7
mov 0a6h,#01eh ;start watchdog timer
mov 0a6h,#0e1h
mov A,#0
jz $ ;down soon...
rela: jmp mout
;iddle state engaged 2 seconds after msg incoming
idd: jnb iddleS,che
clr iddleS
clr P1.6
d2s: mov tmp,#10
lcall d200ms
djnz tmp,d2s
orl PCON,#05h
nop ;...
lcall winkP0 ;I'm awake!
jmp mout
che: jnb checkS,loo
clr checkS
clr P1.5
LCALL INIT_1820 ;check DS18B20
;
jmp mout
;;presence data request
loo: jb mutexb,mout;leave locked bufferrrrrrrrrrrrrrrrrrrrrrrrrrrr
jnb lookS,rte
setb mutexb
clr lookS
clr P1.4
;mov sbuf,P1
;jb TI,$ ;will be soon
lcall d200ms
lcall d200ms
lcall d200ms
jmp mout
;;tempreture data request
rte: jnb rtemprS,wva
clr rtemprS
clr P1.3
mov R5,#1
;; translate the room number to 64-bit DS18B20 internal code
LCALL GET_TEMPER
; send data one by one immediately
jb reporting,relay2 ;cancel all operations
setb reporting
mov SBUF,@R1
jmp mout
wva: jnb wvalveS,mout
clr wvalveS
clr P1.2
;lcall valve;;;;;;;;;;;;;;;
jmp mout
; out of sight,out of mind
mout: jmp main
relay2: jmp data_init
;;------------------M.I.C.R.O --------------------------------------------------
d200ms: ;(uninterrruptable!!!)
MOV R5,#20
d1: MOV R6,#20
d2: MOV R7,#250
DJNZ R7,$
DJNZ R6,d2
DJNZ r5,d1
RET
winkP0: ;5times(used only in main)
mov tmp,R5
push tmp
mov R5,#5
eye0: mov A,#00h
mov P0,A
lcall d200ms
cpl A
mov P0,A
lcall d200ms
djnz R5,eye0
pop tmp
mov R5,tmp
RET
;;-------------------DS18B20(R1,R2,R3,R4)-------------------------------------------------
GET_TEMPER:
LCALL INIT_1820 ;initialization
JB FLAG1,step2 ;ensure device still presence
RET
step2: MOV A,#0CCH ; skip ROM command
LCALL WRITE_1820
MOV A,#44H ;issueing temperatur convertion command
LCALL WRITE_1820
lcall display ;759us for convertion
LCALL INIT_1820 ;initialization
MOV A,#0CCH ;skip ROM command
LCALL WRITE_1820
MOV A,#0BEH ;read scratch pad
LCALL WRITE_1820
LCALL read_temp ;save
CLR P1.0
RET
INIT_1820:
setb DQ ;pull high DQs
clr DQ ;pull low DQs
MOV R4,#239 ;issueing 480us reset pulse
DJNZ R4,$
setb DQ ;release
mov R4,#28 ;wait 15~60us
djnz R4,$
MOV R0,#20 ;wait reply, delay 100us(60us~240us)
de1: jnb DQ,presen
djnz R0,de1
jmp absen
presen: SETB FLAG1 ;presence
CLR P1.1
MOV R0,#50 ;delay 225us
DJNZ R0,$
setb DQ
ret
absen: mov @R1,#0ffh
CLR FLAG1 ;absence, no device on bus
CLR P1.2
setb P1.1
setb DQ
RET
WRITE_1820: ;strict timing required!
MOV R2,#8
CLR C
WR1: CLR DQ ;as a write slot
MOV R3,#6
DJNZ R3,$
RRC A ;within 15us write "0" or "1"
MOV DQ,C ;last for 60us-15us
MOV R3,#23
DJNZ R3,$
SETB DQ ;release
NOP ;at least 1us recovery time
DJNZ R2,WR1
SETB DQ
RET
read_temp:
mov R4,#2
rer: lcall read16_1820
MOV @R1,A ;save temperature low byte
inc R1
djnz R4,rer
dec R1
dec R1 ;reset data pointer at low byte
RET
read16_1820:
MOV R2,#8 ;1 byte = 8 bits
reL: CLR DQ ;as a read slot:pull low
CLR C
NOP
SETB DQ ;release after 2us
MOV R3,#6
DJNZ R3,$
MOV C,DQ ;sample within 15us after pull-low
MOV R3,#23 ;slot last 60us
DJNZ R3,$ ;then least 1us recovery time
RRC A
DJNZ R2,reL
ret
display:
inc R1
mov A,@R1
rrc A ;get lowest bit of temprH
dec R1
mov A,@R1
RRC A
mov @R1,A ;append lowest bit of temprH
inc R1
mov A,@R1
rrc A
rrc A
dec R1
mov A,@R1
RRC A
mov @R1,A
;去掉最低两位和最高六位,保留中间八位作为有效值
;最高温度63.75度,最低温度-64.75度, 精度:0.25度
clr C
rrc A
clr C
rrc A ;cut decimal part
mov b,#10 ;transform hex to tens
clr C
div ab
mov bit4,a
mov bit3,b
mov dptr,#numtab
mov a,bit4 ;fetch ten
MOVC A,@A+DPTR
mov bit4,A
mov a,bit3 ;fetch entry
MOVC A,@A+DPTR
anl A,#0DFh ;lighten point
mov bit3,A
mov A,@R1
anl A,#03h
mov R2,A
mov dptr,#dec1tab ;fetch tenth
movc A,@A+dptr
mov bit2,A
mov A,R2
mov dptr,#dec2tab ;fetch percent
movc A,@A+dptr
mov bit1,A
mov r2,#4
dr2: mov r3,#10 ;refresh 10 times
dr3: mov p0,bit1
clr p2.6
acall d15us
setb p2.6
mov p0,bit2
clr p2.5
acall d15us
setb p2.5
mov p0,bit3
clr p2.4
acall d15us
setb p2.4
mov p0,bit4
clr p2.3
acall d15us
setb p2.3
djnz r3,dr3
djnz r2,dr2 ;total time cusume:>750ms
ret
d15us: ;(oscillator=12MHz)
MOV R4,#5
DJNZ R4,$
RET
numtab: db 28h,7eh,0a2h,62h,74h,61h,21h,7ah,20h,60h
;0 1 2 3 4 5 6 7 8 9
dec1tab:db 28h,0a2h,61h,7ah
;0 2 5 7
dec2tab:db 28h,61h,28h,61h
;0 5 0 5
msg :db "I am alive!",0ah
;; constant
SYN equ 055h
;------------------------------------------------------------------------
end