📄 ds1820sub1200.asm
字号:
;************************************************
;* DS1820 subroutines for AVR's *
;* *
;* Simple Temp read for AT90S1200 *
;* No SRAM!! Less Instructions to use *
;* *
;* Copyright 2001-2003 Wayne Peacock *
;* First Revision 2th July 2001 *
;* Version 1.02 *
;* *
;************************************************
;* 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. *
;* *
;* Muliply/Divide routines are copied from the *
;* AVR200 Application Note (See Below) *
;************************************************
;**** A P P L I C A T I O N N O T E A V R 2 0 0 ************************
;*
;* Title: Multiply and Divide Routines
;* Version: 1.1
;* Last updated: 97.07.04
;* Target: AT90Sxxxx (All AVR Devices)
;*
;* Support E-mail: avr@atmel.com
;*
;* DESCRIPTION
;* This Application Note lists subroutines for the following
;* Muliply/Divide applications:
;*
;* 8x8 bit unsigned
;* 8x8 bit signed
;* 16x16 bit unsigned
;* 16x16 bit signed
;* 8/8 bit unsigned
;* 8/8 bit signed
;* 16/16 bit unsigned
;* 16/16 bit signed
;*
;* All routines are Code Size optimized implementations
;*
;***************************************************************************
;Registers common to all
;.def temp = r16
;.def data = r17
;.def loopcnt = r18
;.def crc = r1
; **** Pin Consignments ****
.equ WIRE = 4
.set WIREPORT = PORTB
.set WIREDIR = DDRB
.set WIREIN = PINB
.def templsb = r2
.def tempmsb = r3
.def userb1 = r4
.def userb2 = r5
.def crap1 = r6
.def crap2 = r7
.def count_remain = r8
.def count_per_c = r9
.def scratch_crc = r10
.def crc = r11
.def templ = r12 ; Converted result
.def temph = r13
.def vallow = r22
.def valhigh = r23
;************************************************
;* 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, WIREIN
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 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
; Byte 0
rcall DS1820_Read ; Read a byte
mov templsb, data ; store data
;rcall onechar
; Byte 1
rcall DS1820_Read ; Read a byte
mov tempmsb, data ; store data
;rcall onechar
; Byte 2
rcall DS1820_Read ; Read a byte
mov userb1, data ; store data
;rcall onechar
; Byte 3
rcall DS1820_Read ; Read a byte
mov userb2, data ; store data
;rcall onechar
; Byte 4
rcall DS1820_Read ; Read a byte
mov crap1, data ; store data
;rcall onechar
; Byte 5
rcall DS1820_Read ; Read a byte
mov crap2, data ; store data
;rcall onechar
; Byte 6
rcall DS1820_Read ; Read a byte
mov count_remain, data ; store data
;rcall onechar
; Byte 7
rcall DS1820_Read ; Read a byte
mov count_per_c, data ; store data
;rcall onechar
; Byte CRC
rcall DS1820_Read ; Read a byte
mov scratch_crc, data ; store data
;rcall onechar
ret
;************************************************
;* Dump Temp from SRAM to RS232 (real value) *
;* Resolution 0.5 deg C negative works *
;* *
;* Input: templsb (SRAM) *
;* Output: RS232 *
;* Requires: data *
;* *
;************************************************
dump_temp:
; Check for positive or negative temp!
tst tempmsb
breq postemp ; Temp is Positive!
; Display a negative number!!
ldi data, '-'
rcall onechar
ldi temp, 0x00
sub temp, templsb
mov hex, temp
rjmp distemp
postemp:
ldi data, ' '
rcall onechar
mov hex, templsb ; Get LSB
distemp:
lsr hex
rcall hexdec ; Convert to decimal
; display now
;mov data, templsb
mov data, hund
rcall onechar
mov data, tens
;mov data, tempmsb
rcall onechar
mov data, unit
rcall onechar
; decimal place
ldi data, '.'
rcall onechar
mov hex, templsb
ldi data, '0'
sbrc hex, 0
ldi data, '5'
rcall onechar
ldi data, 'C'
rcall onechar
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
; Result Registers
clr vallow
clr valhigh
mov valhigh, templsb ; Put DS1820 value in
lsr valhigh ; Remove 0.5C Bit
sbrc tempmsb, 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
mov valueh, count_per_c
mov 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
mov 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:
; We want Low & High result
; Result in R16 (valuel) (Always Positive)
; add R16 to vallow
; add R17 to valhigh
add vallow, valuel ; Add count remaining
adc valhigh, valueh ; Add
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
mov templ, result ;Store Temp Low
ret
;*** Working as of July 2002 !! Removed from sub1200 ***
;************************************************
;* Dump Temp from SRAM to LCD (real value) *
;* High Resolution Version *
;* *
;************************************************
; Display Now
DS_disp:
; Check for positive number
sbrs temph, 7
breq postemp2 ; Temp is Positive!
; Display a negative number!!
ldi data, '-'
rcall onechar
ldi hex, 0xff
sub hex, temph
;mov hex, temph
;neg hex
rcall hexdec ;Convert to decimal
ldi data, ' '
mov data, tens
rcall onechar
mov data, unit
rcall onechar
ldi data, '.'
rcall onechar
mov hex, templ
rcall hexdec
mov data, tens ; Value can only be 0 - 99! No hundreds
rcall onechar
mov data, unit
rcall onechar
rjmp ds_dec
postemp2:
ldi data, ' '
rcall onechar
mov hex, temph ;Get High Value
cbr hex, 0x80
rcall hexdec ;Convert to decimal
ldi data, ' '
mov data, tens
rcall onechar
mov data, unit
rcall onechar
; decimal place
ldi data, '.'
rcall onechar
mov hex, templ
rcall hexdec
mov data, tens ; Value can only be 0 - 99! No hundreds
rcall onechar
mov data, unit
rcall onechar
ds_dec:
ldi data, 'C'
rcall onechar
ret
;************************************************
;* Dump registers to LCD *
;* High Resolution Version *
;* *
;************************************************
dump_reg:
mov hex, templsb ;Get High Value
rcall hexasc ;Convert to Ascii
ldi data, ' '
mov data, tens
rcall onechar
mov data, unit
rcall onechar
mov hex, tempmsb ;Get High Value
rcall hexasc ;Convert to Ascii
ldi data, ' '
mov data, tens
rcall onechar
mov data, unit
rcall onechar
mov hex, count_remain ;Get High Value
rcall hexasc ;Convert to Ascii
ldi data, ' '
mov data, tens
rcall onechar
mov data, unit
rcall onechar
mov hex, count_per_c ;Get High Value
rcall hexasc ;Convert to Ascii
ldi data, ' '
mov data, tens
rcall onechar
mov data, unit
rcall onechar
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -