Skocz do zawartości

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


Pomocna odpowiedź

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.

Link to post
Share on other sites

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.

Link to post
Share on other sites
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?

Link to post
Share on other sites
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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.

Link to post
Share on other sites

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ć 🙂

Link to post
Share on other sites

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 ?

Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.