📄 2313temp8.asm
字号:
;***************************************************************************
;* AVR Temper8 10MHZ AT90S2313 version 20090402 *
;* Reads up to eight Dallas DS1820/DS18S20 Temperature sensors connected *
;* to an AVR port bit. The temperature (degrees C, ASCII, + CRLF) is sent *
;* out the serial port when a Tn (where n is a single digit from 0 to 7) *
;* is received by the serial port. *
;* An R character returns a count of the devices found, plus a list of *
;* their ROM IDs *
;* Vn (where n is a single digit from 0 to 7) sends the contents of the *
;* selected DS1820's internal registers (in Hex) and the device's extended *
;* temperature. *
;* Here's an example: *
;* command sent : r *
;* program returns: *
;* 4 *
;* 0800080007CC0010 *
;* C000080007728A10 *
;* 0D00080007455E10 *
;* 3300080007B60510 *
;* 0000000000000000 *
;* 0000000000000000 *
;* 0000000000000000 *
;* 0000000000000000 *
;* *
;* command sent: t0 *
;* program returns: *
;* +023.50C *
;* *
;* command sent: v1 *
;* program returns: *
;* 3300A199FFFF0810C4 *
;* +25.25C *
;* *
;* 1-Wire port bit: *
;* Port B bit 2 (PB2) -- The code turns on the pullup feature of the AVR *
;* port bit used. This is enough to enable the 1-Wire bus. *
;* The 4.7K pullup resistor required in most applications (see the DS18S20 *
;* data sheet) can also be used without changing the software. *
;* Acknowledgments *
;* This code was ported from my AT90S8515 program, 8515Temp8, which is *
;* in turn a port from my 68HC11 program, LCDTemper8 *
;* The ROMSrch (ROM Search) routine was ported from ML6805,a Public Domain *
;* assembly language example from Dallas Semiconductor. *
;* It was originally written for the 6805. I also used the code in *
;* The Dallas/Maxim Application Note 162: *
;* INTERFACING THE DS18X20/DS1822 1-WIRE TEMPERATURE SENSOR IN A *
;* MICRO-CONTROLLER ENVIRONMENT as a guide. *
;* I also borrowed from a few Atmel AVR application notes *
;* *
;* The DS1820 devices are read only after setup (to read their ROM codes) *
;* and during a temperature conversion request. *
;* Results are sent to the serial port *
;* FH 20030111 First mod of AT90S8515 version *
;* FH 20030112 Enabled the internal pullup resistor for Port B pin 2. The *
;* 4.7K pullup resistor on the DS line is no longer needed *
;* FH 20051012 Fixed a bug that returned nonsense negative temperatures. *
;* Improved temperature accuracy. Fixed an output display bug *
;* FH 20070215 Thanks to Stephan Stadler for pointing out an arithmetic *
;* error that was producing incorrect temperature readings. *
;* FH 20070219 Added the Verbose (V) command to display the register *
;* contents of the selected device. Changed speed to 10MHZ *
;* FH 20070225 Updated the extended temperature calculations. *
;* The results now match the values shown in the datasheet *
;* FH 20090402 Fixed a bug in the extended temperature calculations. *
;* the 0.5C bit was not being truncated properly . *
;* *
;* Frank Henriquez frank@ucla.edu *
;* Check http://frank.bol.ucla.edu/index.htm for the latest version *
;* Please do not delete any of the text in this comment box. *
;* Please do not redistribute modified versions of this code *
;***************************************************************************
.include "2313def.inc"
;**********************************************
;* Equates *
;**********************************************
.equ clock = 10000000 ;10MHZ clock frequency
.equ baudrate = 9600 ;baudrate is 9600
.equ baudconstant= (clock/(16*baudrate))-1
.equ STACKTOP = RAMEND - 100
;**********************************************
;* Registers used *
;**********************************************
.def Done = r10 ;used in GetROMs
.def ROMCount = r11 ;number of devices found
.def SaveSREG = r12 ;used in Delay
.def BitNum = r13 ;used in ROMsrch
.def LastDis = r14 ;used in ROMsrch
.def LasDisCpy = r15 ;used in ROMsrch
.def AReg = r16 ;working reg, like the 68HC11 A register
.def BReg = r17 ;working reg, like the 68HC11 B register
.def ScratchL = r18
.def ScratchH = r19
.def ByteCount = r20 ;used in ShowROM
.def Count8 = r21
.def DelayVal = r22
.def MpyLo = r24
.def MpyHi = r25
;**********************************************
;* DS1820 Command bytes *
;**********************************************
.equ ReadROM = $33
.equ MatchROM = $55
.equ SkipROM = $cc
.equ SearchROM = $f0
.equ SearchAlarm = $ec
.equ ConvertTemp = $44
.equ CpyScratch = $48
.equ WrScratch = $4e
.equ RdScratch = $be
.equ RecallEE = $b8
.equ ReadPS = $84
;**********************************************
;* The following delay constants are based on *
;* a 10MHZ clock (CLK) *
;* times are not exact. *
;**********************************************
.equ d500us = $b2 ;500us CLK/64
.equ d100us = $83 ;100us CLK/8
.equ d44us = $ca ;44us CLK/8
.equ d15us = $6b ;15us CLK/1
.equ d2us = $ec ;2us CLK/1
.equ TSTOP =0 ;Stop Timer/Counter
.equ TCK1 =1 ;Timer/Counter runs from CK
.equ TCK8 =2 ;Timer/Counter runs from CK / 8
.equ TCK64 =3 ;Timer/Counter runs from CK / 64
.equ TCK256 =4 ;Timer/Counter runs from CK / 256
.equ TCK1024 =5 ;Timer/Counter runs from CK / 1024
.equ TEXF =6 ;Timer/Counter runs from external falling edge
.equ TEXR =7 ;Timer/Counter runs from external rising edge
.equ DSBus =2 ;PORTB bit used for the 1-wire bus
;**********************************************
;* 100 bytes of internal data RAM are used by *
;* the program *
;**********************************************
.dseg
.org RAMEND - 99
Buffer: .byte 16
;**********************************************
;* 9 bytes below are the register contents *
;* of the last DS18S20 read *
;**********************************************
TempLSB: .byte 1
TempMSB: .byte 1
THUB1: .byte 1
TLUB2: .byte 1
Res1: .byte 1
Res2: .byte 1
CountRem: .byte 1
CntPerC: .byte 1
CRC: .byte 1
ExtTemp: .byte 1
romoff: .byte 2 ;Pointer to Sensor address
romdta: .byte 8 ;ROM address of urrent device
Sensor0: .byte 8 ;DS1820 sensor 0 ID #
Sensor1: .byte 8 ;DS1820 sensor 1 ID #
Sensor2: .byte 8 ;DS1820 sensor 2 ID #
Sensor3: .byte 8 ;DS1820 sensor 3 ID #
Sensor4: .byte 8 ;DS1820 sensor 4 ID #
Sensor5: .byte 8 ;DS1820 sensor 5 ID #
Sensor6: .byte 8 ;DS1820 sensor 6 ID #
Sensor7: .byte 8 ;DS1820 sensor 7 ID #
.cseg
.org $000 ;Reset Vector
rjmp Reset
;Interrupt vectors
.org INT0addr ;External Interrupt0 Vector
reti
.org INT1addr ;External Interrupt1 Vector
reti
.org ICP1addr ;Input Capture1 Interrupt Vector
reti
.org OC1addr ;Output Compare1 Interrupt Vector Address
reti
.org OVF1addr ;Overflow1 Interrupt Vector
reti
.org OVF0addr ;Overflow0 Interrupt Vector
rjmp Tim0int
.org URXCaddr ;UART Receive Complete Interrupt Vector
rjmp ParseIn
.org UDREaddr ;UART Data Register Empty Interrupt Vector
reti
.org UTXCaddr ;UART Transmit Complete Interrupt Vector
reti
.org ACIaddr ;Analog Comparator Interrupt Vector
reti
Reset:
ldi AReg,low(STACKTOP)
out SPL,AReg ;set low byte for stack pointer
rcall Setup ;set up DS1820 bits, Serial I/O
RPLoop:
rjmp RPLoop ;wait here until something interesting happens
;**********************************************
;* Setup *
;* Initialize the 1-Wire bus & serial port *
;**********************************************
Setup:
;** serial port setup **
ldi AReg,baudconstant
out UBRR,AReg ;load baudrate
;**enable UART receiver & transmitter and IRQ on serial in:
ldi AReg, (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)
out UCR,AReg
ldi AReg,TSTOP ;Timer 0 off (just in case)
out TCCR0,AReg ;Stop timer
ldi AReg,0b00000010 ;Enable Timer 0 interrupt
out TIMSK,AReg
sei ;enable interrupts
rcall GetROMS
ret
;**********************************************
;* DS1820 Routines *
;**********************************************
;**********************************************
;* DSReset *
;* Sends a reset pulse to all devices. *
;* Returns carry set if devices present. *
;* Returns carry clear if no devices present. *
;**********************************************
DSReset:
sbi DDRB,DSBus ;DDRB bit 2 = 1 = output
cbi PORTB,DSBus ;set 1-wire bus low
ldi ScratchH,TCK64 ;load prescaler
ldi DelayVal,d500us
rcall Delay ;Wait 500us
cbi DDRB,DSBus ;Switch DS bus bit to input (pulled up high)
sbi PORTB,DSBus ;turn on pullup
ldi ScratchH,TCK8 ;load prescaler
ldi DelayVal,d100us
rcall Delay ;Wait 100 us for the DS1820 to respond
clc ;exit with carry clear if no device
sbis PINB,DSBus ;skip next if port B bit 2=1
sec ;bit was clear (=0) so set carry flag
ldi ScratchH,TCK64 ;load prescaler
ldi DelayVal,d500us
rcall Delay ;Wait 500 us
ret
;**********************************************
;* GetBit *
;* Carry holds the bit from the DS1820 bus *
;**********************************************
GetBit:
ldi ScratchH,TCK1 ;load prescaler
ldi DelayVal,d2us ;wait for the 1820 data
sbi DDRB,DSBus ;DDRB bit 2 = 1 = output
cbi PORTB,DSBus ;set 1-wire bus low
rcall Delay
cbi DDRB,DSBus ;DDRB bit 2 = 0 = input
sbi PORTB,DSBus ;turn on pullup
ldi ScratchH,TCK1 ;load prescaler
ldi DelayVal,d15us ;wait 15us for the 1820 data
rcall Delay
clc ;assume 1-Wire bus is low
sbic PINB,DSBus
sec ;1-Wire bus is high, so set carry flag
ldi ScratchH,TCK8 ;load prescaler
ldi DelayVal,d44us
rcall Delay
ret
;**********************************************
;* Write bit in CC to DS bus *
;**********************************************
PutBit:
sbi DDRB,DSBus ;DDRB bit 2 = 1 = output
cbi PORTB,DSBus ;Pull Port B, bit 2 low
ldi ScratchH,TCK1 ;load prescaler
ldi DelayVal,d15us ;wait for the 1820 sample window
rcall Delay
brcc Put0 ;if carry = 0, send a 0
cbi DDRB,DSBus ;otherwise, send a 1
sbi PORTB,DSBus ;turn on pullup
Put0:
ldi ScratchH,TCK8 ;load prescaler
ldi DelayVal,d44us ;load 44us delay in delay register
rcall Delay ;and wait
cbi DDRB,DSBus ;this signals the end of a write 0
sbi PORTB,DSBus ;turn on pullup
ldi ScratchH,TCK1 ;load prescaler
ldi DelayVal,d2us ;let the DS1820 rest & digest
rcall Delay
ret
;**********************************************
;* GetByte *
;* AReg returns the byte from the DS1820 bus *
;**********************************************
GetByte:
ldi BReg,8 ;bit count
clr AReg
NxtBit:
rcall GetBit
ror AReg ;shift carry bit into AReg
dec BReg
brne NxtBit ;repeat for all 8 bits
ret
;**********************************************
;* PutByte *
;* data in AReg *
;**********************************************
PutByte:
ldi BReg,8 ;bit counter
ShiftB:
lsr AReg ;shift bits in AReg into carry
rcall PutBit
NextB:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -