GY-273 HMC5883L电子指南针罗盘模块 三轴磁场传感器 avr 获取 三维位置

#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]);
 
效果如下
 
 
 


 

你可能感兴趣的:(单片机,c)