Skocz do zawartości

Błędy odczytu w żyroskopie L3G4200D, GY80


paczkaexpres

Pomocna odpowiedź

Cześć,

Od paru dni zmagam się z uruchomieniem komponentów moduły GY-80. O ile odczyt z akcelerometru okazał się prostym zadaniem to mam ciągły problem z poprawnym odczytem danych z żyroskopu.

Problem objawia się przy próbie odczytu z rejestróe od 0x28 (który przechowuje dane LSB z osi x) do rejestru 0x2D (MSB rejestru danych z osi Z). Wygląda on w ten sposób, że otrzymuję 6 takich samych wartości. Na przykład przy pierwszym odczycie może to być 0x22, a już przy następnym 0xF4.

Pracuję na płytce Discovery Disco wyposażonego w procesor STM32F429. Moduł GY-80 jest podpięty do wejść A8 i C9.

Inicjalizacja I2C:

void init_I2C()
{

	GPIO_InitTypeDef GPIO_InitStructure;
	I2C_InitTypeDef I2C_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_I2C3);	// SCL

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_I2C3); // SDA

	// configure I2C3
	I2C_InitStructure.I2C_ClockSpeed = 100000; 		// 100kHz
	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;			// I2C mode
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;	// 50% duty cycle --> standard
	I2C_InitStructure.I2C_OwnAddress1 = 0x00;			// own address, not relevant in master mode
	I2C_InitStructure.I2C_Ack = I2C_Ack_Disable;		// disable acknowledge when reading (can be changed later on)
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses
	I2C_Init(I2C3, &I2C_InitStructure);				// init I2C3

	// enable I2C3
	I2C_Cmd(I2C3, ENABLE);
}

Inicjalizajca żyroskopu:

void init_Gyroscope()
{

I2C_write(GYROSCOPE_ADDRESS,GYROSCOPE_CTRL_REG1,0x0F); //Ustawiam Power normal mode, uruchamiam możliwosc odczytu danych z osi x,y,z
I2C_write(GYROSCOPE_ADDRESS,GYROSCOPE_CTRL_REG2,0x00); //Ustawianie High Pass filter mode i High Pass filter cut off
I2C_write(GYROSCOPE_ADDRESS,GYROSCOPE_CTRL_REG3,0x08); // odblokowanie sygnału gotowosci
I2C_write(GYROSCOPE_ADDRESS,GYROSCOPE_CTRL_REG4,0x80); // ustawienie skali na 250 deg / sec
}

Odczyt wartości z żyroskopu:

int16_t read_Angle_Velocity()
{
int16_t data;
int8_t i = 0;
int16_t LSB = 0;
int16_t MSB = 0;

data = I2C_read(GYROSCOPE_ADDRESS, ANGULAR_VELOSITY_XAXIS_LSB, 6);

for(i = 0;i<3;i++)
{
	LSB = I2C_Buff[2*i + 0];
	MSB = I2C_Buff[2*i + 1];

	data = LSB + (MSB<<8);
	I2C_Gyro[i] = gyroscope_Convert_ToAng(data);
}

return *I2C_Gyro;
}

Odczyt danych z I2C

uint8_t I2C_read(uint8_t address, uint8_t data,uint8_t Lenght)
{
uint8_t *a = &I2C_Buff;
I2C_start(I2C3, address<<1, I2C_Direction_Transmitter);
I2C_SendData(I2C3, data);
while(!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_start(I2C3, address<<1, I2C_Direction_Receiver);

for(Lenght;Lenght > 0;Lenght--)
{
	if(Lenght > 1)
	{
		I2C_AcknowledgeConfig(I2C3, ENABLE);
	}
	else
	{
		I2C_AcknowledgeConfig(I2C3, DISABLE);
		I2C_GenerateSTOP(I2C3, ENABLE);
	}

	while( !I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_BYTE_RECEIVED) ); 			// wait until one byte has been received
	*a = I2C_ReceiveData(I2C3);	// read data from I2C data register and return data byte
	a++;
}

return *I2C_Buff;
}

Jeszcze na koniec przebiegi z analizatora stanów logicznych:

Będę wdzięczny za sugestie co może być nie tak.

Link do komentarza
Share on other sites

Czy poniższy cytat z danych katalogowych żyroskopu L3G4200D siedzącego na płytce GY-80 jest odpowiedzią? Jest tu mowa o drugim bajcie, tzw sub-address nadawanym po I2C:

"The 7 LSB represent the actual register address while the MSB enables address auto-increment. If the MSB of the SUB field is 1, the SUB (register address) is automatically incremented to allow multiple data read/write."

  • Lubię! 1
Link do komentarza
Share on other sites

Marek1707 jesteś wielki!

Rzeczywiście problemem w moim odczycie było nieustawienie tego jednego bitu. Nigdy do tej pory nie spotkałem się z taką metodą ustawiania automatycznego odczytywania następnego rejestru, dlatego nie spodziewałem się, że to tutaj może leżeć problem. Do tego popełniłem błąd nowicjusza i nie zagłębiłem się w dokumentacji.

W każdym razie wielkie dzięki za pomoc.

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.