Skocz do zawartości

[c] TWI w atmega 128. Błąd przy komendzie Start.


Pomocna odpowiedź

Napisano

Witam,
Ostatnio natknąłem się na problem którego na razie nie jestem w stanie rozwiązać samodzielnie.

Otóż jestem w trakcie budowy robota minisumo. Mam zamiar wykorzystać w nim akcelerometr i żeby móc go obsługiwać potrzebna mi będzie obsługa magistrali TWI/I2C. Zacząłem więc pisać do niej sterownik jednakże bez większych sukcesów.

Funkcja: (umieściłem w niej inicjalizację żeby było wszystko lepiej widoczne)

int accelerometer_x()
{
             SCL_OUT;   //SCL_OUT DDRD  |=  (1<<0)
SDA_OUT;  //SDA_OUT DDRD  |=  (1<<1)

             TWBR=0x64; //skopiowałem z jakiego kodu w internecie
             TWSR=(0<<TWPS1)|(0<<TWPS0); // Prescaler 64

int Position = 0;

TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // Wysyłam komende start
while (!(TWCR & (1<<TWINT))); 
if((TWSR & 0xF8) != 0x08) //  ??? Nie mam pojęcia czemu tu jest 0x08
{
	lcd_text("  NIE BANGLA ",0,0);
	lcd_text("Błąd przy wys-",0,1);
	lcd_text("łaniu komendy ",0,2);
	lcd_text("START         ",0,3);
	_delay_ms(400);
}

TWDR = (0b0011100<<1); //adres akcelerometru + bit wysyłki danych
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));

if((TWSR & 0xF8) != 0x40) //  ??? Nie mam pojęcia czemu tu jest 0x40
{
	lcd_text("  NIE BANGLA ",0,0);
	lcd_text("Błąd przy wys-",0,1);
	lcd_text("łaniu adresu! ",0,2);
	_delay_ms(400);
}

return Position;
}

W kodzie przy znakach zapytania znajdują się miejsca które zapożyczyłem z innych programów i nie mogłem znaleźć co oznaczają.

Problem polega na tym ,że po sprawdzeniu któregokolwiek warunku z if'a wykonuje się funkcja wewnątrz tego warunku. Wygląda na to ,że program nie wysyła poprawnie ani komendy START ani adresu urządzenia.

Czy jest możliwość ,że problem leży po stronie źle przylutowanego przyspieszeniomierza ?

Za każdą pomoc będę bardzo wdzięczny.

Najważniejsza kwestia: masz podciągnięte linie danych i zegara do zasilania przez rezystor? u mnie nie chciało to działać dopóki nie skorzystałem z zewnętrznego podciągnięcia.

if((TWSR & 0xF8) != 0x08) // ??? Nie mam pojęcia czemu tu jest 0x08

Sprawdzasz tutaj czy w rejestrze statusu TWI nie został zgłoszony błąd przy wysyłania komendy START;)

Przejrzałem swój działający kod do obsługi TWI też na Atmedze 128 i wysyłam Start tak samo jak Ty.Jednak linie zegara i danych mam ustawione jako wejscia bez pull-up'a ( w sumie nie pamiętam dlaczego).

I jeszcze jedna kwestia - wyłączyłeś kompatybilność z Atmega 103?

Mam wyłączoną kompatybilność z atmegą 103.

Zastanawiam się czy źródłem problemu może być źle przylutowany akcelerometr lub system przerwań który używam w programie.

Udało mi się rozwiązać pierwszy problem. Spowodowany był on nie wysłaniem komendy stop po skończonej transmisji jako ,że funkcja była w pętli to po pierwszym jej wykonaniu przestawała działać poprawnie.

Nadal mam jednak problem z wysyłaniem adresu.

Przede wszystkim poczytaj sobie trochę o tym, jak I2C działa 🙂

Polecam ten opis -> www.elektroda.pl/rtvforum/download.php?id=352630 Dowiesz się tutaj co oznaczają poszczególne kody i po co się je sprawdza.

Dodatkowo polecam Ci zaopatrzenie się w bibliotekę do obsługi I2C i rozbudowanie jej wg własnych potrzeb, ja do realizacji swojego projektu korzystałem z tej -> http://homepage.hispeed.ch/peterfleury/avr-software.html

Na stronie jest pomoc do funkcji, wszystko jest bardzo ładnie opisane więc da się zrozumieć 🙂

  • 2 lata później...

Mam podobny problem z obsługą TWI w atmedze. Przeczytałem powyższego PDF-a na temat obsługi TWI, stworzyłem coś takiego:

LCD_Initalize();

LCD_WriteText("test");

i2c_init(100);

_delay_ms(2000);

//wysłanie bitu start

TWCR |= (1<

while(!(TWCR &(1<

//sprawdzenie statusu

if (!(TWSR & 0xF8) != TW_START)

{

LCD_GoTo(0,1);

LCD_WriteText("ERR 1");

}

//wysłanie adresu sla +W

TWDR = 0x3C;

TWCR |= (1<

while(!(TWCR & (1<

//wysłanie kodu instrukcji

TWDR = 0x1E;

TWCR |= (1<

while(!(TWCR & (1<

//wysłanie bitu stop

TWCR |= (1<

while(!(TWCR & (1<

Jest to procedura resetu układu MS5611, mam dwa nowe moduły z tymi układami, w obu przypadkach tak samo działa. Nie sądzę by oba były uszkodzone.

Nie działało więc zacząłem sprawdzać statusy, i już po wysłaniu bitu start rejestr statusu wskazuje na błąd.

Na oscyloskopie / analizatorze to wygląda tak, o ile pierwszy bajt danych zawierający addr SLA+W jest wysłany, o tyle drugiego nie ma.

Ktoś ma pomysł jak sobie poradzić z tym problemem ?

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...