#ifndef _GY_273_H
#define _GY_273_H
#define I2C_SCL_PIN 5
#define I2C_SDA_PIN 1
#define I2CPORT PORTC
#define I2CDDR DDRC
#define I2CPIN PINC
#define I2C_SCL_SET I2CPORT|=BIT(I2C_SCL_PIN);
#define I2C_SCL_CLR I2CPORT&=~BIT(I2C_SCL_PIN);
#define I2C_SDA_SET I2CPORT|=BIT(I2C_SDA_PIN);
#define I2C_SDA_CLR I2CPORT&=~BIT(I2C_SDA_PIN);
#define I2C_SDA_DAT I2CPIN&BIT(I2C_SDA_PIN)
#define I2C_SDA_OUT I2CDDR|=BIT(I2C_SDA_PIN);
#define I2C_SDA_IN I2CDDR&=~BIT(I2C_SDA_PIN);
#define I2C_Drop {I2C_SDA_SET I2C_SCL_SET}
#define I2C_PIN_INIT I2CDDR|=BIT(I2C_SDA_PIN)|BIT(I2C_SCL_PIN);
#define START 0x08
#define RE_START 0x10
#define MT_SLA_ACK 0x18
#define MT_SLA_NOACK 0x20
#define MT_DATA_ACK 0x28
#define MT_DATA_NOACK 0x30
#define MR_SLA_ACK 0x40
#define MR_SLA_NOACK 0x48
#define MR_DATA_ACK 0x50
#define MR_DATA_NOACK 0x58
#define DEVICE_ADDR 0x1e
#define FilterSize 30 //滤波系数
void GY273_Init(void);
void GY273_Read(uint *Data);
void GY273_Filter(uint *Data,uint *Out);
void GY273_GetXYZ(uint *Data);
#endif
#include
void Delay(uint16 us)
{
while(us--);
}
/*------------------------------------------------------------------------------
Func: 启动I2C总线
------------------------------------------------------------------------------*/
void I2C_Start(void)
{
I2C_SCL_SET Delay(1); //在SCL的高电平期间SDA线产生一个下跳沿
I2C_SDA_SET Delay(1);
I2C_SDA_CLR Delay(1);
I2C_SCL_CLR Delay(1); //主机占有主动权
}
/*------------------------------------------------------------------------------
Func: 停止I2C总线控制
------------------------------------------------------------------------------*/
void I2C_Stop(void)
{
I2C_SDA_CLR Delay(2); //在SCL的高电期间SDA线产生一个上跳沿
I2C_SCL_SET Delay(1);
I2C_SDA_SET Delay(3);
}
/*------------------------------------------------------------------------------
Func: 发送ACK信号
------------------------------------------------------------------------------*/
void I2C_SendAck(uint8 Ack)
{
if(Ack)I2C_SDA_SET
else I2C_SDA_CLR //发送ACK信号
I2C_SCL_SET Delay(1);
I2C_SCL_CLR Delay(1);
I2C_SDA_SET
}
/*------------------------------------------------------------------------------
Func: 向I2C总线写数据
Time: 2010-7-20
Ver.: V1.0
Note:
------------------------------------------------------------------------------*/
uint8 I2C_SendBytes(uint8 *TxBuffer,uint8 TxLenth)
{
uint8 i,j,Ack,k=TxLenth;
while(TxLenth)
{
j=*TxBuffer++;
for(i=0;i<8;i++,j<<=1)
{
if(j&0x80)I2C_SDA_SET
else I2C_SDA_CLR
I2C_SCL_SET Delay(1);
I2C_SCL_CLR Delay(1);
}
I2C_SDA_SET
I2C_SCL_SET Delay(1);
I2C_SDA_IN; Delay(1);
Ack=I2C_SDA_DAT; Delay(1);
I2C_SDA_OUT; Delay(1);
I2C_SCL_CLR Delay(1);
if(Ack)return (k-TxLenth);
TxLenth--;
}
return k;
}
/*------------------------------------------------------------------------------
Func: 从I2C总线读数据
Time: 2010-7-20
Ver.: V1.0
Note:
------------------------------------------------------------------------------*/
uint8 I2C_RecvBytes(uint8 *RxBuffer,uint8 RxLenth)
{
uint8 i,j,k=RxLenth;
while(RxLenth--)
{
I2C_SDA_IN; Delay(10);
I2C_SDA_SET;
for(i=0,j=0;i<8;i++)
{
j<<=1;
I2C_SCL_SET Delay(1);
if(I2C_SDA_DAT)j|=0x01;
I2C_SCL_CLR Delay(1);
}
I2C_SDA_OUT;
*RxBuffer++=j;
if(RxLenth>0)I2C_SendAck(0);
else I2C_SendAck(1);
}
return k;
}
/*------------------------------------------------------------------------------
Func: 写I2C总线
Time: 2010-7-20
Ver.: V1.0
Note: return 0/无响应 1/发送正常
------------------------------------------------------------------------------*/
uint8 I2C_WriteDatas(uint8 Addr,uint8 *Cmd,uint8 CmdLen,uint8 *TxBuffer,uint8 TxLenth)
{
uint8 Ack;
Addr<<=1;
I2C_Start();
Ack=I2C_SendBytes(&Addr,1);
if(Ack==0){I2C_Drop return 0;}
Ack=I2C_SendBytes(Cmd,CmdLen);
Ack=I2C_SendBytes(TxBuffer,TxLenth);
I2C_Stop();
return Ack;
}
/*------------------------------------------------------------------------------
Func: 读I2C总线
Time: 2010-7-20
Ver.: V1.0
Note: return 0/无响应 1/正常
------------------------------------------------------------------------------*/
uint8 I2C_ReadDatas(uint8 Addr,uint8 *Cmd,uint8 CmdLen,uint8 *RxBuffer,uint8 RxLenth)
{
uint8 Ack=0;
Addr<<=1;
I2C_Start();
if(CmdLen>0){
Ack=I2C_SendBytes(&Addr,1);
if(Ack==0){I2C_Drop return 0;}
Ack=I2C_SendBytes(Cmd,CmdLen);
I2C_Start();
}
Addr|=0x01;
Ack=I2C_SendBytes(&Addr,1);
Ack=I2C_RecvBytes(RxBuffer,RxLenth);
I2C_Stop();
return Ack;
}
#include
#include
void GY273_Init()
{
I2C_PIN_INIT;
}
void GY273_Read(uint *Data)
{
uint8 i;
uint8 data[2];
uint8 reg[3]={0x78,0x00,0x00};
uint8 addr[1]={0x00};
I2C_WriteDatas(DEVICE_ADDR,&addr[0],1,®[0],3);
for(i=0;i<3;i++)
{
addr[0]=0x03+i*2;
I2C_ReadDatas(DEVICE_ADDR,&addr[0],1,&data[0],2);
Data[i]=data[0];
Data[i]<<=8;
Data[i]|=data[1];
}
}
void GY273_Filter(uint *Data,uint *Out)
{
static ulong Pool[3];
static uchar Index[3];
uchar i;
for(i=0;i<3;i++)
{
Out[i]=FlowPoolFilter(&Pool[i],Data[i],&Index[i],FilterSize);
}
}
void GY273_GetXYZ(uint *Data)
{
uint Buf[3];
GY273_Read(&Buf[0]);
GY273_Filter(&Buf[0],Data);
}
说明 初始化 GY273_Init();
读取 uint Buf[3]; GY273_GetXYZ(&Buf[0]);
显示 printf("X=%d,Y=%d,Z=%d",Buf[0],Buf[2],Buf[1]);
效果如下
