В результате "долгих" раздумий и экспериментов получил вот такой код, на основе которого были сделаны прошивки для всех at89c2051:
Code: Select all
;================================================================
; программа эмуляции датчика температуры ds1621(4) на at89c2051
;================================================================
; константы и определения
;================================================================
sda equ p1.0
scl equ p1.1
led equ p3.7
first_sda equ 020h
flags1 equ first_sda+1
var1 equ flags1+1
address equ var1+1
ds_temp_l equ address+1
ds_temp_h equ ds_temp_l+1
command equ ds_temp_h+1
ds_readtemp equ 0aah
ds_startconv equ 0eeh
ds_stopconv equ 022h
ds_config equ 0ach
i2c_start bit flags1.0
i2c_its_me bit flags1.1
was_command bit flags1.2
;================================================================
; точка входа по reset
;================================================================
org 0000h
jmp start
org 0100h
;================================================================
; подпрограммы
;================================================================
;инкремент "температуры"
inc_temp:
mov a, ds_temp_l
inc a
mov ds_temp_l, a
jnc _inc_temp_d1
mov a, ds_temp_h
inc a
mov ds_temp_h, a
_inc_temp_d1:
ret
;================================================================
wait_action:
setb sda
setb scl
jnb scl, $
mov a, P1
anl a, #001h
mov first_sda, a
_wait_end_strobe:
mov a, P1
anl a, #001h
cjne a, first_sda, _wait_exit
jb scl, _wait_end_strobe
_wait_exit:
ret
;========================================================================
write_byte:
mov b, #008h ;счетчик бит
_write_byte_l1:
jb acc.7,_write_byte_d1 ;если младший бит = 1, то перейдем на посылку "1"
clr sda ;иначе пошлем "0"
jmp _write_byte_d2 ;перейдем на формирование строба
_write_byte_d1:
setb sda ;пошлем "1"
_write_byte_d2:
jnb scl, $ ;ждем начала строба
rl a ;сдвинем старший бит в младший
jb scl, $ ;ждем окончания строба
djnz b, _write_byte_l1 ;если не все передали, то вернемся к началу
setb sda
jnb scl, $ ;ждем начала строба
mov a, P1 ;читаем подтверждение
jb scl, $ ;ждем окончания строба
ret ;вернемся назад
;========================================================================
byte_readed:
jnb i2c_start, _not_start
clr i2c_start
mov b, a
clr acc.0
cjne a, address, _br_exit
clr sda
jnb scl, $
setb i2c_its_me
clr was_command
jb scl, $
setb sda
jnb b.0, _br_exit
mov a, command
cjne a, #ds_config, _not_config
mov a, var1
jmp write_byte
_not_config:
cjne a, #ds_readtemp, _br_exit
mov a, dS_temp_h
call write_byte
jb acc.0, _br_exit
mov a, ds_temp_l
jmp write_byte
_not_start:
jnb i2c_its_me, _br_exit
clr sda
jnb scl, $
jb scl, $
setb sda
jb was_command, _was_command
mov command, a
setb was_command
cjne a, #ds_startconv, _br_exit
jmp inc_temp
_was_command:
mov b, a
mov a, command
cjne a, #ds_config, _br_exit
mov var1, b
_br_exit:
ret
;========================================================================
; основной цикл
;========================================================================
start:
mov p0, #0ffh
mov p1, #0ffh
mov p2, #0ffh
mov p3, #0ffh
mov a, p3
anl a, #01ch
rr a
orl a, #090h
mov address, a
clr i2c_start
clr i2c_its_me
clr a
mov ds_temp_h, a
mov ds_temp_l, a
restart_read:
mov b, #008h
clr a
main_loop:
rl a
mov r0, a
call wait_action
cjne a, first_sda, _is_condition
orl a, r0
djnz b, main_loop
call byte_readed
jmp restart_read
_is_condition:
clr i2c_start
clr i2c_its_me
orl a, #000h
jnz restart_read ;was stop condition
jb scl, $
setb i2c_start
jmp restart_read
;================================================================
; конец
;================================================================
end