Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

DS18B20 18F Math Code

Status
Not open for further replies.

Mike - K8LH

Well-Known Member
Just ported DS18B20 (assembly language) math code from 16F' to 18F' (taking advantage of the 18F' hardware multiplier) a couple months ago and thought I'd post it for anyone who might be interested since there is some discussion about the DS18B20 at the moment.

Mike

Code:
;******************************************************************
;
;  CtoC - binary °C*16 to decimal °C*10000 (4 decimal places)
;
;  °C*10000 = 625 * T18B20H:L
;
;  Bcd3:0 packed bcd output -00550000 to +01250000 (°C*10000)
;
;
;                  TempH:L Neg  Output    Display
;     ============================================
;     125.0000°C   h'07D0'  0  01250000  125.0000°C
;     100.0000°C   h'0640'  0  01000000  100.0000°C
;      77.0000°C   h'04D0'  0  00770000   77.0000°C
;      25.0000°C   h'0190'  0  00250000   25.0000°C
;      22.0000°C   h'0160'  0  00220000   22.0000°C
;       0.5000°C   h'0008'  0  00005000    0.5000°C
;       0.0625°C   h'0001'  0  00000625    0.0625°C
;       0.0000°C   h'0000'  0  00000000    0.0000°C
;     - 0.0625°C   h'FFFF'  1  00000625  - 0.0625°C
;     - 0.1250°C   h'FFFE'  1  00001250  - 0.1250°C
;     - 5.0000°C   h'FFB0'  1  00050000  - 5.0000°C
;     -10.0000°C   h'FF60'  1  00100000  -10.0000°C
;     -17.0625°C   h'FEEF'  1  00170625  -17.0625°C
;     -17.6875°C   h'FEE5'  1  00176875  -17.6875°C
;     -17.7500°C   h'FEE4'  1  00177500  -17.7500°C
;     -17.8125°C   h'FEE3'  1  00178125  -17.8125°C
;     -25.0000°C   h'FE70'  1  00250000  -25.0000°C
;     -55.0000°C   h'FC90'  1  00550000  -55.0000°C
CtoC
        movlw   high(0xfee5)    ; <- movf DS18B20H,W
        movwf   AH              ;
        movlw   low(0xfee5)     ; <- movf DS18B20L,W
        movwf   AL              ;
        movlw   high(625)       ;
        movwf   BH              ;
        movlw   low(625)        ;
        movwf   BL              ;
        rcall   Mult16x16       ; signed 16x16 multiply
        bcf     Flags,neg       ;
        btfss   Prod3,7         ; negative?
        bra     CtoC.1          ; no, branch, else
        bsf     Flags,neg       ;
        comf    Prod3,F         ;
        comf    Prod2,F         ;
        comf    Prod1,F         ;
        negf    Prod0           ;
        bnc     CtoC.1          ;
        incf    Prod1,F         ;
        skpnz                   ;
        incf    Prod2,F         ;
        skpnz                   ;
        incf    Prod3,F         ; 65 cycles to this point
CtoC.1
        bra     Bin2Bcd         ;
Code:
;******************************************************************
;
;  CtoF - binary °C*16 to decimal °F*10000 (4 decimal places)
;
;  °F*10000 = 1125 * DS18B20H:L + 320000
;
;  Bcd3:0 packed bcd output -00670000 to +02570000 (°F*10000)
;
;
;                  TempH:L Neg  Output    Display
;     ============================================
;     125.0000°C   h'07D0'  0  02570000  257.0000°F
;     100.0000°C   h'0640'  0  02120000  212.0000°F
;      77.0000°C   h'04D0'  0  01706000  170.6000°F
;      25.0000°C   h'0190'  0  00770000   77.0000°F
;      22.0000°C   h'0160'  0  00716000   71.6000°F
;       0.5000°C   h'0008'  0  00329000   32.9000°F
;       0.0625°C   h'0001'  0  00321125   32.1125°F
;       0.0000°C   h'0000'  0  00320000   32.0000°F
;     - 0.0625°C   h'FFFF'  0  00318875   31.8875°F
;     - 0.1250°C   h'FFFE'  0  00317750   31.7750°F
;     - 5.0000°C   h'FFB0'  0  00230000   23.0000°F
;     -10.0000°C   h'FF60'  0  00140000   14.0000°F
;     -17.0625°C   h'FEEF'  0  00012875    1.2875°F
;     -17.6875°C   h'FEE5'  0  00001625    0.1625°F
;     -17.7500°C   h'FEE4'  0  00000500    0.0500°F
;     -17.8125°C   h'FEE3'  1  00000625  - 0.0625°F
;     -25.0000°C   h'FE70'  1  00130000  -13.0000°F
;     -55.0000°C   h'FC90'  1  00670000  -67.0000°F

CtoF
        movlw   high(0xfee3)    ; <- movf DS18B20H,W
        movwf   AH              ;
        movlw   low(0xfee3)     ; <- movf DS18B20L,W
        movwf   AL              ;
        movlw   high(1125)      ;
        movwf   BH              ;
        movlw   low(1125)       ;
        movwf   BL              ;
        rcall   Mult16x16       ; signed 16x16 multiply
        movlw   high(320000)    ;
        addwf   Prod1,F         ;
        movlw   upper(320000)   ;
        addwfc  Prod2,F         ;
        movlw   0               ;
        addwfc  Prod3,F         ;
        bcf     Flags,neg       ;
        btfss   Prod3,7         ; negative?
        bra     CtoF.1          ; no, branch, else
        bsf     Flags,neg       ;
        comf    Prod3,F         ;
        comf    Prod2,F         ;
        comf    Prod1,F         ;
        negf    Prod0           ;
        bnc     CtoF.1          ;
        incf    Prod1,F         ;
        skpnz                   ;
        incf    Prod2,F         ;
        skpnz                   ;
        incf    Prod3,F         ; 71 cycles to this point
CtoF.1
        bra     Bin2Bcd         ;
Code:
;******************************************************************
;
;  16 x 16 -> 32 signed multiply (16 bit core)
;
;  AL*BL + AH*BH*256*256 + AH*BL*256 + AL*BH*256
;
;  40 words, 43 cycles (including call and return)
;
Mult16x16
        movf    AL,W            ; W = AL                          |
        mulwf   BL              ; AL * BL
        movff   PRODL,Prod0     ; -- -- -- LL
        movff   PRODH,Prod1     ; -- -- MM --

        movf    AH,W            ; W = AH
        mulwf   BH              ; AH * BH * 256 * 256
        movff   PRODL,Prod2     ; -- HH -- --
        movff   PRODH,Prod3     ; UU -- -- --

        mulwf   BL              ; AH * BL * 256
        movf    PRODL,W         ;
        addwf   Prod1,F         ; -- -- MM --
        movf    PRODH,W         ;
        addwfc  Prod2,F         ; -- HH -- --
        movlw   0               ;
        addwfc  Prod3,F         ; UU -- -- --

        movf    AL,W            ; W = AL
        mulwf   BH              ; AL * BH * 256
        movf    PRODL,W         ;
        addwf   Prod1,F         ; -- -- MM --
        movf    PRODH,W         ;
        addwfc  Prod2,F         ; -- HH -- --
        movlw   0               ;
        addwfc  Prod3,F         ; UU -- -- --

SignB
        btfss   BH,7            ; BH:BL argument negative?
        bra     SignA           ; no, branch, else
        movf    AL,W            ;
        subwf   Prod2,F         ;
        movf    AH,W            ;
        subwfb  Prod3,F         ;
SignA
        btfss   AH,7            ; AH:AL argument negative?
        bra     Mulxit          ; no, branch, else
        movf    BL,W            ;
        subwf   Prod2,F         ;
        movf    BH,W            ;
        subwfb  Prod3,F         ;
Mulxit
        return                  ;
Please note that the BINL+0..BINL+2 input variables have been equated to Prod0..Prod2 to eliminate several movff instructions.

Caveat! This code simulates fine but I recall there may be a 'bug' in the daw (decimal adjust) instruction.
Code:
;******************************************************************
;
;  Bin2Bcd -- 24 bit binary to 8 digit packed BCD (16 bit core)
;
;  Number Range: 000000..FFFFFF (0..16,777,215)
;
;  28 words, 537 cycles (including call and return)
;
Bin2Bcd
        clrf    BCDL+0          ; LSB..MSB
        clrf    BCDL+1          ;
        clrf    BCDL+2          ;
        clrf    BCDL+3          ;
        movlw   24              ;
        movwf   BitCtr          ;
ConvertBit
        rlcf    BINL+0,F        ; LSB..MSB
        rlcf    BINL+1,F        ;
        rlcf    BINL+2,F        ;
        movf    BCDL+0,W        ;
        addwfc  BCDL+0,W        ;
        daw                     ;
        movwf   BCDL+0          ;
        movf    BCDL+1,W        ;
        addwfc  BCDL+1,W        ;
        daw                     ;
        movwf   BCDL+1          ;
        movf    BCDL+2,W        ;
        addwfc  BCDL+2,W        ;
        daw                     ;
        movwf   BCDL+2          ;
        movf    BCDL+3,W        ;
        addwfc  BCDL+3,W        ;
        daw                     ;
        movwf   BCDL+3          ;
        decfsz  BitCtr,F        ;
        bra     ConvertBit      ;
        return                  ;
I use these defines in some 18F' applications for the missing 18F' "skip" instructions. I hope my use of them in one or two places in the above code doesn't mess anyone up.
Code:
#define skpnz   btfsc   STATUS,Z
#define skpz    btfss   STATUS,Z
#define skpnc   btfsc   STATUS,C
#define skpc    btfss   STATUS,C
 
Last edited:
Pretty Cool... I dont have a DS18B20 but if i did i would be thanking you :) Just reading this makes me want to get one and play around. In fact i just ordered a sample from Maxim. I might use this in real world. (Comming soon wireless room control.. like control A/C , shades, door(s), TV and more from wireless touch panel.)
 
