?? ds1820sub.asm
字號:
;************************************************
;* DS1820 subroutines for AVR's *
;* *
;* *
;* Copyright 2001-2003 Wayne Peacock *
;* Wayne Peacock 2nd July 2001 *
;* Version 1.00 *
;************************************************
;* See Schematic for Hardware connections *
;* *
;* Disclaimer: *
;* The Author takes no responsibility for the *
;* use of this code. Use at your own risk! *
;* *
;* This code or part there of is licensed only *
;* for private use and NOT for commercial use. *
;* *
;* Please contact the author 'Wayne Peacock' *
;* <wpeacock@senet.com.au> before using the code*
;* or part there of in a commercial project. *
;************************************************
;Registers common to all
;.def temp = r16
;.def data = r17
;.def loopcnt = r18
;.def crc = r1
; **** Pin Consignments ****
.equ WIRE = 0
.set WIREPORT = PORTB
.set WIREDIR = DDRB
.set WIREIN = PINB
; **** SRAM START at 0x60 ****
.equ templsb = 0x69
.equ tempmsb = 0x6a
.equ userb1 = 0x6b
.equ userb2 = 0x6c
.equ crap1 = 0x6d
.equ crap2 = 0x6e
.equ count_remain = 0x6f
.equ count_per_c = 0x70
.equ scratch_crc = 0x71
.equ crc_check2 = 0x72
.equ templ = 0x73 ; Converted result
.equ temph = 0x74
.equ crc_check = 0x07e
.equ DScount = 0x07f
.equ DS1820_0 = 0x080
.equ DS1820_1 = 0x088
.equ DS1820_2 = 0x090
.equ DS1820_3 = 0x098
.equ DS1820_4 = 0x0A0
.equ DS1820_5 = 0x0A8
;.equ DS1820_6 = 0x0B0
;.equ DS1820_7 = 0x0B8
;.equ DS1820_8 = 0x0C0
;.equ DS1820_9 = 0x0C8
; 16 bytes free for stack!!
; **** 0xDF = End of SRAM on 2313 ****
;************************************************
;* DS1820 Init (4 Mhz) *
;************************************************
DS1820_init:
cbi WIREPORT, WIRE ; Bit always low
cbi WIREDIR, WIRE ; Set pin up as open drain
ret
;************************************************
;* DS1820 Reset (4 Mhz) *
;* *
;* T clear if Presence *
;* Requires: temp *
;* count1 (timer) *
;************************************************
.equ T = 6 ; STATUS REG
DS1820_reset:
; Reset Pulse
sbi WIREDIR, WIRE ; Bus Low
ldi count1, 137
rcall delayX5us ; Wait 720us
cbi WIREDIR, WIRE ; Bus High
; Delay
ldi count1, 13
rcall delayX5us ; Wait 67.5us
; Check for Presence signal
in temp, WIREDIR
bst temp, WIRE ; Store bus status
; Delay
ldi count1, 190
rcall delayX5us ; Wait 1ms
ret
;************************************************
;* DS1820 Write Byte (4 Mhz) *
;* *
;* Input: data *
;* Requires: temp (bit count) *
;* count1 (timer) *
;************************************************
DS1820_Write:
ldi temp, 8 ; 8 bits to write
DS1820_wloop:
sbi WIREDIR, WIRE ; [1] Bus low ( 1us to 15us )
nop
nop
nop
nop
nop
ror data ; [1]
brcc DS1820_w0 ; [1] Write 0
DS1820_w1:
cbi WIREDIR, WIRE ; Data = high
DS1820_w0:
; Data alread low
ldi count1, 13 ; Just wait >60us
rcall delayX5us
cbi WIREDIR, WIRE ; Bus high
ldi count1, 1 ; Recovery time >1us
rcall delayX5us ; 5us delay!
dec temp
brne DS1820_wloop
ret
;************************************************
;* DS1820 Read Byte (4 Mhz) *
;* *
;* Output: data *
;* Requires: temp (bit count) *
;* count1 (timer) *
;************************************************
DS1820_read:
ldi temp, 8 ; 8 bits to write
clr data
DS1820_rloop:
sbi WIREDIR, WIRE ; [1] Bus low ( 1us to 15us )
ldi count1, 1 ; Recovery time >1us
rcall delayX5us ; 5us delay!
cbi WIREDIR, WIRE ; Bus high
ldi count1, 1 ; Recovery time >1us
rcall delayX5us ; 5us delay!
; Get Data Now
lsr data
sbic WIREIN, WIRE ; check bit
sbr data, 0x80
; Data alread inactive
ldi count1, 13 ; Just wait >60us
rcall delayX5us
dec temp
brne DS1820_rloop
ret
;************************************************
;* DS1820 Checksum (CRC) *
;* *
;* input: data *
;* crc *
;* output: crc (modified) *
;* requires: temp (bit count) *
;************************************************
;.def data = r17
;.def crc = r18
DS1820_crc:
push data ; Must save for next bit
ldi temp, 0x08 ; 8 bits
crc_loop:
eor data, crc ;
ror data
mov data, crc ;
brcc crc_skip ; Skip if zero
push temp
ldi temp, 0x18 ;
eor data, temp
pop temp ;
crc_skip:
ror data
mov crc, data
pop data
lsr data ; Align bits
push data
dec temp
brne crc_loop ; Process 8 bits
pop data ; Clean up stack
ret
;************************************************
;* DS1820 Do Temp Conversion *
;* *
;* Requires: DS1820_Write *
;************************************************
DS1820_conv:
ldi data, 0xcc ; Skip ROM check
rcall DS1820_Write
ldi data, 0x44 ; Start Temp Conversion
rcall DS1820_Write
wait_con:
sbis WIREIN, WIRE ; Conversion Done!
rjmp wait_con
ret
;************************************************
;* DS1820 Read Scratch Pad *
;* Requires DS1820 ROM ID subroutine *
;* *
;************************************************
DS1820_Scr:
;ldi data, 0xcc ; Skip ROM check
;rcall DS1820_Write
ldi data, 0xbe ; read Scratch Pad
rcall DS1820_Write
clr crc
ldi loopcnt, 0x08 ; Read 8 bytes
ldi YH,high(templsb)
ldi YL,low(templsb) ;init Y-pointer
rom_loop:
rcall DS1820_Read ; Read a byte
st Y+,data ; store data to SRAM
rcall DS1820_crc
dec loopcnt ;
brne rom_loop ;if not done, loop more
rcall DS1820_Read ; Read CRC
st Y+,data ; store data to SRAM
sts crc_check, crc ; Store Calulated CRC
ret
;************************************************
;* DS1820 Temp Calculate *
;* High Resolution *
;* *
;* Input: SRAM *
;* Output: SRAM *
;* Requires: r12 *
;* r13 *
;* r14 *
;* r15 *
;* r16 *
;* r17 *
;* r18 *
;* Fully Functional at 21th Sept 2002 *
;* Tested with Positive and negative temperature*
;* Quick fix added for negative conversion *
;************************************************
dump_temp2:
;***** Register Variables
.def valuel = r16
.def valueh = r17
.def result = r15
.def count = r18
.def valuem = r19
.def templ = r12 ; Converted result
.def temph = r13
.def vallow = r22
.def valhigh = r23
; Result Registers
clr vallow
clr valhigh
lds valhigh, templsb ; Put DS1820 value in
lsr valhigh ; Remove 0.5C Bit
lds temp, tempmsb
sbrc temp, 0 ; Check if negative number
sbr valhigh, 0x80
; Subract the 0.25C
subi vallow,0x40 ;Subtract low bytes (0.25C)
sbci valhigh,0x00 ;Subtract high byte with carry
; Calulate remaining counts
; Temp = countperc - countremain
lds valueh, count_per_c
lds valuel, count_remain
sub valueh, valuel ;Subract remainder from countperc
;***** Divide Two Unsigned 16-Bit Numbers
.def drem16uL=r14 ; Dump (Temp Only)
.def drem16uH=r15 ; Dump (Temp Only)
.def dres16uL=r16 ; Keep (valuel)
.def dres16uH=r17 ; Keep (valueh)
.def dd16uL =r16 ; 00
.def dd16uH =r17 ; count_per_c - countremain
.def dv16uL =r12 ; count_per_c
.def dv16uH =r13 ; 00
lds dv16uL, count_per_c
clr dv16uH
clr dd16uL
div16u: clr drem16uL ;clear remainder Low byte
sub drem16uH,drem16uH ;clear remainder High byte and carry
ldi count,17 ;init loop counter
d16u_1: rol dd16uL ;shift left dividend
rol dd16uH
dec count ;decrement counter
brne d16u_2 ;if done
rjmp dump_3 ;Finished here
d16u_2: rol drem16uL ;shift dividend into remainder
rol drem16uH
sub drem16uL,dv16uL ;remainder = remainder - divisor
sbc drem16uH,dv16uH ;
brcc d16u_3 ;if result negative
add drem16uL,dv16uL ; restore remainder
adc drem16uH,dv16uH
clc ; clear carry to be shifted into result
rjmp d16u_1 ;else
d16u_3: sec ; set carry to be shifted into result
rjmp d16u_1
dump_3:
; Only want Low result
; Result in R16 (valuel) (Always Positive)
add vallow, valuel ; Add count remaining
adc valhigh, valueh ; Just to carry
mov valuel, vallow
mov temph, valhigh ;Store Temp High (Final Value)
; Check if negative Number!!
sbrs temph, 7
rjmp ptemp ; Temp is positive
; Invert fraction for conversion
neg valuel
; Quick Fix 21th Sept 2002
; Fixes jumps at whole negative temperatures
ldi r17, 00
cp valuel, r17
brne ptemp
ldi r17, 01
sub temph, r17
; Fraction in valuel must convert to displayable number!
; Therefore multiply by 64h and dump LSB
; valuel -> multiplicand
; valueh -> multiplier
; result -> Result High Byte
; valueh -> Result Low Byte -> Discard
ptemp:
ldi valueh, 0x64 ;Multiplier
mpy8u: clr result ;clear result High byte
ldi count,8 ;init loop counter
lsr valueh ;rotate multiplier
m8u_1: brcc m8u_2 ;carry set
add result, valuel ;add multiplicand to result High byte
m8u_2: ror result ;rotate right result High byte
ror valueh ;rotate right result L byte and multiplier
dec count ;decrement loop counter
brne m8u_1 ;if not done, loop more
sts templ, result ;Store Temp Low
sts temph, temph ;Store Temp High
ret
;*** Working as of July 2002 !! Removed from sub1200 ***
;************************************************
;* Dump Temp from SRAM to RS232 (real value) *
;* High Resolution Version *
;* *
;************************************************
; Display Now
DS_disp:
lds temp, temph ;Get High Value
; Check for positive number
sbrs temp, 7
breq postemp2 ; Temp is Positive!
; Display a negative number!!
ldi data, '-'
rcall onechar
rcall comm_write
lds temp, temph ;Get High Value
ldi hex, 0xff
sub hex, temp
rcall hexdec ;Convert to decimal
mov data, tens
rcall comm_write
rcall onechar
mov data, unit
rcall comm_write
rcall onechar
rjmp ds_dec
postemp2:
;ldi data, ' '
;rcall onechar
lds hex, temph ;Get High Value
rcall hexdec ;Convert to decimal
mov data, hund
rcall comm_write
rcall onechar
mov data, tens
rcall comm_write
rcall onechar
mov data, unit
rcall comm_write
rcall onechar
ds_dec:
; decimal place
ldi data, '.'
rcall comm_write
rcall onechar
lds hex, templ
rcall hexdec
mov data, tens ; Value can only be 0 - 99! No hundreds
rcall comm_write
rcall onechar
mov data, unit
rcall comm_write
rcall onechar
ldi data, 'C'
rcall comm_write
rcall onechar
ret
;************************************************
;* Dump ID from SRAM to RS232 (real value) *
;* *
;* *
;************************************************
Dump_ID:
ldi data, ' '
rcall comm_write
ldi YH,high(DS1820_0)
ldi YL,low(DS1820_0) ; init Y-pointer
ldi loopcnt, 0x08 ;Loop 6 times
ID_loop:
ld hex, Y+ ;Get High Value
rcall hexasc ;Convert to decimal
mov data, tens
rcall comm_write
mov data, unit
rcall comm_write
ldi data, ':'
rcall comm_write
dec loopcnt
brne ID_loop ;if not done, loop
ret
;************************************************
;* Dump ID's from SRAM to RS232 (real value) *
;* Used for Search ROM *
;* *
;************************************************
Dump_search:
; Get number of devices
lds temp, DScount ; Number of devices found
ldi YH,high(DS1820_0)
ldi YL,low(DS1820_0) ; init Y-pointer
ID_sloop1:
ldi data, ' '
rcall comm_write
ldi loopcnt, 0x07 ;Loop 8 times
ID_sloop:
ld hex, Y+ ;Get High Value
rcall hexasc ;Convert to decimal
mov data, tens
rcall comm_write
mov data, unit
rcall comm_write
ldi data, ':'
rcall comm_write
dec loopcnt
brne ID_sloop ;if not done, loop
ld hex, Y+ ;Get High Value
rcall hexasc ;Convert to decimal
mov data, tens
rcall comm_write
mov data, unit
rcall comm_write
dec temp ; Next device!
brne ID_sloop1
;ldi data, 0x0d
ldi data, ' '
rcall comm_write
ret
;************************************************
;* Get Temp and Display on LCD *
;* Used with Search ROM *
;* Requires Y pointer to DS1820ID *
;************************************************
LCDTemp:
;ldi temp, 0xE8
;sts templsb,temp
;ldi temp, 0xFF
;sts tempmsb, temp
;ldi temp,0x0C
;sts count_remain,temp
;ldi temp,0x10
;sts count_per_c, temp
;rcall dump_temp2
;rcall DS_disp
rcall DS1820_reset
ldi data, 0x55 ; Match ROM
rcall DS1820_Write
ldi loopcnt, 0x08 ; Write 8 bytes
rom_compare:
ld data, Y+
rcall DS1820_Write ; Read a byte
dec loopcnt
brne rom_compare ;if not done, loop more
rcall DS1820_scr
rcall dump_temp2
rcall DS_disp
ldi data, ' '
rcall comm_write
rcall onechar
ret
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -