/*这是我用商家的51程序改过来的,反复比较,找不出问题查资料查资料所在,硬件仿真的结果是器件地址为209,其他加速度,角速度都是65535,求指教呀,调了几天了。谢谢*/
#include "delay.h"
#include "sys.h"
#include "usart.h"
#define uchar unsigned char
#define uint unsigned int
#define ushort unsigned short
#define SDA_IN() {GPIOC->CRL&=0XFFFFF0FF;GPIOC->CRL|=8<<8;}
#define SDA_OUT() {GPIOC->CRL&=0XFFFFF0FF;GPIOC->CRL|=3<<8;}
#define SCL PCout(3) //SCL
#define SDA PCout(2) //SDA
#define READ_SDA PCin(2) //输入SDA
uchar dis[4]; //显示数字(-511至512)的字符数组
int dis_data; //变量
uchar CY=0;
#define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz)
#define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz)
#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
#define  WR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用)
#define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读)
#define SlaveAddress 0xD0 //IIC写入时的地址字节数据,+1为读取
void IIC_Init(void) ;
void InitMPU6050(void); //初始化MPU6050
void I2C_Start(void);
void I2C_Stop(void);
void I2C_SendACK(u8 ack);
u8 I2C_RecvACK(void);
void I2C_SendByte(uchar dat);
uchar I2C_RecvByte(void);
void I2C_ReadPage(void);
void I2C_WritePage(void);
void display_ACCEL_x(void);
void display_ACCEL_y(void);
void display_ACCEL_z(void);
uchar Single_ReadI2C(uchar REG_Address); //读取I2C数据
void Single_WriteI2C(uchar REG_Address,uchar REG_data); //向I2C写入数据
int GetData(uchar REG_Address);
void IIC_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_2|GPIO_Pin_3); //PE.5 输出高
SCL=1;
SDA=1;
}
u16 t[6];
u16 s;
int main(void)
{
delay_init(); //延时函数初始化
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为9600
JTAG_Set(0x01); //
LCD_Init();
IIC_Init();
InitMPU6050(); //初始化MPU6050
while(1)
{
s= Single_ReadI2C( WHO_AM_I);
delay_ms(200);
delay_ms(100);
t[0]= GetData(ACCEL_XOUT_H); //显示X轴加速度
t[1]=GetData(ACCEL_YOUT_H); //显示Y轴加速度
t[2] =GetData(ACCEL_ZOUT_H); //显示Z轴加速度
t[3]=GetData(GYRO_XOUT_H) ; //显示X轴角速度
t[4]=GetData(GYRO_YOUT_H) ; //显示Y轴角速度
t[5]=GetData(GYRO_ZOUT_H); //显示Z轴角速度
delay_ms(100);
}
}
void I2C_Start()
{
SDA = 1; //拉高数据线
SCL = 1; //拉高时钟线
delay_us(5); //延时
SDA = 0; //产生下降沿
delay_us(5); //延时
SCL = 0; //拉低时钟线
}
//**************************************
//I2C停止信号
//**************************************
void I2C_Stop()
{
SDA = 0; //拉低数据线
SCL = 1; //拉高时钟线
delay_us(5); //延时
SDA = 1; //产生上升沿
delay_us(5); //延时
}
//**************************************
//I2C发送应答信号
//入口参数:ack (0:ACK 1:NAK)
//**************************************
void I2C_SendACK(u8 ack)
{
SDA = ack; //写应答信号
SCL = 1; //拉高时钟线
delay_us(5); //延时
SCL = 0; //拉低时钟线
delay_us(5); //延时
}
//**************************************
//I2C接收应答信号
//**************************************
u8 I2C_RecvACK()
{
SDA_IN();
SCL = 1; //拉高时钟线
delay_us(5); //延时
CY = READ_SDA; //读应答信号
SCL = 0; //拉低时钟线
delay_us(5); //延时
SDA_OUT();
return CY;
}
//**************************************
//向I2C总线发送一个字节数据
//**************************************
void I2C_SendByte(uchar dat)
{
uchar i;
for (i=0; i<8; i++) //8位计数器
{
SDA=(dat&0x80)>>7;
dat <<= 1; //移出数据的最高位
// SDA = CY; //送数据口
SCL = 1; //拉高时钟线
delay_us(5); //延时
SCL = 0; //拉低时钟线
delay_us(5); //延时
}
I2C_RecvACK();
}
//**************************************
//从I2C总线接收一个字节数据
//**************************************
uchar I2C_RecvByte()
{
uchar i;
uchar dat = 0;
SDA = 1; //使能内部上拉,准备读取数据,
SDA_IN();
for (i=0; i<8; i++) //8位计数器
{
dat <<= 1;
SCL = 1; //拉高时钟线
delay_us(5); //延时
dat |= READ_SDA; //读数据
SCL = 0; //拉低时钟线
delay_us(5); //延时
}
SDA_OUT();
return dat;
}
//**************************************
//向I2C设备写入一个字节数据
//**************************************
void Single_WriteI2C(uchar REG_Address,uchar REG_data)
{
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress); //发送设备地址+写信号
I2C_SendByte(REG_Address); //内部寄存器地址,
I2C_SendByte(REG_data); //内部寄存器数据,
I2C_Stop(); //发送停止信号
}
//**************************************
//从I2C设备读取一个字节数据
//**************************************
uchar Single_ReadI2C(uchar REG_Address)
{
uchar REG_data;
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress); //发送设备地址+写信号
I2C_SendByte(REG_Address); //发送存储单元地址,从0开始
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号
REG_data=I2C_RecvByte(); //读出寄存器数据
I2C_SendACK(1); //接收应答信号
I2C_Stop(); //停止信号
return REG_data;
}
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050()
{
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(uchar REG_Address)
{
char H,L;
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);
return (H<<8)+L; //合成数据
} |