atmega8, problem z obsluga-inicjacja TWI

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
maciejkos
-
Posty: 3
Rejestracja: 02 lis 2009, 14:37
Lokalizacja: gliwice

atmega8, problem z obsluga-inicjacja TWI

Post autor: maciejkos » 02 lis 2009, 14:54

Jestem na etapie pisania programu obsługi czujnika TSL2561(przetwornik natężenie światła-wartość cyfrowa) w assemblerze na atmedze8 w związku z czym mam parę pytań. Póki co probuję inicjować komunikację poprzez TWI i już na tym program się wysypuje. Atmega8 pracuje na wewnętrznym oscylatorze 1MHz -> ustawiłem TWBR=1 oraz TWPS 00 (wartość 1). wyliczyłem że Fscl=41,6 kHZ. Czy to jest zrobione prawidłowo i czy ma prawo działać?;)

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
++++++++++++++++++++
już po problemie, poradziłem sobie.

ODPOWIEDZ