⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2313temp8.asm

📁 temp cont with assmbly code
💻 ASM
📖 第 1 页 / 共 3 页
字号:
        adc    XL,BReg
        brcc   GR1   
        inc    XH              ;carry set, so add to XH and point to device
GR1:
        sts    romoff,XL
        sts    romoff+1,XH     ;used to point to Temp result
        rcall  ROMatch         ;find it on the bus
        ldi    AReg,ConvertTemp ;convert Temperature command
        rcall  PutByte  
WaiTemp:
        rcall  GetBit          ;wait while busy           
        brcc   WaiTemp         ;DS18S20 will pull bus low while busy
        rcall  DSReset         ;reset bus
        rcall  ROMatch         ;select device again
        
        ldi    AReg,RdScratch  ;read scratchpad command
        rcall  PutByte
        ldi    XL,low(TempLSB) ;point to Scratchpad storage
        ldi    XH,high(TempLSB)  
RdMem:                         ;read in the 1820 scratchpad memory  
        rcall  GetByte         ;read result
        st     X+,AReg         ;ScratchL byte
        cpi    XL,low(TempLSB+9) ;read 9 bytes
        brcs   RdMem

        lds    AReg,TempMSB    ;Look at TempMSB
        sbrs   AReg,0          ;if bit 0 (or any bit) is 0
        rjmp   GExit           ;then it's a positive temperature
        lds    AReg,TempLSB    ;otherwise, it's a negative temp
        neg    AReg            ;so do a 2's complement of the temp
        sts    TempLSB,AReg    ;and save before continuing
GExit:
        cli
        ret 
		      
;********************************************** 
;* GetTemp                                    *
;* Reads the extended Temperatures from the   *
;* DS1820/18S20 device selected in A.         * 
;* Result stored in the AReg storage area     *
;**********************************************
GetTemp:
        rcall  GetRegs
;Get Temp falls through to calculate the extended temperature value

;***************************************************************************
;* CvtExt  converts the extended temperature into degrees C                *
;* In the DS18S20 data sheet, this formula is given as:                    *
;* Temp = Temp_Read - 0.25 + ( count_per_c - count_remain)/count_per_c     *
;* where Temp_Read is TempLSB shfted right to eliminate the 0.5C bit       *
;* This formula can be simplified.In the DS18S20,count_per_c is always 16  *
;* Temp = Temp_Read - 0.25 + (16-count_remain)/16                          *
;* Multiply everything by 16 to simplify the code:                         *
;* 16*Temp = 16*Temp_Read - 4 + (16-count_remain) which becomes:           *
;* 16*Temp = 16*Temp_Read + 12 - count_remain                              *
;* Multiplying everything by 25 and dividing by 4 eliminates fixed point   *
;* numbers. The result is a 16 bit number with the temperature in the      *
;* MSB and the fractional (extended) temperature in the LSB                *
;* Convert the data in TempLSB to ASCII, add a decimal point in the output *
;* string, then convert ExtTemp  to ASCII                                  *
;***************************************************************************
CvtExt:
        lds    ScratchL,TempLSB;If TempLSB > 1 then LSR
        lsr    ScratchL        ;shift right (divide by 2) to get rid of 0.5C bit
        mov    MpyLo,ScratchL  ;get ready to multiply the value by 16

        ldi    ScratchL,16     ;TempLSB * 0016 
        clr    ScratchH          
        clr    MpyHi
        rcall  mpy16u          ;16 x 16 multiply
 
        mov    MpyHi,ScratchH  ;16 bit multiply result in MpyHi:MpyLo
        mov    MpyLo,ScratchL

 CE01:  lds    ScratchL,TempMSB
        sbrc   ScratchL,0      ;skip next instruction if TempMSB bit 0 is positive
        sen                    ;TempMSB was negative, so set the negative flag
        adiw   MpyHi:MpyLo,12  ;16*TempLSB + 12
 
        lds    ScratchL,CountRem
        lds    ScratchH,TempMSB;Get the high order Temperature byte
        sbrc   ScratchH,0      ;skip next instruction if TempMSB bit 0 is positive
        sen                    ;TempMSB was negative, so set the negative flag
        sub    MpyLo,ScratchL  ;subtract count remaining from low byte of Temp result
        brcc   CE1
        dec    MpyHi           ;there was a carry, so subtract it from the MSB
