
производство
   
Профиль
Группа: Модератор
Сообщений: 2724
Регистрация: 4.4.2002
Где: москва
Репутация: 20 Всего: 54
|
Код |
;*************************************************************************** ;* AVR Temper8 AT90S2313 version * ;* 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 * ;* Here's an example: * ;* command sent : r * ;* program returns: * ;* 4 * ;* 0800080007CC0010 * ;* C000080007728A10 * ;* 0D00080007455E10 * ;* 3300080007B60510 * ;* 0000000000000000 * ;* 0000000000000000 * ;* 0000000000000000 * ;* 0000000000000000 * ;* * ;* command sent: t1 * ;* program returns: * ;* +023.50C * ;* * ;* 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 030111 First mod of AT90S8515 version * ;* FH 030112 Enabled the internal pullup resistor for Port B pin 2. The * ;* typical 4.7K pullup resistor on the DS line no longer needed * ;* * ;* Frank Henriquez [email protected] http://www.bol.ucla.edu/~frank/ * ;* 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 = 8000000 ;clock frequency .equ baudrate = 9600 ;choose a baudrate .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
;********************************************** ;* 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 * ;* an 8MHZ clock (CLK) * ;* times are not exact. * ;**********************************************
.equ d250us = 6 ;250us CLK/8 .equ d100us = $9c ;70us CLK/8 .equ d44us = $d4 ;44us CLK/8 .equ d15us = $f2 ;14us CLK/8 .equ d2us = $fe ;2us CLK/8
.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 DelayVal,d250us rcall Delay rcall Delay ;Wait 250us x 2 = 500 us cbi DDRB,DSBus ;Switch DS bus bit to input (pulled up high) sbi PORTB,DSBus ;turn on pullup 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 DelayVal,d250us rcall Delay rcall Delay ;Wait 500 us ret ;********************************************** ;* GetBit * ;* Carry holds the bit from the DS1820 bus * ;********************************************** GetBit: 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 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 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 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 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 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: dec BReg brne ShiftB ret
;********************************************** ;* Search for devices on DS bus * ;* Based on Dallas Semiconductor's ML6805 * ;* code. * ;********************************************** ROM1st: ldi AReg,$41 ;Point Rom Search to top (1st part). mov LastDis,AReg rcall ROMSrch ret
ROMSrch: push XL push XH
rcall DSReset ;Reset 1-wire bus. brcs r_look rjmp NoDev r_look: ldi AReg,$40 ;Prepare to find 64 bits of ROM data. mov BitNum,AReg ldi Count8,8 ;Initial value for eight counter. mov LasDisCpy, LastDis ;Save copy of last dis. from last search. ldi XL,low(romdta) ldi XH,high(romdta) ;point to 1st byte of ROM data sts romoff,XL ;buffer in rombuff. sts romoff+1,XH ldi AReg,SearchROM ;Get ROM search command in AReg. rcall PutByte ;Send ROM search command to DOW bus.
NxtRBit: clr AReg clr BReg rcall GetBit ;1st read time slot. rol BReg ;reg BReg, bit0 has first result rcall GetBit ;2nd read time slot. rol AReg cpi BReg,1 ;Was the first bit received 1? brne no_or ;Branch if it wasn't ori AReg,2 ;Set bit 1 in AReg
no_or: cpi AReg,3 ;See if error condition occurred. breq NoDev ;Abort if error. cpi AReg,0 ;Was there a disagreement on bus. brne nosave ;Branch if there wasn't. cp LasDisCpy,BitNum ;Compare last dis to current position. brne lwhere ;If its not equal look some more. ldi AReg,1 ;We've been on this path and sent a 0. rjmp wrtBit ;now lets send a 1.
lwhere: brcs sLstBit ;Stay on previous path. clr AReg ;Past last dis. fall to the right. rjmp savedis ;Send 0 to bus. sLstBit: lds XL,romoff ;Get offset of ROM data buffer in lds XH,romoff+1 ld AReg,X ;index register, and byte in AReg. andi AReg,1 ;Isolate lsb of AReg. cpi AReg,1 ;See if it was a 1. breq wrtBit ;Don't save as dis position if so. savedis: mov LastDis,BitNum ;Get current position in x register. ;Save current last disagreement pos. rjmp wrtBit ;Send the write bit time slot. nosave: ldi BReg,1 eor AReg,BReg ;Flip lsb of AReg. wrtBit: andi AReg,1 ;Isolate lsb of AReg mov BReg,AReg lsr BReg rcall PutBit ;Send lsb of AReg to 1-wire bus. lds XL,romoff lds XH,romoff+1 ;Get offset into ROM data buffer. ld AReg,X ;Get previous val of rombyte. ror AReg ;Get ROM bit in MSB of rombyte. st X,AReg ;Store new byte value & point to next byte dec Count8 ;Decrement byte counter. brne bnfull ;Branch if we don't have full byte. adiw XH:XL,1 ;increment x sts romoff,XL ;buffer in rombuff. sts romoff+1,XH ldi Count8,8 ;reload the eight counter. bnfull: dec BitNum ;Decrement 64 bit counter. brne NxtRBit ;Go get next rom bit. cp LasDisCpy,LastDis ;Compare to last dis. copy brne MoDows ;If not equal clear AReg. ldi AReg,$41 ;Point ROM search algorithm back mov LastDis,AReg ;to first part. ldi AReg,1 ;Indicate this was last part on bus. rjmp lastdow ;Skip the clra statement and leave. MoDows: clr AReg ;Indicate that more parts are on bus. lastdow: sec ;Indicate success. rjmp DevFnd ;Skip clear carry stuff. NoDev: clc ;Indicate failure. DevFnd: pop XH pop XL ret
;********************************************** ;* GetROMS * ;* Looks for up to 8 DS1820s, reads their * ;* 64 bit ROM codes and saves them in memory * ;********************************************** GetROMS: clr AReg clr ROMCount ;clear out ROMCount clr Done ;clear Done flag ldi YH,high(romdta) ldi YL,low(romdta) ;Y points to romdta buffer ClrOut: st Y+,AReg ;clear out the ROM ID storage area cpi YL,low(Sensor7+8) brcs ClrOut LookROM: rcall DSReset ;Reset 1-wire bus ;*** to send out the list of ROMs found, uncomment the line below brcc SetExit ;Abort if no presence detect ;*** to NOT send out the list of ROMs found, uncomment the line below ; brcc SetExit2 ;Abort if no presence detect
rcall ROM1st ;look for the first ROM mov ScratchL,AReg brcc SetExit ;if AReg = 0 then there are more devices ldi XH,high(Sensor0) ldi XL,low(Sensor0) ;X points to first device ID rjmp MR0 ;process them & exit LR1: rcall ROMSrch ;look for other devices mov ScratchL,AReg breq MR0 ;if AReg = 0 then there are more devices inc Done MR0: ldi YH,high(romdta+8) ldi YL,low(romdta+8) ;Y points to ROM just read MoveROM: ld AReg,-Y ;move byte from romdta st X+,AReg ;to SensorX cpi YL,low(romdta) ;move all 8 bytes brne MoveROM ;of the ROM ID inc ROMCount ;increment the ROM counter tst ScratchL ;repeat until the last device found breq MR2 inc Done MR2: tst Done brne SetExit cpi XL,low(Sensor7+8) ;or until the end of the ROM brcs LR1 ;storage area is reached SetExit: rcall ShowROM ;then Display the ROM IDs SetExit2: ret
;********************************************** ;* ShowROM * ;* Converts data in the Sensor area to ASCII * ;* hex and send them out the serial port. * ;********************************************** ShowROM: ldi XL,low(Sensor0) ;X points to Sensor ID area ldi XH,high(Sensor0) SRLoop: ldi YL,low(Buffer) ;Y points to ASCII data buffer ldi YH,high(Buffer) ldi ByteCount,8 ROMHex: ld AReg,X+ ;convert 8 bytes to 16 ASCII Hex rcall Put1Hex ;characters dec ByteCount brne ROMHex
ldi YL,low(Buffer) ldi YH,high(Buffer) ROMOut: ld AReg,Y+ ;send characters in the buffer rcall SerOut ;to the serial port
cpi YL,low(Buffer+16) brcs ROMOut clr AReg st Y,AReg
| и т д
--------------------
тут могла быть Ваша реклама...
|