problem z 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
Awatar użytkownika
DarkJarek
-
Posty: 44
Rejestracja: 21 mar 2006, 15:48
Lokalizacja: ...
Kontakt:

problem z twi

Post autor: DarkJarek » 01 maja 2008, 15:23

Mam problem obsługą twi. Używam atmega32 jako i2c-master i wszystko działa dobrze ale tylko przez jakąś chwilę a puźniej program się zawiesza. Dokładniej to tam jest while który się zapętla po zapisie lub odczycie. Podejrzewam, że mogą to być zakłucenia jakieś. Ma ktoś jakiś pomysł? Częstotliwość pracy twi ustawiona jest na 10khz. Jako slave mam eeprom i ds1307. Godzinę odczytuję z zegara co sekundę.

ZbeeGin

Post autor: ZbeeGin » 01 maja 2008, 16:29

1. Prosze pokazać kod. Może gdzieś coś przeoczyłeś.
2. Jak taktowany jest procesor: typ generatora, częstotliwość.
3. 10kHz to nieco zbyt mało - może zjadłeś jedno zero podczas pisania posta. Jeśli jednak tak taktujesz TWI to lepiej zwiększyć częstotliwość do 100kHz
4. Czy czekasz na to gotowość układu TWI (bit TWINT = 1) podczas wystawiania warunku STOP? Jeśli tak to program się zatrzyma, gdyż TWI nie potwierdza w ten sposób STOPu.
5. Ostatni odczytany bajt powinno się potwierdzać przez NACK, jak jest u Ciebie?

Moja działająca procedurka (ASM) odczytu z pamięci 24C512 znajduje się tutaj: https://forum.elportal.pl/viewtopic.php?t=6977
Procedurka __wait_4_twiready czeka tylko na ustawienie TWINT. Dla pełności obrazu dodam jeszcze fragment inicjalizacyjny.

Kod: Zaznacz cały

;--------------------------------------------------------------
twi_setup:
        ldi     r16, 10                         ; preskaler TWI = 10
        out     TWBR, r16                       ;
        ldi     r16, (0 << TWPS1)|(0 << TWPS0)  ; TWPS = 0
        out     TWSR, r16                       ; co da nam fscl = 111kHz @8MHz
                                                ; koniec TWI
Ostatnio zmieniony 01 maja 2008, 17:16 przez ZbeeGin, łącznie zmieniany 1 raz.

Awatar użytkownika
DarkJarek
-
Posty: 44
Rejestracja: 21 mar 2006, 15:48
Lokalizacja: ...
Kontakt:

Post autor: DarkJarek » 01 maja 2008, 17:08

kod odpowiedzialny za obsługę i2c:

Kod: Zaznacz cały

#include "i2c.h"
#include <util/delay.h>

void i2c_init(void)
{
	TWBR = 25;
	TWSR = 2;
	TWCR = _BV(TWEN) | _BV(TWEA) | _BV(TWIE);
}

void i2c_start(void)
{
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
	while (!(TWCR & (1<<TWINT)));
}

void i2c_stop(void)
{
	TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
	while ((TWCR & (1<<TWSTO)));
}

void i2c_write(char data)
{
	TWDR = data;
	TWCR = (1<<TWINT) | (1<<TWEN);
	while (!(TWCR & (1<<TWINT)));
}

char i2c_read(char ack)
{
	TWCR = ack? ((1 << TWINT) | (1 << TWEN) | (1 << TWEA)): ((1 << TWINT) | (1 << TWEN)) ;
	while (!(TWCR & (1<<TWINT)));
	return TWDR;
}
Procesor taktowany jest wewnętrznym oscylatorem 8MHz.
Próbowałem z róznymi częstotliwościamy 400,200,50,10kHz, z każdą to samo.
Z tego co zauważyłem while się zapętla tylko w procedurach odczytu i zapisu. Nigdy w stacie lub stopie.
Podkreślę, że odczyt i zapis działa. Ale do pewnego czasu. Około minuty czasami krócej a czasami dłużej.

[ Dodano: 2008-05-01, 21:41 ]
Problem został rozwiązany. Trochę mi głupio bo okazało się że szukałem błędu nie tam gdzie trzeba. Problemy sprawiał sam ds1307 który bez kondensatora między masą a zasilaniem czasami dziwnie się zachowuje.
Ostatnio zmieniony 03 maja 2008, 8:36 przez DarkJarek, łącznie zmieniany 1 raz.

ODPOWIEDZ