[mw_shl_code=c,true]/*main.c*/
#include"I2C2init.h"
#include"delay.h"
#include"sys.h"
#include"usart.h"
#include"mpu6050.h"
#include"usmart.h"
#define uchar unsigned char
#define uint unsigned int
u8 sum_1,sum_2,sum_3,sum_4,sum_5;
u8 Add;
uchar BUF[10];
u32 T_X,T_Y,T_Z;
float T_TEMP;
u32 Gyro_Config,Gyro_Config_7,Gyro_Config_6,Gyro_Config_5;
u32 READ(u8 flag_1,u8 flag_2,u32 Addr_L,u32 Addr_H)
{
u32 data;
BUF[flag_1]=Single_ReadI2C(Addr_L);
BUF[flag_2]=Single_ReadI2C(Addr_H);
data=(BUF[flag_2]<<8)|BUF[flag_1];
data/=16.4;
return data;
}
void READ_MPU6050()
{
T_X=READ(0,1,ACCEL_XOUT_L,ACCEL_XOUT_H);
Gyro_Config=Single_ReadI2C(GYRO_CONFIG);
Gyro_Config_7=Gyro_Config>>7;
Gyro_Config_6=Gyro_Config>>6;
Gyro_Config_5=Gyro_Config>>5;
}
void Read_MPU6050(void)
{
// BUF[0]=Single_ReadI2C(ACCEL_XOUT_L);
// BUF[1]=Single_ReadI2C(ACCEL_XOUT_H);
// T_X=(BUF[1]<<8)|BUF[0];
// T_X/=16.4;
BUF[2]=Single_ReadI2C(ACCEL_YOUT_L);
BUF[3]=Single_ReadI2C(ACCEL_YOUT_H);
T_Y=(BUF[3]<<8)|BUF[2];
T_Y/=16.4;
BUF[4]=Single_ReadI2C(ACCEL_ZOUT_L);
BUF[5]=Single_ReadI2C(ACCEL_ZOUT_H);
T_Z=(BUF[5]<<8)|BUF[4];
T_Z/=16.4;
BUF[6]=Single_ReadI2C(TEMP_OUT_L);
BUF[7]=Single_ReadI2C(TEMP_OUT_H);
T_TEMP=(BUF[7]<<8)|BUF[6];
T_TEMP=T_TEMP/340+36.53;
}
int main()
{
Stm32_Clock_Init(9);
delay_init(72);
uart_init(72,9600);
printf("\r\n");
printf("\r\n");
printf("\r\n");
I2C2_Init();
InitMPU6050();
delay_ms(100);
usmart_dev.init(72);
while(1)
{
Add=Single_ReadI2C(WHO_AM_I);
printf("%d\r\n",Add);
sum_1=Single_ReadI2C(GYRO_CONFIG);
sum_2=Single_ReadI2C(PWR_MGMT_1);
Read_MPU6050();
printf("%d\r\n",sum_1);
printf("%d\r\n",sum_2);
printf("x=%d\r\n",T_X);
printf("y=%d\r\n",T_Y);
printf("z=%d\r\n",T_Z);
printf("T_tempert=%lf\r\n",T_TEMP); //显示温度
printf("%d\r\n",Gyro_Config_7);
printf("%d\r\n",Gyro_Config_6);
printf("%d\r\n\n\n",Gyro_Config_5);
delay_ms(1800);
delay_ms(1800);
}
}
/*I2Cinit.c*/
#include"I2C2init.h"
#include"sys.h"
#include"usart.h"
#include"delay.h"
#include"math.h"
void I2C2_Init()
{
RCC->APB2ENR|=1<<3; //GPIOB时钟使能
GPIOB->CRH&=0xffff00ff;
GPIOB->CRH|=0x00003300; //PB10,PB11设置为复用开漏输出
GPIOB->ODR|=1<<11;
}
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
SDA=1;
SCL=1;
delay_us(5);
SDA=0; //START:when CLK is high,DATA change form high to low
delay_us(5);
SCL=0; //钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT(); //sda线输出
SCL=0;
SDA=0;
delay_us(5);
SCL=1; //STOP:when CLK is high DATA change form low to high
SDA=1; //发送I2C总线结束信号
delay_us(5);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
SDA=1;delay_us(1);
SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
SCL=0; //时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
SCL=0;
SDA_OUT();
SDA=0;
delay_us(2);
SCL=1;
delay_us(2);
SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{
SCL=0;
SDA_OUT();
SDA=1;
delay_us(2);
SCL=1;
delay_us(2);
SCL=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
SCL=0; //拉低时钟开始数据传输
for(t=0;t<8;t++)
{
SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
SCL=1;
delay_us(2);
SCL=0;
delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN(); //SDA设置为输入
for(i=0;i<8;i++ )
{
SCL=0;
delay_us(2);
SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck(); //发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
/*I2Cinit.h*/
#ifndef I2C2_H
#define I2C2_H
#include"sys.h"
#define SCL PBout(10)
#define SDA PBout(11)
#define READ_SDA PBin(11)
#define SDA_IN() {GPIOB->CRH&=0xffff0fff;GPIOB->CRH|=0x00008000;/*GPIOB->ODR|=1<<11;*/}
#define SDA_OUT() {GPIOB->CRH&=0xffff0fff;GPIOB->CRH|=0x00003000;}
void I2C2_Init(void);
void IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void); //发送IIC停止信号
void IIC_Send_Byte(u8 txd); //IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack); //IIC读取一个字节
u8 IIC_Wait_Ack(void); //IIC等待ACK信号
void IIC_Ack(void); //IIC发送ACK信号
void IIC_NAck(void); //IIC不发送ACK信号
#endif
/*mpu6050.c*/
#include"I2C2init.h"
#include"sys.h"
#include"delay.h"
#include"usart.h"
#include"math.h"
#include"mpu6050.h"
#define uchar unsigned char
#define uint unsigned int
//extern uchar BUF[10];
//extern uchar T_X;
/***************************************************************************
*******************************************************************************/
void Single_WriteI2C(u8 REG_Address,u8 REG_data)
{
IIC_Start(); //起始信号
IIC_Send_Byte(SlaveAddress); //发送设备地址+写信号
while(IIC_Wait_Ack());
IIC_Send_Byte(REG_Address); //内部寄存器地址
while(IIC_Wait_Ack());
/**********************/
IIC_Send_Byte(REG_data); //内部寄存器数据
IIC_Wait_Ack(); /**********************/
IIC_Stop(); //发送停止信号
}
//**************************************
//从I2C设备读取一个字节数据
//**************************************
u8 Single_ReadI2C(u8 REG_Address)
{
u8 REG_data;
IIC_Start();
IIC_Send_Byte(SlaveAddress);
while(IIC_Wait_Ack());
IIC_Send_Byte(REG_Address);
IIC_Wait_Ack(); /**********************/
IIC_Start();
IIC_Send_Byte(SlaveAddress+1);
while(IIC_Wait_Ack());
REG_data=IIC_Read_Byte(0);
// IIC_NAck();
delay_us(2);
IIC_Stop();
return REG_data;
}
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050(void)
{
Single_WriteI2C(PWR_MGMT_1,0x00); //解除休眠状态
Single_WriteI2C(GYRO_CONFIG,0x18); //陀螺仪不自检,配置陀螺仪满量程正负2000°/S
Single_WriteI2C(ACCEL_CONFIG,0x01);//加速度计不自检,配置加速度计满量程2g
Single_WriteI2C(SMPLRT_DIV,0x07); //采样频率分频器
Single_WriteI2C(CONFIG,0x06); //低通滤波频率
}
//**************************************
//合成数据
//**************************************
//int GetData(u8 REG_Address)
//{
// char H,L;
// H=Single_ReadI2C(REG_Address);
// L=Single_ReadI2C(REG_Address+1);
// return (H<<8)+L; //合成数据
//}
//void Read_MPU6050(void)
//{
// BUF[0]=Single_ReadI2C(ACCEL_XOUT_L);
// BUF[1]=Single_ReadI2C(ACCEL_XOUT_H);
// T_X=(BUF[1]<<8)|BUF[0];
// T_X/=16.4;
//}
void MPU60x0_Init(void)
{
Single_WriteI2C(GYRO_CONFIG,0xf0); //陀螺仪自检
}
/*mpu6050.h*/
#ifndef Mpu6050_H
#define Mpu6050_H
//****************************************
// 定义MPU6050内部地址
//****************************************
#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 SELF_TEST_X 0x0d
#define SELF_TEST_Y 0x0e
#define SELF_TEST_Z 0x0f
#define SELF_TEST_A 0x10
#define MOTION_DETECTION_THRESHOLD 0xef
#define FIFO_ENABLE 0x23 //FIFO使能
#define I2C_MST_CTRL 0x24
#define I2C_SLV0_ADDR 0x25
#define I2C_SLV0_REG 0x26
#define I2C_SLV0_CTRL 0x27
#define I2C_SLV1_ADDR 0x28
#define I2C_SLV1_REG 0x29
#define I2C_SLV1_CTRL 0x2a
#define I2C_SLV2_ADDR 0x2b
#define I2C_SLV2_REG 0x2c
#define I2C_SLV2_CTRL 0x2d
#define I2C_SLV3_ADDR 0x2e
#define I2C_SLV3_REG 0x2f
#define I2C_SLV3_CTRL 0x30
#define I2C_SLV4_ADDR 0x31
#define I2C_SLV4_REG 0x32
#define I2C_SLV4_DO 0x33
#define I2C_SLV4_CTRL 0x34
#define I2C_SLV4_DI 0x35
#define I2C_MST_STATUS 0x36
#define INT_PIN_CFG 0x37
#define INT_ENABLE 0x38 //中断使能
#define INT_STATUS 0x3A //中断过状态
#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 EXT_SENS_DATA_00 0x49
#define EXT_SENS_DATA_01 0x4A
#define EXT_SENS_DATA_02 0x4B
#define EXT_SENS_DATA_03 0x4C
#define EXT_SENS_DATA_04 0x4D
#define EXT_SENS_DATA_05 0x4E
#define EXT_SENS_DATA_06 0x4F
#define EXT_SENS_DATA_07 0x50
#define EXT_SENS_DATA_08 0x51
#define EXT_SENS_DATA_09 0x52
#define EXT_SENS_DATA_10 0x53
#define EXT_SENS_DATA_11 0x54
#define EXT_SENS_DATA_12 0x55
#define EXT_SENS_DATA_13 0x56
#define EXT_SENS_DATA_14 0x57
#define EXT_SENS_DATA_15 0x58
#define EXT_SENS_DATA_16 0x59
#define EXT_SENS_DATA_17 0x5A
#define EXT_SENS_DATA_18 0x5B
#define EXT_SENS_DATA_19 0x5C
#define EXT_SENS_DATA_20 0x5D
#define EXT_SENS_DATA_21 0x5E
#define EXT_SENS_DATA_22 0x5F
#define EXT_SENS_DATA_23 0x60
#define I2C_SLV0_DO 0x63
#define I2C_SLV1_DO 0x64
#define I2C_SLV2_DO 0x65
#define I2C_SLV3_DO 0x66
#define I2C_MST_DELAY_CTRL 0x67
#define SIGNAL_PATH_RESET 0x68
#define MOT_DETECT_CTRL 0x69
#define USER_CTRL 0x6A
#define PWR_MGMT_1 0x6B //电源管理,退出睡眠,默认是睡眠状态,典型值:0x00(正常启用)
#define PWR_MGMT_2 0x6C
#define FIFO_COUNT_H 0x72
#define FIFO_COUNT_L 0x73
#define FIFO_R_W 0x74
#define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读)
#define SlaveAddress 0xD0 //IIC写入时的地址字节数据,+1为读取
#include"sys.h"
int GetData(u8 REG_Address);
void InitMPU6050(void);
u8 Single_ReadI2C(u8 REG_Address);
void Single_WriteI2C(u8 REG_Address,u8 REG_data);
void Read_MPU6050(void);
void MPU60x0_Init(void);
#endif[/mw_shl_code]
[mw_shl_code=c,true]
[/mw_shl_code]
[mw_shl_code=c,true]用模拟的I2C读出了MPU6050的寄存器数据,供大家分享![/mw_shl_code]
[mw_shl_code=c,true]由于正在研究算法,对于仅读出数据的,有些语句没必要加,但是加了也不影响结果!
[/mw_shl_code]
|