Atmega128 i zegar M41T00 - problem

Aug 30, 2006 1 Replies

Mam M41T00 (i2c) podpiety do Atmega128 i chcialbym z niego odczytac wszystkie 8 rejestrow za jednym zamachem. W dokumentacji do M41T00 napisali, ze jest to mozliwe, wedlug schematu: START adres RTC (czyli D0) R/W=0 ACK Adres pierwszego rejestru do odczytania ACK START adres RTC (czyli D0) R/W=1 ACK Dane z pierwszego rejestru ACK Dane z kilejnego rejestru ACK Dane z klejnego rejestru ACK itd...



Niestety udaje mi sie poprawnie odczytac tylko pierwszy rejestr, potem odbieram tylko $FF mimo ze kolejne rejestry zawieraja inne dane, jesli je czytac osobno. Ponizej zamieszczam procki w asm. I2C_Read dziala dobrze, a I2C_Read_Word odczytuje poprawnie tylko pierwszy bajt. Program puszczam pod emulatorem JTAGICE wiec mam podglad na biezaco. Macie moze jakies sugestie? Co zmienic, zeby zadzialalo? Bardzo podobnie odczytuje sie pamieci 24LC16 i pokrewne, moze z nimi macie doswiadczenie. Pozdrawiam. /PM



.macro WAIT wait1: LDS tmp,TWCR sbrs tmp,TWINT rjmp wait1 .endmacro ;********************************************************************* .macro START ldi tmp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);send START STS TWCR,tmp .endmacro ;********************************************************************* .macro STOP ldi tmp,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN) ;send STOP STS TWCR,tmp .endmacro ;********************************************************************* I2C_Setup: LDI tmp,10 ;szybkosc 28KHz przy zegarze 1MHz STS TWBR,tmp LDI tmp,(0<<TWPS1)|(0<<TWPS0) STS TWSR,tmp RET ;********************************************************************* ; WYWO£ANIE: ; tmp=adres do odczytania ; ZWRACA: ; tmp=odczytany bajt I2C_Read: ^^^^^^^^ ta procka dziala OK bo odczytuje tylko jeden bajt push tmp ;zapamietuje adres do odczytania



START



WAIT



ldi tmp,(ADDRRTC|SDA_W) ;send RTC Address STS TWDR,tmp ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp



WAIT



pop tmp ;przywracam adres do odczytania STS TWDR,tmp ;send Word Address ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp



WAIT



START



WAIT



ldi tmp,(ADDRRTC|SDA_R) ;send RTC Address STS TWDR,tmp ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp



WAIT



ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp



WAIT



STOP



LDS tmp,TWDR ;bajt odczytany



ret ;********************************************************************* ; WYWO£ANIE: ; tmp=adres do odczytania ; ZWRACA: ; tmp=1 bajt ; tmp2=2 bajt I2C_Read_Word: ^^^^^^^^^^^^^ ta procka odczytuje poprawnie pierwszy bajt a w drugim zwraca $FF(a nie powinna)



push tmp



START



WAIT



ldi tmp,(ADDRRTC|SDA_W) ;send RTC Address STS TWDR,tmp ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp



WAIT



pop tmp STS TWDR,tmp ;send Word Address ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp



WAIT



START



WAIT



ldi tmp,(ADDRRTC|SDA_R) ;send RTC Address STS TWDR,tmp ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp



WAIT



ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp



WAIT



LDS tmp,TWDR ;1 bajt odczytany push tmp ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp



WAIT



STOP



LDS tmp2,TWDR ;2 bajt odczytany pop tmp



ret



Odpowiem sobie sam, bo znalazlem rozwiazanie. Atmaga musi wyslac sygnal ACK po odebraniu kazdego bajtu, czyli trzeba ustawic bit TWEA w TWCR. Inaczej RTC mysli, ze nie chcemy od niego kolejnych bajtow danych i konczy transmisje. Poprawiona procka jest ponizej. Pozdrawiam /PM PS: moze komus sie to przyda ;)

I2C_Read_Word:

push tmp

START

WAIT

ldi tmp,(ADDRRTC|SDA_W) ;send RTC Address STS TWDR,tmp ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp

WAIT

pop tmp STS TWDR,tmp ;send Word Address ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp

WAIT

START

WAIT

ldi tmp,(ADDRRTC|SDA_R) ;send RTC Address STS TWDR,tmp ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp

WAIT

ldi tmp,(1<<TWINT)|(1<<TWEN|1<<TWEA) ;<to wlasnie ta linijka zostala poprawiona STS TWCR,tmp

WAIT

LDS tmp,TWDR ;bajt odczytany push tmp ldi tmp,(1<<TWINT)|(1<<TWEN) STS TWCR,tmp

WAIT

STOP

LDS tmp2,TWDR ;bajt odczytany pop tmp

ret

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required