金牌会员
- 积分
- 1488
- 威望
- 751
- 贡献
- 411
- 兑换币
- 442
- 注册时间
- 2015-1-27
- 在线时间
- 163 小时
- 毕业学校
- 陕西科技大学
|
#include "hidef.h"
#include "IIC_L3G4200D.h"
#include "MC9S12XS128.h"
#include "SCI_Output.h"
#include "AngDeal.h"
int dis_datay,dis_dataz;
int IIC_Receive[6];
uchar IIC_ERROR; /*应答标志位*/
/***************************************************
IIC通信
注意 !总线频率为80MHZ,如需应用与不同频率,请
更改延时函数,增减至合适的NOP数量。器件地址为SDO接高的地址
SDO默认为高。
****************************************************/
void IIC_Init()
{
DDRJ=0xff;
}
void Delay1us(int c)
{
int cnt;
for(cnt=0;cnt<c;cnt++)
{
_asm NOP;_asm NOP;_asm NOP;
_asm NOP;_asm NOP;_asm NOP;
_asm NOP;_asm NOP;_asm NOP;
_asm NOP;_asm NOP;_asm NOP;
_asm NOP;_asm NOP;
_asm NOP;_asm NOP;_asm NOP;
_asm NOP;_asm NOP;_asm NOP;
}
}
void IIC_START()
{
SDA=1; /*发送起始条件的数据信号*/
Delay1us(1);
SCL=1;
Delay1us(5); /*起始条件建立时间大于4.7us,延时*/
SDA=0; /*发送起始信号*/
Delay1us(5); /* 起始条件锁定时间大于4μs*/
SCL=0; /*钳住IIC总线,准备发送或接收数据 */
Delay1us(2);
}
void IIC_STOP()
{
SDA=0; /*发送结束条件的数据信号*/
Delay1us(1); /*发送结束条件的时钟信号*/
SCL=1; /*结束条件建立时间大于4us*/
Delay1us(5);
SDA=1; /*发送IIC总线结束信号*/
Delay1us(4);
}
void IIC_Send_ack(uchar A)
{
SDA=A;
Delay1us(1);
SCL=1;
Delay1us(5);
SCL=0;
Delay1us(2);
}
void IIC_Check_ack()
{
Delay1us(3);
SCL=0;
Delay1us(3);
DDRJ_DDRJ6=0;
SDA=1;
Delay1us(3);
SCL=1;
Delay1us(5);
if(SDA==1)
IIC_ERROR=1;
else
IIC_ERROR=0;
SCL=0;
Delay1us(3);
DDRJ_DDRJ6=1;
}
//**************通过IIC总线发送1字节数据***************//
void IIC_Send1byte(uchar data)
{
uint i=8;
uchar m=data;
uchar temp;
for(i=8;i>0;i--)
{
temp=m&0x80;
if(temp==0x80)
SDA=1;
else
SDA=0;
Delay1us(5);
SCL=1;
Delay1us(5);
SCL=0;
m=m<<1;
}
}
//***************通过IIC总线接受1字节数据******************//
uchar IIC_Receive1byte()
{
int i=8;
uchar j=0;
DDRJ_DDRJ6=0;
SDA=1;
for(i=8;i>0;i--)
{
SDA=1;
Delay1us(3);
SCL=1;
Delay1us(5);
if(SDA==1)
j=j|0x01;
else j=j;
SCL=0;
if(i!=1)
{
j=j<<1;
}
}
DDRJ_DDRJ6=1;
return j;
}
// *****通过IIC总线向某一寄存器写入一个字节数据********
void IIC_write(uchar add,uchar mem,uchar data) // 写数据(器件地址,寄存器地址,数据)
{
IIC_START();
IIC_Send1byte(add);
IIC_Check_ack();
IIC_Send1byte(mem);
IIC_Check_ack();
IIC_Send1byte(data);
IIC_Check_ack();
IIC_STOP();
}
//***************L3G4200D读取*******************//
void L3G4200D_Init()
{
IIC_write(READ,0X20, 0x8F);
IIC_write(READ,0X21, 0x00);
IIC_write(READ,0X22, 0x08);
IIC_write(READ,0X23, 0x36 );
IIC_write(READ,0X24, 0x00);
}
int IIC_Read(uchar add,uchar mem) // 读数据(器件地址,寄存器地址)
{
int data;
IIC_START();
IIC_Send1byte(add);
IIC_Check_ack();
IIC_Send1byte(mem);
IIC_Check_ack();
IIC_START();
IIC_Send1byte(add+1);
IIC_Check_ack();
data=IIC_Receive1byte();
IIC_Send_ack(1);
IIC_STOP();
return data;
}
/***************读取结果传送值虚拟示波器,如不需要可删去**********************
注:
采集到的值为16位数,并且要经过数据合成才可以使用。经实验,选择初始自检后波形很棒,没有毛刺
但是同样的初始后不在零位了。所以经过修正使得Y和Z初始都在零位。
数据是int型,因为有两个方向∶使用的Z轴和Y轴。其中,俯仰使用Z轴,偏航使用Y轴。没有用X轴的原因
是因为实验发现X轴即使加了初始自检,依然有较明显毛刺。原因不祥
**************************************************************************/
void GET_AngleSpeed(void)
{
IIC_Receive[2]=IIC_Read(READ,0X2A); // Y
IIC_Receive[3]=IIC_Read(READ,0X2B); //数据合成
dis_datay=(IIC_Receive[3]<<8)+IIC_Receive[2]+6500; //因为经过了自检,初始后波形更好,但是不在0位
//需要加修正值,Z轴同理
// IIC_Receive[4]=IIC_Read(READ,0X2C); // Z
// IIC_Receive[5]=IIC_Read(READ,0X2D); //
// dis_dataz=(IIC_Receive[5]<<8)+IIC_Receive[4]-7320; //
} |
|