CE1:
        ldi    ScratchL,25     ;multiply result by 25: 25*(16*TempLSB + 12 - CountRemain)
        clr    ScratchH        ;
        rcall  mpy16u          ;result is a 16 bit number.
        		
        lsr    ScratchH       ;divided by 2
        ror    ScratchL
CE13:
        lsr    ScratchH       ;divided by 4
        ror    ScratchL

        sts    TempLSB,ScratchH  ;store temperature result
        sts    ExtTemp,ScratchL  ;store extended result

        ret

;**********************************************
;* TempCvt                                    *
;* converts the Temperature in degrees C into *
;* an ASCII string                            *
;**********************************************  
TempCvt:
        ldi    YL, low(Buffer)
        ldi    YH,high(Buffer)

        lds    AReg,TempMSB    ;Get the high order Temperature byte
        tst    AReg            ;Test high order byte
        brmi   TS0             ;ones indicate a negative Temperature
        ldi    AReg,'+'
        st     Y+,AReg         ;Save a + into the buffer
        rjmp   Cvt2BCD         
TS0:
        ldi    AReg,'-'
        st     Y+,AReg         ;Save a - into the buffer

Cvt2BCD:
        lds    BReg,TempLSB    ;convert temperature to 
        lds    AReg,ExtTemp    ;a packed BCD
        rcall  BIN2BCD16
        mov    AReg,r14        ;then convert the resulting 4 digits
        swap   AReg
        rcall  Put1Asc         ;to 4 ASCII characters
        mov    AReg,r14
        rcall  Put1Asc
        ldi    AReg,'.'        ;put a decimal point in the buffer
        st     Y+,AReg
        mov    AReg,r13
        swap   AReg
        rcall  Put1Asc
        mov    AReg,r13
        rcall  Put1Asc
        ldi    AReg,'C'  
        st     Y+,AReg

        clr    AReg
        st     Y,AReg
        ret

;**********************************************
;* "mpy16u" 16x16 Bit Unsigned Multiplication *
;* This subroutine multiplies the two 16-bit  *
;* register variables                         * 
;* ScratchH:ScratchL and BReg:AReg.           *
;* The result is placed in:                   *
;* r21:r20:ScratchH:ScratchL.                 *
;* The following registers are used:          *
;* MpyLo     ;multiplicand low byte           *   
;* MpyHi     ;multiplicand high byte          *
;* ScratchL ;multiplier low byte              *
;* ScratchH ;multiplier high byte             *
;* ScratchL ;result byte 0 (LSB)              *
;* ScratchH ;result byte 1                    *
;* r20      ;result byte 2                    *
;* r21      ;result byte 3 (MSB)              *
;* r22      ;loop counter                     *
;* Based on Atmel Application Note AVR 200    *
;**********************************************  
mpy16u:	
        clr    r21             ;clear 2 highest bytes of result
        clr    r20
        ldi    r22,16          ;init loop counter
        lsr    ScratchH
        ror    ScratchL

m16u_1:
        brcc   noad8           ;if bit 0 of multiplier set
        add    r20,MpyLo       ;add multiplicand Low to byte 2 of res
        adc    r21,MpyHi       ;add multiplicand high to byte 3 of res
noad8:
        ror    r21             ;shift right result byte 3
        ror    r20             ;rotate right result byte 2
        ror    ScratchH        ;rotate result byte 1 and multiplier High
        ror    ScratchL        ;rotate result byte 0 and multiplier Low
        dec    r22             ;decrement loop counter
        brne   m16u_1          ;if not done, loop more
        ret

;**********************************************
;* Bin2BCD16,16-bit Binary to BCD conversion  *
;* converts a 16 bit binary number to         *
;* a 5 digit packed BCD number                *
;* number to convert in BReg:AReg             *
;* returns MSB in ScratchH, LSB in ScratchL   *
;* The following registers are used:          *
;* r13 BCD value digits 1 and 0               *
;* r14 BCD value digits 3 and 2               *
;* r15 BCD value digit 4                      *
;* AReg r16 binary value Low byte             *
;* BReg r17 binary value High byte            *
;* ScratchL r18 loop counter                  *
;* ScratchH r19 temporary value               *
;* Based on Atmel Application Note AVR 204    *
;**********************************************  

.equ	AtBCD0	=13		;address of r13
.equ	AtBCD2	=15		;address of r14

bin2BCD16:
        ldi    ScratchL,16     ;Init loop counter	
        clr    r15             ;clear result (3 bytes)
        clr    r14		
        clr    r13		
        clr    ZH              ;clear ZH (not needed for AT90Sxx0x)
