И снова здравствуйте, уважаемые. Это снова я со своими глупыми вопросамию
Решил я в свою программу, которую обсуждал тут же добавить таймер, чтоб с определённой ячейки DSки через определённое время велось считывание данных и отображалось на светодиодах программатора - порт D (для начала, в будущем буду сохранять куда нить в другое место). Модернизировал немного прогу, но что-то не работает. Подскажите - где я накосячил....
Код: Выделить всё
.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8def.inc"
; TWI (I2C) Мастер, приём-передача
;результат выводится в порт D
;Подключние файла, объявление имён регистров ATmega8
.equ TW_START = 0x08
.equ TW_RESTART = 0x10
.equ MT_SLA_ACK = 0x18
.equ MT_DATA_ACK = 0x28
.equ MR_SLA_ACK = 0x40
.equ MR_DATA_ACK = 0x50
.equ MR_DATA_NACK = 0x58
.equ SLA_R = $69
.equ SLA_W = $68
.def tmp = R17
.cseg
.org 0
;---------- Вектора прерываний ----------
rjmp INIT
nop
nop
nop
nop
nop
nop
nop
rjmp TIM0_OVF
;----------
;=============
;Считывание из регистра $14 микросхемы DS2782 числа 0b10011001
;=============
twi_r:
; Повторный старт
ldi tmp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)
out TWCR,tmp
; Ждать окончания операции
rcall wait
; Проверка кода ответа 0x10
cpi tmp,TW_RESTART
brne twi_err
; Если ОК - загрузка и передача адреса
ldi tmp,SLA_W
out TWDR,tmp
ldi tmp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
out TWCR,tmp
; Ждать окончания операции
rcall wait
; Проверка кода ответа 0x18
cpi tmp,MT_SLA_ACK
brne twi_err
; Если ОК - загрузка указателя адреса
;=============;
; Адрес для считывания!!! ;
;=============;
ldi tmp,$14
out TWDR,tmp
ldi tmp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
out TWCR,tmp
; Ждать окончания операции
rcall wait
; Проверка кода ответа 0x28
cpi tmp,MT_DATA_ACK
brne twi_err
twi_r1:
; Повторный старт
ldi tmp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)
out TWCR,tmp
; Ждать окончания операции
rcall wait
; Проверка кода ответа 0x10
cpi tmp,TW_RESTART
brne twi_err
; Если ОК - загрузка и передача адреса
ldi tmp,SLA_R
out TWDR,tmp
ldi tmp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
out TWCR,tmp
; Ждать окончания операции
rcall wait
; Проверка кода ответа 0x18
cpi tmp,MR_SLA_ACK
brne twi_err
; Приём байта c подтверждением
ldi tmp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)
out TWCR,tmp
; Ждать окончания операции
rcall wait
; Проверка кода 0x58
cpi tmp,MR_DATA_ACK
brne twi_err
; Данные приняты - считать и сохранить.
in tmp,TWDR
rjmp twi_r1
; Сформировать стоп
ldi tmp,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
out TWCR,tmp
;Начало программы
INIT: ;PROG
ldi R16,high(RAMEND)
out SPH,R16
ldi R16,low(RAMEND)
out SPL,R16
ldi R16,$FF ;DDRB=$FF
out DDRD,R16
;Инициализация TWI,установка частоты SCL
ldi R16,$20 ;TWI.SCLfreguency=100K(8Mhz)
out TWBR,R16
;Сброс в 0 битов TWPS1:TWPS0 регистра TWSR
in R16,TWSR
andi R16,$FC
out TWSR,R16
ldi r16,0b00000101 ; загружаем константу
out TCCR0,r16 ; делитель таймера CK/1024
ldi r16,$01
out TIMSK,r16 ; разрешаем прерывание timer0 по переполнению
ldi r16,$00
out TCNT0,r16 ;начальное значение счетчика - 0
sei ; разрешить прерывания
rjmp twi_r ; возврат в тело цикла
;===========
; Обработчик ошибок
twi_err:
nop
nop
nop
nop
nop
nop
nop
nop
rjmp twi_end
;===========
; Выход из режима работы с TWI
twi_end:
ret
;===========
; Процедура ожидания завершения операции
;===========
wait:
in tmp,TWCR
sbrs tmp,TWINT
rjmp wait
in tmp,TWSR
andi tmp,0xF8
ret
;===========
; Обработка прерывания
;===========
TIM0_OVF:
in tmp,TWDR
out PORTD,tmp
reti
PS. Ещё может кто подскажет - как проверять работу TWI с учётом таймера. А то я что-то даже не могу понять - работает он или нет (таймер в смысле).