;; Dallas DS1820 multidrop routines using timer 0 in mode 3 for MCS51 ;; External power for DS1820 assumed ;; Clock is 11.0592 MHz -> one cycle is 1.0850694 us ;; Copyright 1999, Leon Kos, University of Ljubljana ;; TODO: Initial check routines for external power on each device ;; $Id: ds1820.asm,v 1.2 2003/09/13 15:31:57 leon Exp $ NAME DS1820 APD BIT 0F8h ; P5.0 driving gate of the DMOS for READ BIT 0EFh ; P4.7 reading response from slaves ds1820_routines SEGMENT CODE T1_interrupt SEGMENT CODE ds1820rom SEGMENT CODE dowcrc SEGMENT CODE ds1820data SEGMENT DATA bitvar SEGMENT BIT public ds1820_init public _ds1820_start public touch_byte public convert_time public ds1820error public scratchpad public ds1820crc_ok public errornum public ds1820device CSEG AT 0001BH jmp timer1 RSEG T1_interrupt timer1: push acc ; 2 push psw ; 2 push dpl ; 2 push dph ; 2 jnb bit_state, matchROM_loop bit_loop: ; bit writing/reading loop clr APD setb bit_state ; enable this state mov c, read_slot mov a, touch_byte rrc a mov touch_byte, a djnz bitcnt, touch_bit mov bitcnt, #9 clr bit_state jmp exit_t1 touch_bit: setb APD ; 1T nop ; 1T nop nop nop ; 1T cpl c ; 1T mov APD, c ; 1T nop nop nop nop nop nop nop mov c, READ mov read_slot, c mov TH0, #(0FFh - 30) pop dph ; 2 pop dpl ; 2 pop psw ; 2 pop acc ; 2 reti matchROM_loop: jnb matchROM_state, reset_state_loop mov a, loop ; test the loop counter clr C ; clear for one byte substraction subb a, #8 ; loop couner in incrementing jz _rom_end ; substract to match zero at end mov dptr, #rom_table; point to in CODE device table mov a, ds1820device ; which device rl a ; address rl a ; is multiple of rl a ; 8 offset add a, loop ; select byte from table movc a, @a+dptr mov touch_byte, a inc loop jmp bit_loop _rom_end: clr matchROM_state inc state jmp state_loop reset_state_loop: jnb reset_state, state_loop mov a, loop dec a jz _reset_end mov loop, a add a, #254 jnz _rst0 clr APD _rst0: jmp exit_t1 _reset_end: clr reset_state inc state state_loop: ; Main state machine loop mov a, state ; must be in the middle mov dptr, #jump_table; of the code movc a, @a+dptr jmp @a+dptr jump_table: db reset0 - jump_table db match_rom0 - jump_table db convertT - jump_table db readbusy - jump_table db reset1 - jump_table db match_rom1 - jump_table db read_scratchpad - jump_table db temp_lsb - jump_table db temp_msb - jump_table db user_byte1 - jump_table db user_byte2 - jump_table db reserved1 - jump_table db reserved2 - jump_table db count_remain - jump_table db count_per_c - jump_table db crc - jump_table db stop - jump_table reset0: mov loop, #4 setb reset_state mov TH0, #(255-200) ; first half of the reset time setb APD jmp exit_t1 match_rom0: mov touch_byte, #55h mov loop, #0 setb matchROM_state jmp bit_loop convertT: mov touch_byte, #44h inc state mov convert_time, #00h mov convert_time + 1, #00h jmp bit_loop readbusy: ; check every 280us inc convert_time + 1; mov a, convert_time + 1 jnz _noinc inc convert_time mov a, #12h ; 12*72ms=860ms overrun anl a, convert_time jz _noinc setb ds1820error ; short circuit mov errornum, #1 ; to long zero resonse jmp end_t1 _noinc: mov a, touch_byte mov touch_byte, #0FFh inc a jz converted jmp bit_loop converted: clr C inc state reset1: mov loop, #4 setb reset_state mov TH0, #(255-200) ; first half of the reset time setb APD jmp exit_t1 match_rom1: mov touch_byte, #55h mov loop, #0 setb matchROM_state jmp bit_loop read_scratchpad: mov touch_byte, #0BEh inc state jmp bit_loop temp_lsb: ; larger but easy to fetch bytes mov touch_byte, #0FFh inc state jmp bit_loop temp_msb: mov scratchpad, touch_byte mov touch_byte, #0FFh inc state jmp bit_loop user_byte1: mov scratchpad + 1, touch_byte mov touch_byte, #0FFh inc state jmp bit_loop user_byte2: mov scratchpad + 2, touch_byte mov touch_byte, #0FFh inc state jmp bit_loop reserved1: mov scratchpad + 3, touch_byte mov touch_byte, #0FFh inc state jmp bit_loop reserved2: mov scratchpad + 4, touch_byte mov touch_byte, #0FFh inc state jmp bit_loop count_remain: mov scratchpad + 5, touch_byte mov touch_byte, #0FFh inc state jmp bit_loop count_per_c: mov scratchpad + 6, touch_byte mov touch_byte, #0FFh inc state jmp bit_loop crc: mov scratchpad + 7, touch_byte mov touch_byte, #0FFh inc state jmp bit_loop stop: mov scratchpad + 8, touch_byte end_t1: clr ET1 ; disable interrupt clr TR1 ; stop the timer mov state, #0 ; reset the machine state clr APD ; power the line exit_t1: ; exit from interrupt pop dph ; 2 pop dpl ; 2 pop psw ; 2 pop acc ; 2 reti RSEG ds1820_routines ds1820_init: ; initialize the variables mov bitcnt, #9 ; bit counter clr APD ; power the devices on line setb READ ; enable reading clr matchROM_state ; not sending match ROM to ds1820 clr bit_state ; not in the bit delay state clr reset_state ; not in the reset state mov state, #0 ; clear machine state mov ds1820device,#0 ; default is reading device0 anl TMOD, #0f0h ; timer 0 orl TMOD, #03h ; in mode 3 setb EA ; Enable interrupts ret _ds1820_start: ; R7 has the device number to read mov ds1820device,R7 mov TH0,#0FAh clr ds1820error ; no error at beginning mov errornum, #0 setb ET1 setb TR1 ret RSEG dowcrc ds1820crc_ok: ; extern bit ds1820crc_ok(void); mov loop, #9 ; 8+1 byte CRC mov ds1820crc, #0 ; clear CRC register mov dptr, #dowcrc_table mov r0, #scratchpad _crc: mov a, @r0 ; scratchad value xrl a, ds1820crc movc a, @a+dptr mov ds1820crc, a inc r0 djnz loop, _crc jz _ok clr CY ret _ok: setb CY ret dowcrc_table: DB 0, 94, 188, 226, 97, 63, 221, 131 DB 194, 156, 126, 32, 163, 253, 31, 65 DB 157, 195, 33, 127, 252, 162, 64, 30 DB 95, 1, 227, 189, 62, 96, 130, 220 DB 35, 125, 159, 193, 66, 28, 254, 160 DB 225, 191, 93, 3, 128, 222, 60, 98 DB 190, 224, 2, 92, 223, 129, 99, 61 DB 124, 34, 192, 158, 29, 67, 161, 255 DB 70, 24, 250, 164, 39, 121, 155, 197 DB 132, 218, 56, 102, 229, 187, 89, 7 DB 219, 133, 103, 57, 186, 228, 6, 88 DB 25, 71, 165, 251, 120, 38, 196, 154 DB 101, 59, 217, 135, 4, 90, 184, 230 DB 167, 249, 27, 69, 198, 152, 122, 36 DB 248, 166, 68, 26, 153, 199, 37, 123 DB 58, 100, 134, 216, 91, 5, 231, 185 DB 140, 210, 48, 110, 237, 179, 81, 15 DB 78, 16, 242, 172, 47, 113, 147, 205 DB 17, 79, 173, 243, 112, 46, 204, 146 DB 211, 141, 111, 49, 178, 236, 14, 80 DB 175, 241, 19, 77, 206, 144, 114, 44 DB 109, 51, 209, 143, 12, 82, 176, 238 DB 50, 108, 142, 208, 83, 13, 239, 177 DB 240, 174, 76, 18, 145, 207, 45, 115 DB 202, 148, 118, 40, 171, 245, 23, 73 DB 8, 86, 180, 234, 105, 55, 213, 139 DB 87, 9, 235, 181, 54, 104, 138, 212 DB 149, 203, 41, 119, 244, 170, 72, 22 DB 233, 183, 85, 11, 136, 214, 52, 106 DB 43, 117, 151, 201, 74, 20, 246, 168 DB 116, 42, 200, 150, 21, 75, 169, 247 DB 182, 232, 10, 84, 215, 137, 107, 53 alternate_dowcrc: ; slower and thus not used mov ds1820crc, #0 mov loop, #8 ; 8 bytes mov r0, #scratchpad _dcrc: mov a, @r0 call do_crc inc r0 djnz loop, _dcrc ret do_crc: push acc push b push acc mov b, #8 crc_loop: xrl a, ds1820crc rrc a mov a, ds1820crc jnc zero xrl a, #18h zero: rrc a mov ds1820crc, a pop acc rr a push acc djnz b, crc_loop pop acc pop b pop acc ret RSEG ds1820data bitcnt: ds 1 ; bit couter touch_byte: ds 1 ; touch byte scratchpad: ds 9 ; DS1820 scratchpad convert_time: ds 2 ; time required for conversion state: ds 1 ; machine state loop: ds 1 ; shared byte for loops errornum: ds 1 ; error number ds1820device: ds 1 ; which device number 0,1,... ds1820crc: ds 1 ; DOW 8 bit CRC value RSEG bitvar read_slot: DBIT 1 ; read bit from ds1820 bit_state: DBIT 1 ; delaying one bit state matchROM_state: DBIT 1 ; sending MATCH ROM state reset_state: DBIT 1 ; resetting the bus state ds1820error: DBIT 1 ; error getting temperature RSEG ds1820rom rom_table: ; avalable devices on the 1-wire net device0: DB 10h, 09Ah, 4Bh, 09h, 00h, 00h, 00h, 08Fh device1: DB 10h, 088h, 3Dh, 0Ch, 00h, 00h, 00h, 0CAh device2: DB 10h, 05Bh, 49h, 09h, 00h, 00h, 00h, 0A4h device3: DB 10h, 022h, 49h, 09h, 00h, 00h, 00h, 0AAh device4: DB 10h, 0DAh, 4Ah, 09h, 00h, 00h, 00h, 037h device5: DB 10h, 099h, 48h, 09h, 00h, 00h, 00h, 098h device6: DB 10h, 021h, 47h, 09h, 00h, 00h, 00h, 051h device7: DB 10h, 0EEh, 47h, 09h, 00h, 00h, 00h, 0EAh device8: DB 10h, 06Eh, 47h, 09h, 00h, 00h, 00h, 000h device9: DB 10h, 0D3h, 49h, 09h, 00h, 00h, 00h, 0EFh device10: DB 10h, 09Ah, 47h, 09h, 00h, 00h, 00h, 0AEh device11: DB 10h, 0B1h, 4Ah, 09h, 00h, 00h, 00h, 00Ch device12: DB 10h, 08Bh, 4Ah, 09h, 00h, 00h, 00h, 02Eh device13: DB 10h, 03Ch, 4Bh, 09h, 00h, 00h, 00h, 061h device14: DB 10h, 074h, 49h, 09h, 00h, 00h, 00h, 036h device15: DB 10h, 024h, 48h, 09h, 00h, 00h, 00h, 0D5h device16: DB 10h, 057h, 49h, 09h, 00h, 00h, 00h, 0D9h device17: DB 10h, 050h, 04h, 0B0h,90h, 00h, 00h, 0DFh END