I recall you write in both Assembler and C so that's great. I'm happy to know someone may be able to use the code.

Have fun, Mike
 
Yes, you are correct i write in both. The benefit is that i learn how things work with assembler and i if i know how it works i can write short code in C :D
 
Thank you for the code post!!

Remember some head scratching when converting the negative decimal part. Will have to compare when re-visiting the OW temp sensors. Thought it took a bazillion cycles to do 16x16 mult for the 14 bit family; The 18 bit family must be much more efficient?

Edit: Meant 16 bit family, or 18f's, all crossed up again.
 
Last edited:
Thank you for the code post!!

Remember some head scratching when converting the negative decimal part.
Yes, in my 16F' code I added one instruction to a PICLIST routine to turn it into an 8x16 "sign extended" multiply routine. That allowed me to perform the addition directly on the multiplication product before using an Absolute() function on the final number.

Will have to compare when re-visiting the OW temp sensors. Thought it took a bazillion cycles to do 16x16 mult for the 14 bit family; The 18 bit family must be much more efficient?
The 16F' multiply routines aren't that bad. My 16F' 8x16 "sign extended" multiply used 97..137 cycles. It's the 16F' bin2bcd routines that seem to eat up much more cycles compared to 18F' routines of similar function.

The 18F' hardware multiplier is cool but I still haven't figured out how to use it to do a signed 8x16 multiply.

Regards, Mike
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top