Witam.
Natrafiłem na pewien uciążliwy problem... W swoim projekcie realizuję transmisję przez TWI między AVRem a zegarem czasu rzeczywistego DS1307. Wykorzystuję sprzętową obsługę TWI. Transmisję w obie strony, czyli zapis czasu do DS1307 oraz późniejsze jego odczytywanie, udało mi się zrealizować i jako tako to działało. Tylko że wszystko działo się to jeszcze póki ATmega32 pracowała z domyślnym zegarem czyli wewnętrznym oscylatorem 1MHz. Gdy zaprogramowałem Fuse Bity tak aby umożliwić pracę z zewnętrznym rezonatorem 16MHz transmisja przestała działać. Transmisja powinna działać z częstotliwością 100kHz i wiem że powinno się ustawiać rejestry TWBR i preskaler w TWSR tak aby tą częstotliwość osiągnąć. Jednak wcześniej (przed programowaniem Fuse Bitów) zapomniałem o tym i działało a teraz ustawiłem TWBR na 72, czyli 16Mhz/(16+2*72*1)=100kHz i niby powinno działać a tak nie jest. Ma ktoś pomysł co może być nie tak? Program piszę w asemblerze. Poniżej zamieszczam moją procedurę zapisu:
Natrafiłem na pewien uciążliwy problem... W swoim projekcie realizuję transmisję przez TWI między AVRem a zegarem czasu rzeczywistego DS1307. Wykorzystuję sprzętową obsługę TWI. Transmisję w obie strony, czyli zapis czasu do DS1307 oraz późniejsze jego odczytywanie, udało mi się zrealizować i jako tako to działało. Tylko że wszystko działo się to jeszcze póki ATmega32 pracowała z domyślnym zegarem czyli wewnętrznym oscylatorem 1MHz. Gdy zaprogramowałem Fuse Bity tak aby umożliwić pracę z zewnętrznym rezonatorem 16MHz transmisja przestała działać. Transmisja powinna działać z częstotliwością 100kHz i wiem że powinno się ustawiać rejestry TWBR i preskaler w TWSR tak aby tą częstotliwość osiągnąć. Jednak wcześniej (przed programowaniem Fuse Bitów) zapomniałem o tym i działało a teraz ustawiłem TWBR na 72, czyli 16Mhz/(16+2*72*1)=100kHz i niby powinno działać a tak nie jest. Ma ktoś pomysł co może być nie tak? Program piszę w asemblerze. Poniżej zamieszczam moją procedurę zapisu:
;wysłanie danych - tryb Master Transmitter
i2c_write: LDI R16,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN) ;sekwencja startowa
OUT TWCR, R16
wait1: IN R16,TWCR ;oczekiwanie na ustawienie flagi TWINT
SBRS R16,TWINT
RJMP wait1
IN R16,TWSR ;sprawdzenie poprawności statusu startu
ANDI R16,0xF8
CPI R16,START
BRNE error_w
LDI R16,SLA_W ;wysłanie Slave Address + W
OUT TWDR,R16
LDI R16,(1<<TWINT)|(1<<TWEN)
OUT TWCR,R16
wait2: IN R16,TWCR ;oczekiwanie na ustawienie flagi TWINT
SBRS R16,TWINT
RJMP wait2
IN R16,TWSR ;sprawdzenie poprawności statusu SLA_W
ANDI R16,0xF8
CPI R16,MT_SLA_ACK
BRNE error_w
MOV R16,WORD_ADDR ;wysłanie adresu wskaźnika dla DS1307
OUT TWDR,R16
LDI R16,(1<<TWINT)|(1<<TWEN)
OUT TWCR,R16
wait3: IN R16,TWCR ;oczekiwanie na ustawienie flagi TWINT
SBRS R16,TWINT
RJMP wait3
IN R16,TWSR ;sprawdzenie poprawności statusu danych
ANDI R16,0xF8
CPI R16,MT_DATA_ACK
BRNE error_w
MOV R16,DATA_W ;wysłanie bajtu danych
OUT TWDR,R16
LDI R16,(1<<TWINT)|(1<<TWEN)
OUT TWCR,R16
wait4: IN R16,TWCR ;oczekiwanie na ustawienie flagi TWINT
SBRS R16,TWINT
RJMP wait4
IN R16,TWSR ;sprawdzenie poprawności statusu danych
ANDI R16,0xF8
CPI R16,MT_DATA_ACK
BRNE error_w
LDI R16,(1<<TWINT)|(1<<TWEN)|(1<<TWSTO) ;sekwencja stop
OUT TWCR,R16
RET