nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 16 Apr 2024 05:07



Reply to topic  [ 1 post ] 
Реализация I2C slave-device на примере at89c2051 
Author Message
God

Joined: 02 Jan 2006 02:28
Posts: 1390
Location: Abakan
Reply with quote
Примерно год назад делал небольшой проект, в котором требовалось собирать информацию с множества датчиков по RS232 и I2C. Когда источников RS232 один или два, то можно подобрать соответствующий микроконтроллер, с нужным количеством последовательных портов, но источников было несколько, а искать многопортовое решение не было времени. Потому, я сдел "ход конём" и повесил несколько процессоров at89c2051 для сбора информации. Далее оставалось организовать сбор всех потоков в одну кучу. Здесь решающим фактором было использование уже имеющейся шины I2C, по которой происходил сбор информации с других датчиков без какого-либо преобразования. Оставалось написать код, который бы отслеживал состояние линий I2C, и адекватно принимал и отправлял нужную информацию.
В результате "долгих" раздумий и экспериментов получил вот такой код, на основе которого были сделаны прошивки для всех at89c2051:
Code:
;================================================================
; программа эмуляции датчика температуры 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


15 Apr 2006 21:17
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 1 post ] 

Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.