#define SDA_1 PORTC|= (1<<2)
#define SDA_0 PORTC&=~(1<<2)
#define SCL_1 PORTC|= (1<<1)
#define SCL_0 PORTC&=~(1<<1)
void I2C_Init(void)
{
DDRC|=1<<1;
DDRC|=1<<2;
SCL_1;
delay_us(20);
SDA_1;
delay_us(20);
}
void I2C_Start(void)//起始信号
{
DDRC|=1<<1; //PC1 SCL时钟打开
DDRC|=1<<2; //PC2 SDA时钟打开
SDA_1;//SDA=1;
SCL_1;//SCL=1;
delay_us(20);
SDA_0;//SDA=0
delay_us(20);
SCL_0;//SCL=0
}
void I2C_Stop(void)//停止信号
{
DDRC|=1<<1; //PC1 SCL时钟打开
DDRC|=1<<2; //PC2 SDA时钟打开
SDA_0;//SDA=0
SCL_1;//SCL=1
delay_us(20);
SDA_1;//SDA=1
delay_us(20);
}
void I2C_SendACK(void)
{
DDRC|=1<<1; //PC1 SCL时钟打开
DDRC|=1<<2; //PC2 SDA时钟打开
SDA_1; //写应答信号
SCL_1; //拉高时钟线
delay_us(20); //延时
SCL_0; //拉低时钟线
delay_us(20);
}
u8 I2C_RecvACK(void)
{
u8 ack=0;
DDRC|=1<<1; //PC1 SCL时钟打开
DDRC&=~(1<<2); //PC2 SDA时钟打开
SCL_1; //拉高时钟线
delay_us(20);
if(PINC&(1<<2))
ack=1; //读应答信号
else ack=0;
SCL_0; //拉低时钟线
delay_us(20);
return ack;
}
void I2C_SendByte(u8 data)
{
u8 i;
DDRC|=1<<1; //PC1 SCL时钟打开
DDRC|=1<<2; //PC2 SDA时钟打开
for (i=0;i<8;i++) //8位计数器
{
data=data<<1; //移出数据的最高位
if((data&0x80)>>7==1)
SDA_1; //送数据口
else SDA_0;
SCL_1; //拉高时钟线
delay_us(20);
SCL_0; //拉低时钟线
delay_us(20);
}
I2C_RecvACK();
}
u8 I2C_RecvByte(void)
{
u8 i;
u8 data = 0;
DDRC|=1<<1; //PC1 SCL时钟打开
DDRC&=~(1<<2); //PC2 SDA时钟打开
SDA_1; //使能内部上拉,准备读取数据
for(i=0; i<8; i++) //8位计数器
{
data=data<<1;
SCL_1; //拉高时钟线
delay_us(20); //延时
if(PINC&(1<<2)) //读数据
data|=0x01;
else data|=0x00;
SCL_0; //拉低时钟线
delay_us(20); //延时
}
return data;
}
//向I2C设备写入一个字节数据
void Single_WriteI2C(u8 REG_Address,u8 REG_data)
{
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress); //发送设备地址+写信号
I2C_SendByte(REG_Address); //内部寄存器地址,
I2C_SendByte(REG_data); //内部寄存器数据,
I2C_Stop(); //发送停止信号
}
//从I2C设备读取一个字节数据
u8 Single_ReadI2C(u8 REG_Address)
{
u8 REG_data;
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress); //发送设备地址+写信号
I2C_SendByte(REG_Address); //发送存储单元地址,从0开始
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号
REG_data=I2C_RecvByte(); //读出寄存器数据
I2C_SendACK(); //接收应答信号
I2C_Stop(); //停止信号
return REG_data;
}
//初始化MPU6050
void InitMPU6050(void)
{
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态
Single_WriteI2C(SMPLRT_DIV, 0x07);
Single_WriteI2C(CONFIG, 0x06);
Single_WriteI2C(GYRO_CONFIG, 0x18);
Single_WriteI2C(ACCEL_CONFIG, 0x01);
}
//合成数据
int GetData(u8 REG_Address)
{
char H,L;
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);
return (H<<8)+L; //合成数据
}
void main(void)
{
u16 temp=0x0000;
uart0_init();
I2C_Init();
InitMPU6050(); //初始化MPU6050
delay_us(200);
while(1)
{
temp=GetData(GYRO_XOUT_H); //显示X轴角速度
//temp=GetData(WHO_AM_I); //
USART_Transmit0((u8)temp&0xff00);
USART_Transmit0((u8)temp&0x00ff);
//USART_Transmit0(0xFF);
delay_ms(400);
}
}
|