bBCDx_1:
        lsl    AReg            ;shift input value
        rol    BReg            ;through all bytes
        rol    r13
        rol    r14
        rol    r15
        dec    ScratchL        ;decrement loop counter
        brne   bBCDx_2         ;if counter not zero
        ret                    ;routine exit point

bBCDx_2:
        ldi    r30,AtBCD2+1    ;Z points to result MSB + 1
bBCDx_3:
        ld     ScratchH,-Z     ;get (Z) with pre-decrement
        subi   ScratchH,-$03   ;add 0x03
        sbrc   ScratchH,3      ;if bit 3 not clear
        st     Z,ScratchH      ;store back
        ld     ScratchH,Z      ;get (Z)
        subi   ScratchH,-$30   ;add 0x30
        sbrc   ScratchH,7      ;if bit 7 not clear
        st     Z,ScratchH      ;store back
        cpi    ZL,AtBCD0       ;done all three?
        brne   bBCDx_3         ;loop again if not
        rjmp   bBCDx_1		
  
;**********************************************
;* Convert the LSB nibble of AReg to an ASCII *
;* Hex character and stores it in the buffer  *
;* addressed by Y. Exit with Y pointing to    *
;* the next empty buffer location             *
;**********************************************
Put1Asc:
        andi   AReg,$0f
        cpi    AReg,$0a
        brmi   PTASC1
        ldi    BReg,7
        add    AReg,BReg
PTASC1:
        ldi    BReg,$30
        add    AReg,BReg
        st     Y+,AReg
        ret

;**********************************************
;* Converts the contents of AReg to 2 ASCII   *
;* Hex characters, storing them in the buffer *
;* addressed by Y. Exit with Y pointing to    *
;* the next empty buffer location             *
;**********************************************
Put1Hex:
        mov    r0,AReg
        lsr    AReg
        lsr    AReg
        lsr    AReg
        lsr    AReg
        rcall  Put1Asc
        mov    AReg,r0
        rcall  Put1Asc
        ret

;**********************************************
;* ParseIn  Scans incoming serial port data   *
;* and parses the commands:                   *
;* R: Outputs ROM count & ROM IDs to ser port *
;* Tn : Outputs the Temperature for sensor n  *
;* Vn : Outputs the register contents and     *
;*      temperature for sensor n              *
;**********************************************
ParseIn:
        cli                    ;block off interrupts
 
        rcall  SerIn           ;look at the incoming character
        andi   AReg,$5f        ;convert to uppercase
        cpi    AReg,'R'        ;ROM IDs found        
        brne   VData
         
        mov    AReg,ROMCount   ;it was an R - send # of devices found
        ldi    BReg,$30
        add    AReg,BReg       ;convert to an ASCII number
        rcall  SerOut          ;send it out the serial port
        rcall  OutCRLF
        rcall  ShowROM         ;send the ROM ID array out the serial port
        rjmp   PExit

VData:
        cpi    AReg,'V'        ;Verbose - sends DS1820 register contents & temp
        brne   TTest           ;exit if it isn't a Verbose Data command

        rcall  SerIn           ;read number of device
        subi   AReg,$30        ;convert it to binary
        cp     AReg,ROMCount   ;make sure it's <= to the device count
        brcc   PExit           ;exit otherwise

        rcall  GetRegs         ;read in the register values
        rcall  ShowData        ;convert it to ASCII and send out the serial port
        rcall  CvtExt          ;calculate the extended temperature value 
        rjmp   TT1             ;finish off by displaying the temperature

TTest:  
        cpi    AReg,'T'        ;Calculate and send temperatire 
        brne   PExit

        rcall  SerIn           ;read number of device
        subi   AReg,$30        ;convert it to binary
        cp     AReg,ROMCount   ;make sure it's <= to the device count
        brcc   PExit           ;exit otherwise
        rcall  GetTemp         ;Get the extended temperature and
TT1:    
        rcall  TempCvt         ;convert it to ASCII

        ldi    XL,low(Buffer)  ;point to the converted Scratch buffer
        ldi    XH,high(Buffer) 
SenDat:
        ld     AReg,X+
        tst    AReg            ;output strings are NULL terminated
        breq   SDEnd           ;end of buffer; send a CRLF
        rcall  SerOut          ;send the buffer data until a 0 is detected
        rjmp   SenDat 
 
SDEnd:  
        rcall  OutCRLF
PExit:
        sei                    ;enable interrupts
        reti
    
;**********************************************
;* Code ends here.                            *
;**********************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -