Skocz do zawartości

Problem z uruchomieniem Żyroskopu[ L3G4200D]


MacGyver

Pomocna odpowiedź

Witajcie, mam dość dziwny problem, próbuje odczytywać dane przez TWI(I2C) z żyroskopu(gotowy moduł), płytka ewaluacyjna(także w postaci gotowego modułu):

chcąc odczytać wartość z którejś z osi np X, dostaje daną, lecz nie zostaje ona odświeżana, co oznacza, że cały czas wysyłana jest ta sama liczba(do PC przez UART);

Sama komunikacja moim zdaniem przebiega poprawie, ponieważ wysyłając zapytanie o wartość rejestru 0x0F(Who I Am) otrzymuje poprawną wartość. Poniżej program:

Domyślam się, że mogę robić błąd w konfiguracji

konfiguracja TWI:

void i2cSetBitrate(uint16_t bitrateKHz) {
uint8_t bitrate_div;

bitrate_div = ((F_CPU/1000l)/bitrateKHz);
if(bitrate_div >= 16)
	bitrate_div = (bitrate_div-16)/2;

TWBR = bitrate_div;
}

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

void TWI_write(uint8_t bajt) {
TWDR = bajt;
TWCR = (1<<TWINT)|(1<<TWEN);
while ( !(TWCR&(1<<TWINT)));
}

uint8_t TWI_read(uint8_t ack) {
TWCR = (1<<TWINT)|(ack<<TWEA)|(1<<TWEN);
while ( !(TWCR & (1<<TWINT)));
return TWDR;
}


Program Główny:

int main()
{

sei();			//zezwolenie na globalne przerwania
DDRC=0;
PORTC|=(1<<PC0)|(1<<PC1);

	 	i2cSetBitrate(100);	//	ustawienie predkosci żyroskopu

		TWI();				//zakoncz komunikacje

		TWI();				//zakoncz komunikacje

		TWI();	

		TWI();				//zakoncz komunikacje

		TWI();				//zakoncz komunikacje

		TWI();	



while(1)
{
	if(pid_timer==1)
	{

		TWI();				//zakoncz komunikacje



		_delay_ms(100);
		uart_puts("Odchylenie(x) wynosi: ");
		uart_putint_2(temp, 10);

		pid_timer=0;



	}

}



}

Za wszelką pomoc dziękuje 🙂

Link do komentarza
Share on other sites

Nie mam przy sobie mojego kodu, ale o ile komunikacja działa to:

1. Po co piszesz coś do 0x27? to jest status register i z niego powinieneś tylko czytać.

2. Teoretycznie masz wszystko wyłączone, ale sprawdź co się będzie działo jak odczytasz wszystkie dane (oba bajty z X,Y i Z). Ten czujnik ma tryby uniemożliwiające odczytanie tylko cząstki wyniku i nie zrobią odświeżenia dopóki nie odczytasz wszystkiego... niby one są wyłączone, ale na wszelki wypadek warto spróbować.

3. Ja zawsze używałem ctrl_reg2 = 0.

Link do komentarza
Share on other sites

Pomysł niestety nie przynosi sukcesu. Próbuje odczytać samą temperaturę(która ma rejestr 8bitowy) i spokojnie powinno sie dac odczytać, a tu klosp 😃

Tutaj jest ten kod do odczytu kolejno wszystkiego

TWI();
Link do komentarza
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

Chyba mam problem, tylko nie potrafię go rozwiązać.

Wszystkiemu jest winne TWI, mogę odczytywać dane z żyroskopu, ale tylko raz, potem musze wyłączyć zasilanie i odczytuje nowe dane, w przeciwnym wypadku wszystko zostaje powtórzone.

206 -XL

254 -XH

158 -YL

1 -YH

121-ZL

255-ZH

tylko pytanie, co złego jest w konfiguracji, skoro ta biblioteka jest od wydawnictwa ATNEL. Muszę gdzieś robić błąd, tylko pytanie gdzie ?😃

Link do komentarza
Share on other sites

Niestety nie używałem tej biblioteki, ale w I2C zawsze ostatni bajt odczytywany w trybie Master Receiver powinien być NACK-owany. U Ciebie wszystkie czytane bajty - łącznie z ostatnim - mają ACK. Być może zaburza to jakoś pracę automatu sterującego pracą I2C w żyroskopie.

Link do komentarza
Share on other sites

Podaje całą inicjalizacje żyroskopu:

i2cSetBitrate(100);	//	ustawienie predkosci żyroskopu

uart_puts("1");
		TWI();	
uart_puts("2");
		TWI();
uart_puts("3");
		TWI();				//zakoncz komunikacje
uart_puts("4");
		TWI();				//zakoncz komunikacje
uart_puts("5");
		TWI();				//zakoncz komunikacje
	uart_puts("6");

while(1)
{
	if(pid_timer==1)
	{


		TWI();
		uart_putint_2(ZL, 10);
		USART_Transmit(0x00D);
     }

}

Te dane z Uartu to taki "JTAG" 🙂

Wyjście CS->VCC;

wyjście SDO-> VCC;

SCL,SDA ->4.7k pull-up;

GND->GND;

Link do komentarza
Share on other sites

Hm, oprócz tego, że zapisem do REG4 wymuszasz konieczność odczytu całego rejestru (bit BDU) oraz, że odwracasz ułożenie młodszych/starszych połówek (bit BLE) - obie rzeczy są dziwne w Twoim przypadku - to nie ma tu nic złego. No może poza mylącymi komentarzami, bo ostatni zapis do REG1 ustawia częstotliwość odświeżania na 100Hz i najwęższe pasmo 12.5Hz. Taka konfiguracja rejestrów XYZ nie pasuje do sposobu ich odczytu jaki zrobiłeś, bo czytając ZL czytasz naprawdę ZH, ale to nie powinno powodować braku nowych pomiarów. Czy możesz wstawić do pętli także odczyt rejestru WHO_AM_I, wypisać wszystkie wczytane wyniki oraz pokazać wyniki działania takiej pętli przy co najmniej dwukrotnym jej obróceniu (min. dwa komplety danych)?

Trochę też nie rozumiem funkcji programowania szybkości transmisji I2C. Jaki masz obecnie rzeczywisty zegar procesora (i jakie F_CPU)? Sprawdź co masz w TWBR oraz jaki jest stan bitów TWPS w rejestrze TWSR.

Czy Vcc procesora i całego I2C to 3V?

Biblioteka jest prymitywna aż żal ściska. Nie ma żadnej diagnostyki, żadnych reakcji na błędy. Nie ma wykrywania, że adresowanie SLAVE'a się nie powiodło, nie ma informacji, że wysłany bajt danych nie został potwierdzony itp. To daje złudne przekonanie, że wszystko na I2C działa, a w rzeczywistości może być coś bardzo źle na poziomie podstawowym.

Link do komentarza
Share on other sites

Po powrocie do domu wszystko wysle, dziekuje za zainteresowanie 🙂

[ Dodano: 03-03-2014, 14:57 ]

Rejestry TWI:

TWBR= 0x20;

TWPS=0;

TWPS=0;

Odczyt wartości rejestrów żyroskopu, które uprzednio konfiguruje:

		TWI();

		TWI();

Dla pewności odczytałem jeszcze inne rejestry, ale jak widać wszystko jest poprawnie

*CTRL_REG1 = 0x15 - czyli jak jak powinno być;

*CTRL_REG2= 0x00; - także jest OK;

*CTRL_REG3= 0x00 -ok

*CTRL_REG4= 0x00- tutaj popranie

*WHO_I_AM= 0xD3; <-- i tutaj OK

//EDIT:

Zrobiłem odczyt wszystkich osi ze sprawdzeniem rejestru statusu(0x27):

i tutaj widać, że powarzenie odczytu jest spowodowany brakiem gotowości odczytu danych XYZ (4bit rejestru STATUS_REGISTER)

Może to przez źle dobraną prędkość transmisji danych ?

ramka ma postać:

XL

XH

YL

YH

ZL

ZH

STATUS_REGISTER

219

251

24

252

6

246

255

218

254

196

1

127

255

255

218

254

196

1

127

255

0

218

254

196

1

127

255

0

Link do komentarza
Share on other sites

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...

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.