Вот вся процедура чтения с PCF8583
Может не совсем красиво
;===========================================================
;====Чтение данных с PCF8583====
;===========================================================
clock:
rcall start_i2c ;Стартуем шину i2c
ldi tmp2,0b10100000 ;загружаем адрес в который пишим
rcall outSLAW_i2c ;передаём
ldi tmp2,$02 ;загружаем байт который пишем
rcall outdata_i2c ;передаём
rcall povstart_i2c;Повстарт
ldi tmp2,0b10100001 ;загружаем адрес с которого читаем
rcall outSLAR_i2c ;передаём
rcall indata_i2c ;читаем первый байт
mov sek,tmp2 ;первый байт - секунды
rcall indata_i2c ;читаем второй байт
mov min,tmp2 ;второй байт - минуты
rcall indata_i2c ;читаем третий байт
mov chas,tmp2 ;третий байт - часы
rcall povstart_i2c;Повстарт
ldi tmp2,0b10100000 ;переводим девайс на чтение
rcall outSLAW_i2c ;(по другому не заработало)
rcall stop_i2c ;Останавливаем шину i2c
ret
;===========================================================
;=====Модуль для работы интерфейса i2c=====
;===========================================================
;====Условие Start====
start_i2c:
ldi err,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
out TWCR,err
wait1:
in err,TWCR
sbrs err,TWINT
rjmp wait1
in err,TWSR ;Если бит TWINT регистра TWCR не установился то ждем
andi err,0xF8
cpi err,$08 ;Если код статуса = $08 старт был
brne codeerror ;иначе ошибка
ret
;====Повторный старт====
povstart_i2c: ;Условие пов_старт
ldi err,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
out TWCR,err
wait2:
in err,TWCR
sbrs err,TWINT
rjmp wait2 ;Если бит TWINT регистра TWCR не установился то ждем
in err,TWSR
andi err,0xF8
cpi err,$10 ;Если код статуса = $10 пов_старт был
brne codeerror ;иначе ошибка
ret
;====Условие Stop====
stop_i2c:
ldi err,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
out TWCR,err
ret
;====Выводим адрес в каторый будем записывать====
outSLAW_i2c:
mov err,tmp2 ;tmp2=адресу в который пишем+W(0)
out TWDR,err
ldi err,(1<<TWINT) | (1<<TWEN)
out TWCR,err
wait3:
in err,TWCR
sbrs err,TWINT
rjmp wait3 ;Если бит TWINT регистра TWCR не установился то ждем
in err,TWSR
andi err,0xF8
cpi err, $18 ;Если код статуса = $18 был передан пакет и принято АСК
brne codeerror ;иначе ошибка
ret
;====Выводим адрес с которого быдем считывать====
outSLAR_i2c:
mov err,tmp2 ;tmp2=адресу c которого считываем+R(1)
out TWDR,err
ldi err,(1<<TWINT) | (1<<TWEN)
out TWCR,err
wait4:
in err,TWCR
sbrs err,TWINT
rjmp wait4 ;Если бит TWINT регистра TWCR не установился то ждем
in err,TWSR
andi err,0xF8
cpi err, $40 ;Если код статуса = $18 был передан пакет и принято АСК
brne codeerror ;иначе ошибка
ret
;=====Выводим данные====
outdata_i2c:
mov err,tmp2 ;tmp2=байт для передачи
out TWDR,err
ldi err,(1<<TWINT) | (1<<TWEN)
out TWCR,err
wait5:
in err,TWCR
sbrs err,TWINT
rjmp wait5 ;Если бит TWINT регистра TWCR не установился то ждем
in err,TWSR
andi err,0xF8
cpi err, $28 ;Если код статуса = $18 был передан пакет и принято АСК
brne codeerror ;иначе ошибка
ret
;====Принимаем данные====
indata_i2c:
ldi err,(1<<TWINT) | (1<<TWEN)|(1<<TWEA)
out TWCR,err
wait6: ;(4)
in err,TWCR
sbrs err,TWINT
rjmp wait6 ;Если бит TWINT регистра TWCR не установился то ждем
in tmp2,TWDR ;tmp2=принятый байт
in err,TWSR
andi err,0xF8
cpi err, $50 ;Если код статуса = $50 был принят пакет и передано АСК
brne codeerror ;иначе ошибка
ret
;===========================================================
;=====END=====
;===========================================================