Листинг П5.3

;файл I2С.рrg

;Процедуры чтения и записи по интерфейсу I2C

;+----------- порт D ---------+

.equ pSCL = 4

.equ pSDA = 6

;-------------------------------

.def DATA = r17

.def ClkA = r18

.def cnt = r23

.def AddrL = r24  ;адреса EEPROM

.def AddrH = r25

;---------------- запись EEPROM ------------

WriteFlash:  ;в AddrL,AddrH — адрес, данные в DATA

                  ;на выходе если бит с = 1 в регистре флагов, то ошибка

         cbi PORTD,pSDA

         cbi PORTD,pSCL

         ldi cnt,120  ;120 попыток прописать

loop120f:

         push DATA

         rcall start

         ldi DATA,0xA0  ;addr device=0,r/w=0

         rcall write

         brcs rt_writef  ;C=1 ERROR

         mov DATA,AddrH  ;set HI address

         rcall write

         brcs rt_writef  ;C=1 ERROR

         mov DATA,AddrL  ;set LO address

         rcall write

         brcs rt_writef  ;C=1 ERROR

         pop DATA  ;set data to DATA

         rcall write

         brcs rt_f  ;C=1 ERROR

         rcall stop

         brcs rt_f  ;C=1 ERROR

         ret

;--------------- чтение EEPROM -------------

ReadFlash:  ;в AddrL,AddrH — адрес, данные в DATA

                  ;если бит с = 1 в регистре флагов, то ошибка

         cbi PORTD,pSDA

         cbi PORTD,pSCL

ldi cnt,120

loop_read_f:

         rcall start

         ldi DATA,0xA0  ;addr device=0,r/w=0

         rcall write

         brcs rt__f  ;C=1 ERROR

         mov DATA,AddrH  ;set HI address

         rcall write

         brcs rt__f  ;C=1 ERROR

         mov DATA,AddrL  ;set LO address rcall write

         brcs rt__f  ;C=1 ERROR

         rcall start

         ldi DATA,0xA1  ;addr device=0,r/w=1

         rcall write

         brcs rt__f  ;C=1 ERROR

         clt;  ;no put ACK

         rcall read

         rcall stop

         brcs rt__f  ;G=1 ERROR

         ret

rt__f:

         dec cnt

         brne loop_read_f

         ret

rt_writef:

         pop DATA

rt_f:

         brcc Ok_wr_f

         dec cnt

         brne loop120f

Ok_wr_f:

         ret

;------------ запись RTC ------------

write_i2c:  ;b ClkA — адрес, данные в DATA

                  ;если бит с = 1 в регистре флагов, то ошибка

         cbi PORTD,pSDA

         cbi PORTD,pSCL

         ldi cnt,120  ;120 попыток прописать

lоор120:

         push DATA

         rcall start

         ldi DATA,0bi1010000  ;addr device,r/w=0

         rcall write

         brcs rt_write  ;C=1 ERROR

         mov DATA,ClkA  ;set HI address

         rcall write

         brcs rt_write  ;C=1 ERROR

         pop DATA  ;set data to DATA

         rcall write

         brcs rt_  ;C=1 ERROR

         rcall stop

         brcs rt_  ;C=1 ERROR

         ret

;-----------чтение RTC-----------

read_i2c:  ;ClkA — адрес, данные в DATA

                ;если бит с = 1 в регистре флагов, то ошибка

         cbi PORTD,pSDA

         cbi PORTD,pSCL

ldi cnt,120

loop_read_:

         rcall start

         ldi DATA 0b11010000  ;addr device,r/w=0

         rcall write  ;C=1 ERROR

         mov DATA ClkA  ;set HI address

         rcall write

         brcs rt  ;C=1 ERROR

         rcall stare

         ldi DATA, 0b11010001  ;addr device, r/w=1

         rcall write

         brcs rt  ;C=1 ERROR

         clt  ;no put ACK

         rcall read

         rcall stop

         brcs rt  ;C=1 ERROR

         ret

rt__:

         dec cnt

         brne loop_read_

         ret

rt_write:

         pop DATA

rt_:

         brcc Ok_wr_

         dec cnt

         brne loop120

Ok_wr_:

         ret

;--------------------------------

write:  ;запись байта из DATA

         push DATA

         push cnt

         ldi cnt,8  ;счетчик бит

x42:

         rol DATA

         brcs sei

         sbi DDRD,pSDA

         rjmp del_wr

sel:

         cbi DDRD,pSDA

del_wr:

         cbi DDRD,pSCL

         rcall delay

         sbi DDRD,pSCL

         rcall delay

         dec cnt

         brne x42  ;следующий бит

         cbi DDRD,pSDA  ;освободить pSDA для АСК

         rcall delay

         cbi DDRD,pSCL

         rcall delay

         clc

         sbic PIND,pSDA  ;читаем в бит С состояние АСК

         sec  ;АСК не пришел

         sbi DDRD,pSCL

         rcall delay

         pop cnt

         pop DATA

         ret

read:  ;чтение в DATA, бит t=1 —> ответить АСК, t=0 не отвечать АСК

         ldi DATA,1

loop_read:

         sbi DDRD,pSCL  ;SCL=0

         cbi DDRD,pSDA  ;SDA=1

         rcall delay

         cbi DDRD,pSCL  ;SCL=1

         rcall delay

         clc

         sbic PIND,pSDA  ;читать SDA в бит С

         sec

         rol DATA

         brcc loop_read

         ;отсылаем ACK ()

         sbi DDRD,pSCL  ;SCL=0

         rcall delay

         brts se0

         cbi DDRD,pSDA  ;не отвечать ACK (t), SDA=1

         rjmp rd_

se0:

         sbi DDRD,pSDA  ;отвечать ACK (t), SDA=0

rd_:

         clc

         rcall delay

         cbi DDRD,pSCL  ;SCL=1

         rcall delay

ret

start:

         cbi DDRD,pSDA

         cbi DDRD,pSCL

         rcall delay

         sbis PINC,pSDA

         rjmp start

         sbis PINC,pSCL

         rjmp start

         sbi DDRD,pSDA  ;0=SDA

         rcall delay

         sbi DDRD,pSCL  ;0=SCL

         rcall delay

ret

stop:

         sbi DDRD,pSDA

         sbi DDRD,pSCL

         rcall delay

         cbi DDRD,pSCL  ;1=SCL

         rcall delay

         cbi DDRD.pSDA  ;1=SDA

         rcall delay

         clc

         sbic PIND,pSDA

         ret

sbic PIND,pSCL

         ret

         sec

ret

delay:  ;~5 мкс (кварц 4 МГц)

          push cnt

          ldi cnt,6

cyk_delay: dec cnt

          brne cyk_delay

          pop cnt

ret

Перейти на страницу:

Поиск

Похожие книги