Flaga TWINT ustawia się (program sprawdza jej ustawienie i idzie dalej) ale sprawdzenie poprawności przesłania instrukcji w rejestrze statusu TWSR już generuje błąd i nie wiem dlaczego.
dorzucam kod programu i będę wdzięczny za wszelkie uwagi.
Kod: Zaznacz cały
.INCLUDE "m8def.inc"
.def temp = r16
.def zero = r20
.def czekaj = r21
.def licznik = r22
.def DATA = r24
.def ustaw = r25
.def secure = r30
.def maska = r31
.equ SLA1_W=0x92 ;adres czujnika (VCC na ADR SEL) 1001001 oraz bit 7=0 ;(zapis)
.equ SLA1_R=0x93 ;adres czujnika (VCC na ADR SEL) 1001001 oraz bit 7=1 ;(odczyt)
.CSEG
.ORG 0x000
rjmp Reset
Reset:
ldi R17, high(RAMEND) ;stos
ldi R16, low(RAMEND)
out SPH, R17
out SPL, R16
;******** wylaczenie WATCHDOG-a ***
cli
wdr ; reset watchdoga
out MCUSR,zero ;wyzerowanie WDRF w rejestrze MCUSR musi nastapic przed wpisem zero do WDE
ldi temp,(1<<WDCE|1<<WDE);wpisanie 0 lub 1 do WDE jest tylko mozliwe przy WDCE=1
sts WDTCSR,temp
ldi temp,(0<<WDE)
sts WDTCSR,temp
ldi secure,SLA1_W ;zapis odpowiedniego adresu (zapis-secure, maska-odczyt) dla czujnika TSL2561
ldi maska,SLA1_R
sbi DDRD, DDD5 ;dioda
cbi DDRC,DDC0 ; klawiatura 0
cbi PORTC, PORTC0
cbi DDRC,DDC1 ; klawiatura 1
cbi PORTC, PORTC1
cbi DDRC,DDC2 ; klawiatura 2
cbi PORTC, PORTC2
cbi DDRC,DDC3 ; klawiatura 3
cbi PORTC, PORTC3
cbi DDRC,DDC4
sbi PORTC, PORTC4 ; SDA
cbi DDRC,DDC4
sbi PORTC, PORTC5 ; SCL
cbi PORTD, PORTD5
rcall TSL2561
main:
rjmp main
;******** podprogram obsługi czujnika TSL2561 ********
;*** Start interfejsu I2C ***
I2CSTART:
cbi TWSR,0
cbi TWSR,1
ldi temp,0xA4 ;rozpoczecie transmisji warunkiem START TWCR-10100100
sts TWCR,temp ; ustawione TWINT,TWSTA,TWEN
CZEKAJ1:lds temp,TWCR ;czekaj do chwili gdy flaga TWINT=1
sbrs temp,TWINT
rjmp CZEKAJ1
lds temp,TWSR ;sprawdzenie poprawnosci przeslania instrukcji START w statusowym TWSR
andi temp,0xF8 ;oraz REPEATED START (08 oraz 10h) - na tym koniec działania - TWSR się nie ustawia
cpi temp,START
breq WYJDZ
cpi temp,REPSTART
brne ZLE ;
ZLE: rjmp BLAD
WYJDZ: ret
;*** Wyslanie adresu wraz z bitem zapis ***
AD_WRITE:
sts TWDR,temp ;transmisja adresu urzadzenia z bitem odczyt/zapis
sts TWCR,ustaw ;w temp - SLA1_W - ardes zapisu
; w ustaw ustaw,0x84;(1<<TWINT) | (1<<TWEN); TWINT=1 TWEN=1
CZEKAJ2:lds temp,TWCR;
sbrs temp,TWINT;
rjmp CZEKAJ2
lds temp,TWSR ;sprawdzenie poprawnosci przeslania adresu wraz
andi temp,0xF8 ;z bitem odczyt/zapis
cpi temp,ADRES_WOK
brne BLAD
ret
;*** Wyslanie adresu wraz z bitem odczyt ***
AD_READ:
sts TWDR,temp ;w temp - SLA1_R adres odczytu
sts TWCR,ustaw ;transmisja adresu urzadzenia z bitem odczyt/zapis
; w ustaw ustaw,0x84;(1<<TWINT) | (1<<TWEN); TWINT=1 TWEN=1
CZEKAJ4:lds temp,TWCR;
sbrs temp,TWINT;
rjmp CZEKAJ4
lds temp,TWSR ;sprawdzenie poprawnosci przeslania adresu wraz
andi temp,0xF8 ;z bitem odczyt/zapis
cpi temp,ADRES_ROK
brne BLAD
ret
;*** Zapisanie danej przy uzyciu I2C ***
DANE_WR:sts TWDR,temp ;w temp 0x80 wartosc COMMAND odpowiadajaca rejestrowi kontrolnemu lub powerup czujnika;
sts TWCR,ustaw ;w ustaw ustaw,0x84;(1<<TWINT) | (1<<TWEN); TWINT=1 TWEN=1
CZEKAJ3:lds temp,TWCR
sbrs temp,TWINT
rjmp CZEKAJ3
lds temp,TWSR ;sprawdzenie poprawnosci przeslania danej
andi temp,0xF8
cpi temp,DANE_WOK
brne BLAD
ret
;*** Odczytanie danej przy uzyciu I2C ***
DANE_RD:sts TWCR,ustaw ;w ustaw 0x84;(1<<TWINT) | (1<<TWEN); TWINT=1 TWEN=1
CZEKAJ5:lds temp,TWCR
sbrs temp,TWINT
rjmp CZEKAJ5
lds temp,TWSR ;sprawdzenie poprawnosci przeslania danej
andi temp,0xF8
cpi temp,DANE_ROK
brne BLAD
lds temp,TWDR
ret
;*** Koniec przesyłania interfejsem I2C ***
I2CSTOP:ldi temp,0x94 ;instrukcja STOP; TWINT TWEN TWSTO
sts TWCR,temp
ret
;*** Blad podczas transmisji przez I2C ***
BLAD: push r16
push r17 ;sygnalizacja wizualna bledu
sbi PORTD, PORTD5
ldi R16, 200
ldi R17, 10
rcall Czekaj_ms ;swieci dioda
cbi PORTD, PORTD5
ldi R16, 200
ldi R17, 10
rcall Czekaj_ms
pop r17
pop r16
rjmp BLAD
;***** petla glowna podprogramu TSL2561 *****
TSL2561:
cli
ldi temp,0x01 ;ustawienie wspolczynnika podzialu na wartosc 1
sts TWBR,temp
ldi ustaw,0x84 ;(1<<TWINT) | (1<<TWEN); TWINT=1 TWEN=1 wykorzystane pozniej w procedurach
GLOWNY: rcall I2CSTART
ldi temp,SLA1_W ;ustawienie czujnika na zapis
rcall AD_WRITE
ldi temp,0x80 ;wartosc COMMAND odpowiadajaca rejestrowi kontrolnemu;
rcall DANE_WR ;zgodnie z tabelą 2 dokumentacji technicznej
ldi temp,0x03 ;POWERUP czujnika
rcall DANE_WR
ldi temp,0x08 ;przerwa czasowa na wykonanie pomiaru
PRZERWA:ldi czekaj,0xFF
rcall TIMEOUT
dec temp
brne PRZERWA
ldi DATA,0x8C ;wartosc COMMAND odpowiadajaca rejestrowi DATA0LOW
ldi licznik,0x04
PRZEKAZ:rcall I2CSTART ;rozpoczecie na nowo transmisji w celu odebrania wyniku
ldi temp,SLA1_W ;ustawienie czujnika na zapis
rcall AD_WRITE
mov temp,DATA ;wartosc COMMAND pozwalajaca na odczyt z rejestrow danych
rcall DANE_WR
rcall I2CSTART
ldi temp,SLA1_R ;ustawienie czujnika na odczyt
rcall AD_READ
rcall DANE_RD ;odczyt z rejestru i zapis do pamieci mikrokontrolera
st X+,temp ;??????????????? wybranie odpowiedniego miejsca w pamieci
dec licznik
breq END_I2C
inc DATA ;przesuniecie adresu na kolejny rejestr danych
rjmp PRZEKAZ
END_I2C:rcall I2CSTOP
ret
problem już rozwiązany.