STM32F4-I2C-L3G4200D gyro örnek uygulama

Başlatan bilal0052, 19 Temmuz 2013, 16:54:04

bilal0052

kodları CoIDE ile yazıp derledim gayet güzel çalışıyor  aynı kodlar keilde de derlenebilir. programın derlenebilmesi için STnin kütüphanelerini projeye ekelemeniz gerekiyo.

i2c haberleşme protolünü kullanan bütün sensörleri aynı mantıkla kullanabilirsiniz. yakın  zamanda ADXL345 i de kullanıp bir IMU yapmayı düşünüyorum :)



#include "stdio.h"
#include "stm32f4xx.h"
#include "stm32f4xx_i2c.h"

#define CTRL_REG1                       0x20
#define CTRL_REG2                       0x21
#define CTRL_REG3                       0x22
#define CTRL_REG4                       0x23
#define CTRL_REG5                       0x24
#define STATUS_REG                      0x27
#define OUT_X_L                         0x28
#define OUT_X_H                         0x29
#define OUT_Y_L                         0x2A
#define OUT_Y_H                         0x2B
#define OUT_Z_L                         0x2C
#define OUT_Z_H                         0x2D
#define L3G4200D_ADDR                   (105<<1)

uint8_t i2cdata,a1,a2;
int16_t gyroX, gyroY, gyroZ;

uint8_t I2C_write(uint8_t devAddr, uint8_t regAddr, uint8_t val);
uint8_t I2C_readreg(uint8_t devAddr, uint8_t regAddr);

void init_I2C1(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	I2C_InitTypeDef I2C_InitStruct;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

	RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
	RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOB, &GPIO_InitStruct);

	GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);	// SCL pini 
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1); // SDA pini

	I2C_InitStruct.I2C_ClockSpeed = 100000;    //i2c hızı normal modda                
	I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
	I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
	I2C_InitStruct.I2C_OwnAddress1 = 0x00;
	I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
	I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	I2C_Init(I2C1, &I2C_InitStruct);

	I2C_Cmd(I2C1, ENABLE);
}


uint8_t I2C_write(uint8_t devAddr, uint8_t regAddr, uint8_t val)
{
        while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY ));

        I2C_GenerateSTART(I2C1, ENABLE);

        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT ));

        I2C_Send7bitAddress(I2C1, devAddr, I2C_Direction_Transmitter );

        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ));

        I2C_SendData(I2C1, regAddr);

        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING ));

        I2C_SendData(I2C1, val);

        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING ));

        I2C_GenerateSTOP(I2C1, ENABLE);
}

uint8_t I2C_readreg(uint8_t devAddr, uint8_t regAddr)
{
        uint8_t reg;
        while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY ));

        I2C_GenerateSTART(I2C1, ENABLE);

        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT ));

        I2C_Send7bitAddress(I2C1, devAddr, I2C_Direction_Transmitter );

        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ));

        I2C_SendData(I2C1, regAddr);

        while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF ) == RESET);

        I2C_GenerateSTOP(I2C1, ENABLE);

        I2C_GenerateSTART(I2C1, ENABLE);

        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT ));

        I2C_Send7bitAddress(I2C1, devAddr, I2C_Direction_Receiver );

        while (I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR ) == RESET);

	I2C_AcknowledgeConfig(I2C1, DISABLE);

	while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED ));

	reg = I2C_ReceiveData(I2C1);

        I2C_GenerateSTOP(I2C1, ENABLE);

        return reg;
}

void sensor_ayarla()
{
	I2C_write(L3G4200D_ADDR, CTRL_REG1, 0x0F); // X,Y,Z eksenlerini aktif et ve 100Hz data çıkış frekansı 
	I2C_write(L3G4200D_ADDR, CTRL_REG2, 0x00); 
	I2C_write(L3G4200D_ADDR, CTRL_REG3, 0x08); //eğer istenilirse sensörün int2 (data hazır) interuptı kullanılabilir
	I2C_write(L3G4200D_ADDR, CTRL_REG4, 0x30); //çıkış değeri  2000d/s olacak şekilde ayarla
	I2C_write(L3G4200D_ADDR, CTRL_REG5, 0x00);
}

int main(void)
{

	SystemInit();
	init_I2C1();
	sensor_ayarla();

	while (1){

	if((I2C_readreg(L3G4200D_ADDR,STATUS_REG)&0x08)==0x08) // eğer yeni data kullanılmaya hazırsa dataları oku
	{
		a1=I2C_readreg(L3G4200D_ADDR,OUT_X_L);
		a2=I2C_readreg(L3G4200D_ADDR,OUT_X_H);
		gyroX=((a2<<8) | a1);

		a1=I2C_readreg(L3G4200D_ADDR,OUT_Y_L);
		a2=I2C_readreg(L3G4200D_ADDR,OUT_Y_H);
		gyroY=((a2<<8) | a1);

		a1=I2C_readreg(L3G4200D_ADDR,OUT_Z_L);
		a2=I2C_readreg(L3G4200D_ADDR,OUT_Z_H);
		gyroZ=((a2<<8) | a1);
	}
	}
}