This commit is contained in:
MobKBK
2026-06-20 21:22:34 +08:00
commit 460e0e9e73
320 changed files with 135203 additions and 0 deletions

352
HARDWARE/MPU6050/I2C.c Normal file
View File

@@ -0,0 +1,352 @@
#include "I2C.h"
/**************************************************************************
Function: IIC pin initialization
Input : none
Output : none
函数功能IIC引脚初始化
入口参数:无
返回 值:无
**************************************************************************/
void I2C_GPIOInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
IIC_SCL=1;
IIC_SDA=1;
}
/**************************************************************************
Function: Simulate IIC start signal
Input : none
Output : none
函数功能模拟IIC起始信号
入口参数:无
返回 值:无
**************************************************************************/
void I2C_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
if(!READ_SDA)return ;
IIC_SCL=1;
delay_us(1);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
if(READ_SDA)return ;
delay_us(1);
IIC_SCL=0;//钳住I2C总线准备发送或接收数据
return ;
}
/**************************************************************************
Function: Analog IIC end signal
Input : none
Output : none
函数功能模拟IIC结束信号
入口参数:无
返回 值:无
**************************************************************************/
void I2C_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(1);
IIC_SCL=1;
IIC_SDA=1;//发送I2C总线结束信号
delay_us(1);
}
bool I2C_WaiteForAck(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;
delay_us(1);
IIC_SCL=1;
delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>50)
{
I2C_Stop();
return 0;
}
delay_us(1);
}
IIC_SCL=0;//时钟输出0
return 1;
}
/**************************************************************************
Function: IIC response
Input : none
Output : none
函数功能IIC应答
入口参数:无
返回 值:无
**************************************************************************/
void I2C_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(1);
IIC_SCL=1;
delay_us(1);
IIC_SCL=0;
}
/**************************************************************************
Function: IIC don't reply
Input : none
Output : none
函数功能IIC不应答
入口参数:无
返回 值:无
**************************************************************************/
void I2C_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(1);
IIC_SCL=1;
delay_us(1);
IIC_SCL=0;
}
bool I2C_WriteOneBit(uint8_t DevAddr, uint8_t RegAddr, uint8_t BitNum, uint8_t Data)
{
uint8_t Dat;
Dat =I2C_ReadOneByte(DevAddr, RegAddr);
Dat = (Data != 0) ? (Dat | (1 << BitNum)) : (Dat & ~(1 << BitNum));
I2C_WriteOneByte(DevAddr, RegAddr, Dat);
return true;
}
bool I2C_WriteBits(uint8_t DevAddr, uint8_t RegAddr, uint8_t BitStart, uint8_t Length, uint8_t Data)
{
uint8_t Dat, Mask;
Dat = I2C_ReadOneByte(DevAddr, RegAddr);
Mask = (0xFF << (BitStart + 1)) | 0xFF >> ((8 - BitStart) + Length - 1);
Data <<= (8 - Length);
Data >>= (7 - BitStart);
Dat &= Mask;
Dat |= Data;
I2C_WriteOneByte(DevAddr, RegAddr, Dat);
return true;
}
/**************************************************************************
Function: IIC sends a bit
Input : none
Output : none
函数功能IIC发送一个位
入口参数:无
返回 值:无
**************************************************************************/
void I2C_WriteByte(uint8_t Data)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(Data&0x80)>>7;
Data<<=1;
delay_us(1);
IIC_SCL=1;
delay_us(1);
IIC_SCL=0;
delay_us(1);
}
}
u8 I2C_WriteOneByte(uint8_t DevAddr, uint8_t RegAddr, uint8_t Data)
{
I2C_Start();
I2C_WriteByte(DevAddr | I2C_Direction_Transmitter);
I2C_WaiteForAck();
I2C_WriteByte(RegAddr);
I2C_WaiteForAck();
I2C_WriteByte(Data);
I2C_WaiteForAck();
I2C_Stop();
return 1;
}
bool I2C_WriteBuff(uint8_t DevAddr, uint8_t RegAddr, uint8_t Num, uint8_t *pBuff)
{
uint8_t i;
if(0 == Num || NULL == pBuff)
{
return false;
}
I2C_Start();
I2C_WriteByte(DevAddr | I2C_Direction_Transmitter);
I2C_WaiteForAck();
I2C_WriteByte(RegAddr);
I2C_WaiteForAck();
for(i = 0; i < Num; i ++)
{
I2C_WriteByte(*(pBuff + i));
I2C_WaiteForAck();
}
I2C_Stop();
return true;
}
/**************************************************************************
Function: IIC reads a bit
Input : none
Output : none
函数功能IIC读取一个位
入口参数:无
返回 值:无
**************************************************************************/
uint8_t I2C_ReadByte(uint8_t Ack)
{
uint8_t i, RecDat = 0;
SDA_IN();
for(i = 0; i < 8; i ++)
{
// I2C_SCL_Clr();
IIC_SCL=0;
delay_us(1);
// I2C_SCL_Set();
IIC_SCL=1;
RecDat <<= 1;
if(READ_SDA)
RecDat |= 0x01;
else
RecDat &= ~0x01;
delay_us(1);
}
if(I2C_ACK == Ack)
I2C_Ack();
else
I2C_NAck();
return RecDat;
}
uint8_t I2C_ReadOneByte(uint8_t DevAddr, uint8_t RegAddr)
{
uint8_t TempVal = 0;
I2C_Start();
I2C_WriteByte(DevAddr | I2C_Direction_Transmitter);
I2C_WaiteForAck();
I2C_WriteByte(RegAddr);
I2C_WaiteForAck();
I2C_Start();
I2C_WriteByte(DevAddr | I2C_Direction_Receiver);
I2C_WaiteForAck();
TempVal = I2C_ReadByte(I2C_NACK);
I2C_Stop();
return TempVal;
}
bool I2C_ReadBuff(uint8_t DevAddr, uint8_t RegAddr, uint8_t Num, uint8_t *pBuff)
{
uint8_t i;
if(0 == Num || NULL == pBuff)
{
return false;
}
I2C_Start();
I2C_WriteByte(DevAddr | I2C_Direction_Transmitter);
I2C_WaiteForAck();
I2C_WriteByte(RegAddr);
I2C_WaiteForAck();
I2C_Start();
I2C_WriteByte(DevAddr | I2C_Direction_Receiver);
I2C_WaiteForAck();
for(i = 0; i < Num; i ++)
{
if((Num - 1) == i)
{
*(pBuff + i) = I2C_ReadByte(I2C_NACK);
}
else
{
*(pBuff + i) = I2C_ReadByte(I2C_ACK);
}
}
I2C_Stop();
return true;
}
///**************************************************************************
//Function: IIC continuous reading data
//Input : devTarget device IIC addressreg:Register address
// lengthNumber of bytes*data:The pointer where the read data will be stored
//Output : countNumber of bytes read out-1
//函数功能IIC连续读数据
//入口参数dev目标设备IIC地址reg:寄存器地址length字节数
// *data:读出的数据将要存放的指针
//返回 值count读出来的字节数量-1
//**************************************************************************/
//u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data){
// u8 count = 0;
//
// IIC_Start();
// IIC_Send_Byte(dev); //发送写命令
// IIC_Wait_Ack();
// IIC_Send_Byte(reg); //发送地址
// IIC_Wait_Ack();
// IIC_Start();
// IIC_Send_Byte(dev+1); //进入接收模式
// IIC_Wait_Ack();
//
// for(count=0;count<length;count++){
//
// if(count!=length-1) data[count]=IIC_Read_Byte(1); //带ACK的读数据
// else data[count]=IIC_Read_Byte(0); //最后一个字节NACK
// }
// IIC_Stop();//产生一个停止条件
// return count;
//}

52
HARDWARE/MPU6050/I2C.h Normal file
View File

@@ -0,0 +1,52 @@
#ifndef _I2C_H_
#define _I2C_H_
#include "system.h"
#include "sys.h"
#include "math.h"
#include "stdbool.h"
#include "stdio.h"
#include "string.h"
#define SDA_IN() {GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=0<<11*2;} //PB5输入模式
#define SDA_OUT() {GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB5输出模式
//IO操作函数
#define IIC_SCL PBout(10) //SCL
#define IIC_SDA PBout(11) //SDA
#define READ_SDA PBin(11) //输入SDA
#ifndef I2C_Direction_Transmitter
#define I2C_Direction_Transmitter ((uint8_t)0x00)
#endif
#ifndef I2C_Direction_Receiver
#define I2C_Direction_Receiver ((uint8_t)0x01)
#endif
enum
{
I2C_ACK,
I2C_NACK
};
void I2C_SDAMode(uint8_t Mode);
void I2C_Start(void);
void I2C_Stop(void);
bool I2C_WaiteForAck(void);
void I2C_Ack(void);
void I2C_NAck(void);
bool I2C_WriteOneBit(uint8_t DevAddr, uint8_t RegAddr, uint8_t BitNum, uint8_t Data);
bool I2C_WriteBits(uint8_t DevAddr, uint8_t RegAddr, uint8_t BitStart, uint8_t Length, uint8_t Data);
void I2C_WriteByte(uint8_t Data);
uint8_t I2C_ReadByte(uint8_t Ack);
u8 I2C_WriteOneByte(uint8_t DevAddr, uint8_t RegAddr, uint8_t Data);
uint8_t I2C_ReadOneByte(uint8_t DevAddr, uint8_t RegAddr);
bool I2C_WriteBuff(uint8_t DevAddr, uint8_t RegAddr, uint8_t Num, uint8_t *pBuff);
bool I2C_ReadBuff(uint8_t DevAddr, uint8_t RegAddr, uint8_t Num, uint8_t *pBuff);
void I2C_GPIOInit(void);
#endif

545
HARDWARE/MPU6050/MPU6050.c Normal file
View File

@@ -0,0 +1,545 @@
#include "MPU6050.h"
#include "I2C.h"
#include "usart.h"
#define PRINT_ACCEL (0x01)
#define PRINT_GYRO (0x02)
#define PRINT_QUAT (0x04)
#define ACCEL_ON (0x01)
#define GYRO_ON (0x02)
#define MOTION (0)
#define NO_MOTION (1)
#define DEFAULT_MPU_HZ (200)
#define FLASH_SIZE (512)
#define FLASH_MEM_START ((void*)0x1800)
#define q30 1073741824.0f
short gyro[3], accel[3], sensors;
//零点漂移计数
int Deviation_Count;
short sum_gyro[3];
short sum_accel[3];
// Gyro static error, raw data
//陀螺仪静差,原始数据
short Deviation_gyro[3],Original_gyro[3];
short Deviation_accel[3],Original_accel[3];
float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f;
//static signed char gyro_orientation[9] = {-1, 0, 0,
// 0,-1, 0,
// 0, 0, 1};
//static unsigned short inv_row_2_scale(const signed char *row)
//{
// unsigned short b;
// if (row[0] > 0)
// b = 0;
// else if (row[0] < 0)
// b = 4;
// else if (row[1] > 0)
// b = 1;
// else if (row[1] < 0)
// b = 5;
// else if (row[2] > 0)
// b = 2;
// else if (row[2] < 0)
// b = 6;
// else
// b = 7; // error
// return b;
//}
void MPU6050_task(void *pvParameters)
{
u32 lastWakeTime = getSysTickCnt();
while(1)
{
//This task runs at 100Hz
//此任务以100Hz的频率运行
vTaskDelayUntil(&lastWakeTime, F2T(RATE_100_HZ));
//Read the gyroscope zero before starting
//开机前,读取陀螺仪零点
if(Deviation_Count<CONTROL_DELAY)
{
Deviation_Count++;
sum_gyro[0]+=gyro[0];
sum_gyro[1]+=gyro[1];
sum_gyro[2]+=gyro[2];
sum_accel[0]+=accel[0];
sum_accel[1]+=accel[1];
sum_accel[2]+=accel[2];
for(int i=0;i<3;i++)
{
Deviation_gyro[i] = (short)(sum_gyro[i] / (short)Deviation_Count);
}
// memcpy(Deviation_gyro,gyro,sizeof(gyro));
memcpy(Deviation_accel,accel,sizeof(accel));
}
MPU_Get_Gyroscope(); //得到陀螺仪数据
MPU_Get_Accelscope(); //获得加速度计值(原始值)
}
}
//static unsigned short inv_orientation_matrix_to_scalar(
// const signed char *mtx)
//{
// unsigned short scalar;
// scalar = inv_row_2_scale(mtx);
// scalar |= inv_row_2_scale(mtx + 3) << 3;
// scalar |= inv_row_2_scale(mtx + 6) << 6;
// return scalar;
//}
//static void run_self_test(void)
//{
// int result;
// long gyro[3], accel[3];
// result = mpu_run_self_test(gyro, accel);
// if (result == 0x7) {
// /* Test passed. We can trust the gyro data here, so let's push it down
// * to the DMP.
// */
// float sens;
// unsigned short accel_sens;
// mpu_get_gyro_sens(&sens);
// gyro[0] = (long)(gyro[0] * sens);
// gyro[1] = (long)(gyro[1] * sens);
// gyro[2] = (long)(gyro[2] * sens);
// dmp_set_gyro_bias(gyro);
// mpu_get_accel_sens(&accel_sens);
// accel[0] *= accel_sens;
// accel[1] *= accel_sens;
// accel[2] *= accel_sens;
// dmp_set_accel_bias(accel);
// //printf("setting bias succesfully ......\r\n");
// }
//}
uint8_t buffer[14];
int16_t MPU6050_FIFO[6][11];
int16_t Gx_offset=0,Gy_offset=0,Gz_offset=0;
/**************************************************************************
Function: The new ADC data is updated to FIFO array for filtering
Input : axayazxy, z-axis acceleration datagxgygzx. Y, z-axis angular acceleration data
Output : none
函数功能将新的ADC数据更新到 FIFO数组进行滤波处理
入口参数axayazxyz轴加速度数据gxgygzxyz轴角加速度数据
返回 值:无
**************************************************************************/
void MPU6050_newValues(int16_t ax,int16_t ay,int16_t az,int16_t gx,int16_t gy,int16_t gz)
{
unsigned char i ;
int32_t sum=0;
for(i=1;i<10;i++){ //FIFO 操作
MPU6050_FIFO[0][i-1]=MPU6050_FIFO[0][i];
MPU6050_FIFO[1][i-1]=MPU6050_FIFO[1][i];
MPU6050_FIFO[2][i-1]=MPU6050_FIFO[2][i];
MPU6050_FIFO[3][i-1]=MPU6050_FIFO[3][i];
MPU6050_FIFO[4][i-1]=MPU6050_FIFO[4][i];
MPU6050_FIFO[5][i-1]=MPU6050_FIFO[5][i];
}
MPU6050_FIFO[0][9]=ax;//将新的数据放置到 数据的最后面
MPU6050_FIFO[1][9]=ay;
MPU6050_FIFO[2][9]=az;
MPU6050_FIFO[3][9]=gx;
MPU6050_FIFO[4][9]=gy;
MPU6050_FIFO[5][9]=gz;
sum=0;
for(i=0;i<10;i++){ //求当前数组的合,再取平均值
sum+=MPU6050_FIFO[0][i];
}
MPU6050_FIFO[0][10]=sum/10;
sum=0;
for(i=0;i<10;i++){
sum+=MPU6050_FIFO[1][i];
}
MPU6050_FIFO[1][10]=sum/10;
sum=0;
for(i=0;i<10;i++){
sum+=MPU6050_FIFO[2][i];
}
MPU6050_FIFO[2][10]=sum/10;
sum=0;
for(i=0;i<10;i++){
sum+=MPU6050_FIFO[3][i];
}
MPU6050_FIFO[3][10]=sum/10;
sum=0;
for(i=0;i<10;i++){
sum+=MPU6050_FIFO[4][i];
}
MPU6050_FIFO[4][10]=sum/10;
sum=0;
for(i=0;i<10;i++){
sum+=MPU6050_FIFO[5][i];
}
MPU6050_FIFO[5][10]=sum/10;
}
/**************************************************************************
Function: Setting the clock source of mpu6050
Input : sourceClock source number
Output : none
函数功能:设置 MPU6050 的时钟源
入口参数source时钟源编号
返回 值:无
* CLK_SEL | Clock Source
* --------+--------------------------------------
* 0 | Internal oscillator
* 1 | PLL with X Gyro reference
* 2 | PLL with Y Gyro reference
* 3 | PLL with Z Gyro reference
* 4 | PLL with external 32.768kHz reference
* 5 | PLL with external 19.2MHz reference
* 6 | Reserved
* 7 | Stops the clock and keeps the timing generator in reset
**************************************************************************/
void MPU6050_setClockSource(uint8_t source){
I2C_WriteBits(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, source);
}
/** Set full-scale gyroscope range.
* @param range New full-scale gyroscope range value
* @see getFullScaleRange()
* @see MPU6050_GYRO_FS_250
* @see MPU6050_RA_GYRO_CONFIG
* @see MPU6050_GCONFIG_FS_SEL_BIT
* @see MPU6050_GCONFIG_FS_SEL_LENGTH
*/
void MPU6050_setFullScaleGyroRange(uint8_t range) {
I2C_WriteBits(devAddr, MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, range);
}
/**************************************************************************
Function: Setting the maximum range of mpu6050 accelerometer
Input : rangeAcceleration maximum range number
Output : none
函数功能:设置 MPU6050 加速度计的最大量程
入口参数range加速度最大量程编号
返回 值:无
**************************************************************************/
//#define MPU6050_ACCEL_FS_2 0x00 //===最大量程+-2G
//#define MPU6050_ACCEL_FS_4 0x01 //===最大量程+-4G
//#define MPU6050_ACCEL_FS_8 0x02 //===最大量程+-8G
//#define MPU6050_ACCEL_FS_16 0x03 //===最大量程+-16G
void MPU6050_setFullScaleAccelRange(uint8_t range) {
I2C_WriteBits(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, range);
}
/**************************************************************************
Function: Set mpu6050 to sleep mode or not
Input : enable1sleep0work
Output : none
函数功能:设置 MPU6050 是否进入睡眠模式
入口参数enable1睡觉0工作
返回 值:无
**************************************************************************/
void MPU6050_setSleepEnabled(uint8_t enabled) {
I2C_WriteOneBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, enabled);
}
/**************************************************************************
Function: Read identity
Input : none
Output : 0x68
函数功能:读取 MPU6050 WHO_AM_I 标识
入口参数:无
返回 值0x68
**************************************************************************/
uint8_t MPU6050_getDeviceID(void) {
return I2C_ReadOneByte(devAddr,MPU6050_RA_WHO_AM_I);
// IICreadBytes(devAddr, MPU6050_RA_WHO_AM_I, 1, buffer);
// return buffer[0];
}
/**************************************************************************
Function: Check whether mpu6050 is connected
Input : none
Output : 1Connected0Not connected
函数功能检测MPU6050 是否已经连接
入口参数:无
返回 值1已连接0未连接
**************************************************************************/
uint8_t MPU6050_testConnection(void) {
if(MPU6050_getDeviceID() == 0x68) //0b01101000;
return 1;
else return 0;
}
/**************************************************************************
Function: Setting whether mpu6050 is the host of aux I2C cable
Input : enable1yes0;not
Output : none
函数功能:设置 MPU6050 是否为AUX I2C线的主机
入口参数enable10
返回 值:无
**************************************************************************/
void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) {
I2C_WriteOneBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_EN_BIT, enabled);
}
/**************************************************************************
Function: Setting whether mpu6050 is the host of aux I2C cable
Input : enable1yes0;not
Output : none
函数功能:设置 MPU6050 是否为AUX I2C线的主机
入口参数enable10
返回 值:无
**************************************************************************/
void MPU6050_setI2CBypassEnabled(uint8_t enabled) {
I2C_WriteOneBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_I2C_BYPASS_EN_BIT, enabled);
}
/**************************************************************************
Function: initialization Mpu6050 to enter the available state
Input : none
Output : none
函数功能:初始化 MPU6050 以进入可用状态
入口参数:无
返回 值:无
**************************************************************************/
u8 MPU6050_initialize(void)
{
u8 res;
//IIC_Init(); //Initialize the IIC bus //初始化IIC总线
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X80); //Reset MPUrobot_select_init.h //复位MPUrobot_select_init.h
delay_ms(200); //Delay 200 ms //延时200ms
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X00); //Wake mpurobot_select_init.h //唤醒MPUrobot_select_init.h
//MPU6050_Set_Gyro_Fsr(1); //Gyroscope sensor //陀螺仪传感器,±500dps=±500°/s ±32768 (gyro/32768*500)*PI/180(rad/s)=gyro/3754.9(rad/s)
MPU6050_setFullScaleGyroRange(MPU6050_GYRO_FS_500);
//MPU6050_Set_Accel_Fsr(0); //Acceleration sensor //加速度传感器,±2g=±2*9.8m/s^2 ±32768 accel/32768*19.6=accel/1671.84
MPU6050_setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
MPU6050_Set_Rate(50); //Set the sampling rate to 50Hz //设置采样率50Hz
I2C_WriteOneByte(devAddr,MPU6050_RA_INT_ENABLE,0X00); //Turn off all interrupts //关闭所有中断
I2C_WriteOneByte(devAddr,MPU6050_RA_USER_CTRL,0X00); //The I2C main mode is off //I2C主模式关闭
I2C_WriteOneByte(devAddr,MPU6050_RA_FIFO_EN,0X00); //Close the FIFO //关闭FIFO
//The INT pin is low, enabling bypass mode to read the magnetometer directly
//INT引脚低电平有效开启bypass模式可以直接读取磁力计
I2C_WriteOneByte(devAddr,MPU6050_RA_INT_PIN_CFG,0X80);
//Read the ID of MPU6050
//读取MPU6050的ID
res=I2C_ReadOneByte(devAddr,MPU6050_RA_WHO_AM_I);
if(res==MPU6050_DEFAULT_ADDRESS) //The device ID is correct, The correct device ID depends on the AD pin //器件ID正确, 器件ID的正确取决于AD引脚
{
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X01); //Set CLKSEL,PLL X axis as reference //设置CLKSEL,PLL X轴为参考
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_2,0X00); //Acceleration and gyroscope both work //加速度与陀螺仪都工作
MPU6050_Set_Rate(50); //Set the sampling rate to 50Hz //设置采样率为50Hz
}else return 1;
return 0;
}
/**************************************************************************
Function: Initialization of DMP in mpu6050
Input : none
Output : none
函数功能MPU6050内置DMP的初始化
入口参数:无
返回 值:无
**************************************************************************/
//void DMP_Init(void)
//{
// u8 temp[1]={0};
// i2cRead(0x68,0x75,1,temp);
// printf("mpu_set_sensor complete ......\r\n");
// if(temp[0]!=0x68)NVIC_SystemReset();
// if(!mpu_init())
// {
// if(!mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL))
// printf("mpu_set_sensor complete ......\r\n");
// if(!mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL))
// printf("mpu_configure_fifo complete ......\r\n");
// if(!mpu_set_sample_rate(DEFAULT_MPU_HZ))
// printf("mpu_set_sample_rate complete ......\r\n");
// if(!dmp_load_motion_driver_firmware())
// printf("dmp_load_motion_driver_firmware complete ......\r\n");
// if(!dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation)))
// printf("dmp_set_orientation complete ......\r\n");
// if(!dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
// DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |
// DMP_FEATURE_GYRO_CAL))
// printf("dmp_enable_feature complete ......\r\n");
// if(!dmp_set_fifo_rate(DEFAULT_MPU_HZ))
// printf("dmp_set_fifo_rate complete ......\r\n");
// run_self_test();
// if(!mpu_set_dmp_state(1))
// printf("mpu_set_dmp_state complete ......\r\n");
// }
//}
/**************************************************************************
Function: Read the attitude information of DMP in mpu6050
Input : none
Output : none
函数功能读取MPU6050内置DMP的姿态信息
入口参数:无
返回 值:无
**************************************************************************/
//void Read_DMP(void)
//{
// unsigned long sensor_timestamp;
// unsigned char more;
// long quat[4];
// dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors, &more); //读取DMP数据
// if (sensors & INV_WXYZ_QUAT )
// {
// q0=quat[0] / q30;
// q1=quat[1] / q30;
// q2=quat[2] / q30;
// q3=quat[3] / q30; //四元数
// Roll = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; //计算出横滚角
// Pitch = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // 计算出俯仰角
// Yaw = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //计算出偏航角
// }
//}
/**************************************************************************
Function: Read mpu6050 built-in temperature sensor data
Input : none
Output : Centigrade temperature
函数功能读取MPU6050内置温度传感器数据
入口参数:无
返回 值:摄氏温度
**************************************************************************/
int Read_Temperature(void)
{
float Temp;
Temp=(I2C_ReadOneByte(devAddr,MPU6050_RA_TEMP_OUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_TEMP_OUT_L);
if(Temp>32768) Temp-=65536; //数据类型转换
Temp=(36.53f+Temp/340)*10; //温度放大十倍存放
return (int)Temp;
}
/**************************************************************************
Function: Initialize TIM2 as the encoder interface mode
Input : LPF: Digital low-pass filtering frequency (Hz)
Output : 0: Settings successful, others: Settings failed
函数功能设置MPUrobot_select_init.h的数字低通滤波器
入口参数lpf:数字低通滤波频率(Hz)
返回 值0:设置成功, 其他:设置失败
**************************************************************************/
unsigned char MPU6050_Set_LPF(u16 lpf)
{
u8 data=0;
if(lpf>=188)data=1;
else if(lpf>=98)data=2;
else if(lpf>=42)data=3;
else if(lpf>=20)data=4;
else if(lpf>=10)data=5;
else data=6;
return I2C_WriteOneByte(devAddr,MPU6050_RA_CONFIG,data); //Set the digital lowpass filter//设置数字低通滤波器
}
/**************************************************************************
Function: Initialize TIM2 as the encoder interface mode
Input : rate:4~1000(Hz)
Output : 0: Settings successful, others: Settings failed
函数功能设置MPUrobot_select_init.h的采样率(假定Fs=1KHz)
入口参数rate:4~1000(Hz)
返回 值0:设置成功, 其他:设置失败
**************************************************************************/
unsigned char MPU6050_Set_Rate(u16 rate)
{
u8 data;
if(rate>1000)rate=1000;
if(rate<4)rate=4;
data=1000/rate-1;
data=I2C_WriteOneByte(devAddr,MPU6050_RA_SMPLRT_DIV,data); //Set the digital lowpass filter//设置数字低通滤波器
return MPU6050_Set_LPF(rate/2); //Automatically sets LPF to half of the sampling rate //自动设置LPF为采样率的一半
}
/**************************************************************************
Function: Initialize TIM2 as the encoder interface mode
Input : Gx, Gy, Gz: raw readings (plus or minus) of the x,y, and z axes of the gyroscope
Output : 0: success, others: error code
函数功能:获得陀螺仪值(原始值)
**************************************************************************/
void MPU_Get_Gyroscope(void)
{
gyro[0]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_L); //读取X轴陀螺仪
gyro[1]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_YOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_YOUT_L); //读取Y轴陀螺仪
gyro[2]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_L); //读取Z轴陀螺仪
if(Deviation_Count<CONTROL_DELAY) // 10 seconds before starting //开机前10秒
{
Led_Count=1; //LED high frequency flashing //LED高频闪烁
Flag_Stop=1; //The software fails to flag location 1 //软件失能标志位置1
}
else //10 seconds after starting //开机10秒后
{
if(Deviation_Count==CONTROL_DELAY)
Flag_Stop=0; //The software fails to flag location 0 //软件失能标志位置0
Led_Count=300; //The LED returns to normal flicker frequency //LED恢复正常闪烁频率
//Save the raw data to update zero by clicking the user button
//保存原始数据用于单击用户按键更新零点
Original_gyro[0] =gyro[0];
Original_gyro[1] =gyro[1];
Original_gyro[2]= gyro[2];
//Removes zero drift data
//去除零点漂移的数据
gyro[0] =Original_gyro[0]-Deviation_gyro[0];
gyro[1] =Original_gyro[1]-Deviation_gyro[1];
gyro[2]= Original_gyro[2]-Deviation_gyro[2];
}
}
/**************************************************************************
Function: Initialize TIM2 as the encoder interface mode
Input : Gx, Gy, Gz: raw readings (plus or minus) of the x,y, and z axes of the gyroscope
Output : 0: success, others: error code
函数功能:获得加速度计值(原始值)
**************************************************************************/
void MPU_Get_Accelscope(void)
{
accel[0]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_XOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_XOUT_L); //读取X轴加速度计
accel[1]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_YOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_YOUT_L); //读取X轴加速度计
accel[2]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_ZOUT_L); //读取Z轴加速度计
if(Deviation_Count<CONTROL_DELAY) // 10 seconds before starting //开机前10秒
{
}
else //10 seconds after starting //开机10秒后
{
//Save the raw data to update zero by clicking the user button
//保存原始数据用于单击用户按键更新零点
Original_accel[0] =accel[0];
Original_accel[1] =accel[1];
Original_accel[2]= accel[2];
//Removes zero drift data
//去除零点漂移的数据
accel[0] =Original_accel[0]-Deviation_accel[0];
accel[1] =Original_accel[1]-Deviation_accel[1];
accel[2]= Original_accel[2]-Deviation_accel[2]+16384;
}
}
//------------------End of File----------------------------

385
HARDWARE/MPU6050/mpu6050.h Normal file
View File

@@ -0,0 +1,385 @@
#ifndef __MPU6050_H
#define __MPU6050_H
#include "sys.h"
#define devAddr 0xD0
#define MPU6050_ADDRESS_AD0_LOW 0x68 // address pin low (GND), default for InvenSense evaluation board
#define MPU6050_ADDRESS_AD0_HIGH 0x69 // address pin high (VCC)
#define MPU6050_DEFAULT_ADDRESS MPU6050_ADDRESS_AD0_LOW
#define MPU6050_RA_XG_OFFS_TC 0x00 //[7] PWR_MODE, [6:1] XG_OFFS_TC, [0] OTP_BNK_VLD
#define MPU6050_RA_YG_OFFS_TC 0x01 //[7] PWR_MODE, [6:1] YG_OFFS_TC, [0] OTP_BNK_VLD
#define MPU6050_RA_ZG_OFFS_TC 0x02 //[7] PWR_MODE, [6:1] ZG_OFFS_TC, [0] OTP_BNK_VLD
#define MPU6050_RA_X_FINE_GAIN 0x03 //[7:0] X_FINE_GAIN
#define MPU6050_RA_Y_FINE_GAIN 0x04 //[7:0] Y_FINE_GAIN
#define MPU6050_RA_Z_FINE_GAIN 0x05 //[7:0] Z_FINE_GAIN
#define MPU6050_RA_XA_OFFS_H 0x06 //[15:0] XA_OFFS
#define MPU6050_RA_XA_OFFS_L_TC 0x07
#define MPU6050_RA_YA_OFFS_H 0x08 //[15:0] YA_OFFS
#define MPU6050_RA_YA_OFFS_L_TC 0x09
#define MPU6050_RA_ZA_OFFS_H 0x0A //[15:0] ZA_OFFS
#define MPU6050_RA_ZA_OFFS_L_TC 0x0B
#define MPU6050_RA_XG_OFFS_USRH 0x13 //[15:0] XG_OFFS_USR
#define MPU6050_RA_XG_OFFS_USRL 0x14
#define MPU6050_RA_YG_OFFS_USRH 0x15 //[15:0] YG_OFFS_USR
#define MPU6050_RA_YG_OFFS_USRL 0x16
#define MPU6050_RA_ZG_OFFS_USRH 0x17 //[15:0] ZG_OFFS_USR
#define MPU6050_RA_ZG_OFFS_USRL 0x18
#define MPU6050_RA_SMPLRT_DIV 0x19
#define MPU6050_RA_CONFIG 0x1A
#define MPU6050_RA_GYRO_CONFIG 0x1B
#define MPU6050_RA_ACCEL_CONFIG 0x1C
#define MPU6050_RA_FF_THR 0x1D
#define MPU6050_RA_FF_DUR 0x1E
#define MPU6050_RA_MOT_THR 0x1F
#define MPU6050_RA_MOT_DUR 0x20
#define MPU6050_RA_ZRMOT_THR 0x21
#define MPU6050_RA_ZRMOT_DUR 0x22
#define MPU6050_RA_FIFO_EN 0x23
#define MPU6050_RA_I2C_MST_CTRL 0x24
#define MPU6050_RA_I2C_SLV0_ADDR 0x25
#define MPU6050_RA_I2C_SLV0_REG 0x26
# define MPU6050_RA_I2C_SLV0_CTRL 0x27
#define MPU6050_RA_I2C_SLV1_ADDR 0x28
#define MPU6050_RA_I2C_SLV1_REG 0x29
#define MPU6050_RA_I2C_SLV1_CTRL 0x2A
#define MPU6050_RA_I2C_SLV2_ADDR 0x2B
#define MPU6050_RA_I2C_SLV2_REG 0x2C
#define MPU6050_RA_I2C_SLV2_CTRL 0x2D
#define MPU6050_RA_I2C_SLV3_ADDR 0x2E
#define MPU6050_RA_I2C_SLV3_REG 0x2F
#define MPU6050_RA_I2C_SLV3_CTRL 0x30
#define MPU6050_RA_I2C_SLV4_ADDR 0x31
#define MPU6050_RA_I2C_SLV4_REG 0x32
#define MPU6050_RA_I2C_SLV4_DO 0x33
#define MPU6050_RA_I2C_SLV4_CTRL 0x34
#define MPU6050_RA_I2C_SLV4_DI 0x35
#define MPU6050_RA_I2C_MST_STATUS 0x36
#define MPU6050_RA_INT_PIN_CFG 0x37
#define MPU6050_RA_INT_ENABLE 0x38
#define MPU6050_RA_DMP_INT_STATUS 0x39
#define MPU6050_RA_INT_STATUS 0x3A
#define MPU6050_RA_ACCEL_XOUT_H 0x3B
#define MPU6050_RA_ACCEL_XOUT_L 0x3C
#define MPU6050_RA_ACCEL_YOUT_H 0x3D
#define MPU6050_RA_ACCEL_YOUT_L 0x3E
#define MPU6050_RA_ACCEL_ZOUT_H 0x3F
#define MPU6050_RA_ACCEL_ZOUT_L 0x40
#define MPU6050_RA_TEMP_OUT_H 0x41
#define MPU6050_RA_TEMP_OUT_L 0x42
#define MPU6050_RA_GYRO_XOUT_H 0x43
#define MPU6050_RA_GYRO_XOUT_L 0x44
#define MPU6050_RA_GYRO_YOUT_H 0x45
#define MPU6050_RA_GYRO_YOUT_L 0x46
#define MPU6050_RA_GYRO_ZOUT_H 0x47
#define MPU6050_RA_GYRO_ZOUT_L 0x48
#define MPU6050_RA_EXT_SENS_DATA_00 0x49
#define MPU6050_RA_EXT_SENS_DATA_01 0x4A
#define MPU6050_RA_EXT_SENS_DATA_02 0x4B
#define MPU6050_RA_EXT_SENS_DATA_03 0x4C
#define MPU6050_RA_EXT_SENS_DATA_04 0x4D
#define MPU6050_RA_EXT_SENS_DATA_05 0x4E
#define MPU6050_RA_EXT_SENS_DATA_06 0x4F
#define MPU6050_RA_EXT_SENS_DATA_07 0x50
#define MPU6050_RA_EXT_SENS_DATA_08 0x51
#define MPU6050_RA_EXT_SENS_DATA_09 0x52
#define MPU6050_RA_EXT_SENS_DATA_10 0x53
#define MPU6050_RA_EXT_SENS_DATA_11 0x54
#define MPU6050_RA_EXT_SENS_DATA_12 0x55
#define MPU6050_RA_EXT_SENS_DATA_13 0x56
#define MPU6050_RA_EXT_SENS_DATA_14 0x57
#define MPU6050_RA_EXT_SENS_DATA_15 0x58
#define MPU6050_RA_EXT_SENS_DATA_16 0x59
#define MPU6050_RA_EXT_SENS_DATA_17 0x5A
#define MPU6050_RA_EXT_SENS_DATA_18 0x5B
#define MPU6050_RA_EXT_SENS_DATA_19 0x5C
#define MPU6050_RA_EXT_SENS_DATA_20 0x5D
#define MPU6050_RA_EXT_SENS_DATA_21 0x5E
#define MPU6050_RA_EXT_SENS_DATA_22 0x5F
#define MPU6050_RA_EXT_SENS_DATA_23 0x60
#define MPU6050_RA_MOT_DETECT_STATUS 0x61
#define MPU6050_RA_I2C_SLV0_DO 0x63
#define MPU6050_RA_I2C_SLV1_DO 0x64
#define MPU6050_RA_I2C_SLV2_DO 0x65
#define MPU6050_RA_I2C_SLV3_DO 0x66
#define MPU6050_RA_I2C_MST_DELAY_CTRL 0x67
#define MPU6050_RA_SIGNAL_PATH_RESET 0x68
#define MPU6050_RA_MOT_DETECT_CTRL 0x69
#define MPU6050_RA_USER_CTRL 0x6A
#define MPU6050_RA_PWR_MGMT_1 0x6B
#define MPU6050_RA_PWR_MGMT_2 0x6C
#define MPU6050_RA_BANK_SEL 0x6D
#define MPU6050_RA_MEM_START_ADDR 0x6E
#define MPU6050_RA_MEM_R_W 0x6F
#define MPU6050_RA_DMP_CFG_1 0x70
#define MPU6050_RA_DMP_CFG_2 0x71
#define MPU6050_RA_FIFO_COUNTH 0x72
#define MPU6050_RA_FIFO_COUNTL 0x73
#define MPU6050_RA_FIFO_R_W 0x74
#define MPU6050_RA_WHO_AM_I 0x75
#define MPU6050_TC_PWR_MODE_BIT 7
#define MPU6050_TC_OFFSET_BIT 6
#define MPU6050_TC_OFFSET_LENGTH 6
#define MPU6050_TC_OTP_BNK_VLD_BIT 0
#define MPU6050_VDDIO_LEVEL_VLOGIC 0
#define MPU6050_VDDIO_LEVEL_VDD 1
#define MPU6050_CFG_EXT_SYNC_SET_BIT 5
#define MPU6050_CFG_EXT_SYNC_SET_LENGTH 3
#define MPU6050_CFG_DLPF_CFG_BIT 2
#define MPU6050_CFG_DLPF_CFG_LENGTH 3
#define MPU6050_EXT_SYNC_DISABLED 0x0
#define MPU6050_EXT_SYNC_TEMP_OUT_L 0x1
#define MPU6050_EXT_SYNC_GYRO_XOUT_L 0x2
#define MPU6050_EXT_SYNC_GYRO_YOUT_L 0x3
#define MPU6050_EXT_SYNC_GYRO_ZOUT_L 0x4
#define MPU6050_EXT_SYNC_ACCEL_XOUT_L 0x5
#define MPU6050_EXT_SYNC_ACCEL_YOUT_L 0x6
#define MPU6050_EXT_SYNC_ACCEL_ZOUT_L 0x7
#define MPU6050_DLPF_BW_256 0x00
#define MPU6050_DLPF_BW_188 0x01
#define MPU6050_DLPF_BW_98 0x02
#define MPU6050_DLPF_BW_42 0x03
#define MPU6050_DLPF_BW_20 0x04
#define MPU6050_DLPF_BW_10 0x05
#define MPU6050_DLPF_BW_5 0x06
#define MPU6050_GCONFIG_FS_SEL_BIT 4
#define MPU6050_GCONFIG_FS_SEL_LENGTH 2
#define MPU6050_GYRO_FS_250 0x00
#define MPU6050_GYRO_FS_500 0x01
#define MPU6050_GYRO_FS_1000 0x02
#define MPU6050_GYRO_FS_2000 0x03
#define MPU6050_ACONFIG_XA_ST_BIT 7
#define MPU6050_ACONFIG_YA_ST_BIT 6
#define MPU6050_ACONFIG_ZA_ST_BIT 5
#define MPU6050_ACONFIG_AFS_SEL_BIT 4
#define MPU6050_ACONFIG_AFS_SEL_LENGTH 2
#define MPU6050_ACONFIG_ACCEL_HPF_BIT 2
#define MPU6050_ACONFIG_ACCEL_HPF_LENGTH 3
#define MPU6050_ACCEL_FS_2 0x00
#define MPU6050_ACCEL_FS_4 0x01
#define MPU6050_ACCEL_FS_8 0x02
#define MPU6050_ACCEL_FS_16 0x03
#define MPU6050_DHPF_RESET 0x00
#define MPU6050_DHPF_5 0x01
#define MPU6050_DHPF_2P5 0x02
#define MPU6050_DHPF_1P25 0x03
#define MPU6050_DHPF_0P63 0x04
#define MPU6050_DHPF_HOLD 0x07
#define MPU6050_TEMP_FIFO_EN_BIT 7
#define MPU6050_XG_FIFO_EN_BIT 6
#define MPU6050_YG_FIFO_EN_BIT 5
#define MPU6050_ZG_FIFO_EN_BIT 4
#define MPU6050_ACCEL_FIFO_EN_BIT 3
#define MPU6050_SLV2_FIFO_EN_BIT 2
#define MPU6050_SLV1_FIFO_EN_BIT 1
#define MPU6050_SLV0_FIFO_EN_BIT 0
#define MPU6050_MULT_MST_EN_BIT 7
#define MPU6050_WAIT_FOR_ES_BIT 6
#define MPU6050_SLV_3_FIFO_EN_BIT 5
#define MPU6050_I2C_MST_P_NSR_BIT 4
#define MPU6050_I2C_MST_CLK_BIT 3
#define MPU6050_I2C_MST_CLK_LENGTH 4
#define MPU6050_CLOCK_DIV_348 0x0
#define MPU6050_CLOCK_DIV_333 0x1
#define MPU6050_CLOCK_DIV_320 0x2
#define MPU6050_CLOCK_DIV_308 0x3
#define MPU6050_CLOCK_DIV_296 0x4
#define MPU6050_CLOCK_DIV_286 0x5
#define MPU6050_CLOCK_DIV_276 0x6
#define MPU6050_CLOCK_DIV_267 0x7
#define MPU6050_CLOCK_DIV_258 0x8
#define MPU6050_CLOCK_DIV_500 0x9
#define MPU6050_CLOCK_DIV_471 0xA
#define MPU6050_CLOCK_DIV_444 0xB
#define MPU6050_CLOCK_DIV_421 0xC
#define MPU6050_CLOCK_DIV_400 0xD
#define MPU6050_CLOCK_DIV_381 0xE
#define MPU6050_CLOCK_DIV_364 0xF
#define MPU6050_I2C_SLV_RW_BIT 7
#define MPU6050_I2C_SLV_ADDR_BIT 6
#define MPU6050_I2C_SLV_ADDR_LENGTH 7
#define MPU6050_I2C_SLV_EN_BIT 7
#define MPU6050_I2C_SLV_BYTE_SW_BIT 6
#define MPU6050_I2C_SLV_REG_DIS_BIT 5
#define MPU6050_I2C_SLV_GRP_BIT 4
#define MPU6050_I2C_SLV_LEN_BIT 3
#define MPU6050_I2C_SLV_LEN_LENGTH 4
#define MPU6050_I2C_SLV4_RW_BIT 7
#define MPU6050_I2C_SLV4_ADDR_BIT 6
#define MPU6050_I2C_SLV4_ADDR_LENGTH 7
#define MPU6050_I2C_SLV4_EN_BIT 7
#define MPU6050_I2C_SLV4_INT_EN_BIT 6
#define MPU6050_I2C_SLV4_REG_DIS_BIT 5
#define MPU6050_I2C_SLV4_MST_DLY_BIT 4
#define MPU6050_I2C_SLV4_MST_DLY_LENGTH 5
#define MPU6050_MST_PASS_THROUGH_BIT 7
#define MPU6050_MST_I2C_SLV4_DONE_BIT 6
#define MPU6050_MST_I2C_LOST_ARB_BIT 5
#define MPU6050_MST_I2C_SLV4_NACK_BIT 4
#define MPU6050_MST_I2C_SLV3_NACK_BIT 3
#define MPU6050_MST_I2C_SLV2_NACK_BIT 2
#define MPU6050_MST_I2C_SLV1_NACK_BIT 1
#define MPU6050_MST_I2C_SLV0_NACK_BIT 0
#define MPU6050_INTCFG_INT_LEVEL_BIT 7
#define MPU6050_INTCFG_INT_OPEN_BIT 6
#define MPU6050_INTCFG_LATCH_INT_EN_BIT 5
#define MPU6050_INTCFG_INT_RD_CLEAR_BIT 4
#define MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT 3
#define MPU6050_INTCFG_FSYNC_INT_EN_BIT 2
#define MPU6050_INTCFG_I2C_BYPASS_EN_BIT 1
#define MPU6050_INTCFG_CLKOUT_EN_BIT 0
#define MPU6050_INTMODE_ACTIVEHIGH 0x00
#define MPU6050_INTMODE_ACTIVELOW 0x01
#define MPU6050_INTDRV_PUSHPULL 0x00
#define MPU6050_INTDRV_OPENDRAIN 0x01
#define MPU6050_INTLATCH_50USPULSE 0x00
#define MPU6050_INTLATCH_WAITCLEAR 0x01
#define MPU6050_INTCLEAR_STATUSREAD 0x00
#define MPU6050_INTCLEAR_ANYREAD 0x01
#define MPU6050_INTERRUPT_FF_BIT 7
#define MPU6050_INTERRUPT_MOT_BIT 6
#define MPU6050_INTERRUPT_ZMOT_BIT 5
#define MPU6050_INTERRUPT_FIFO_OFLOW_BIT 4
#define MPU6050_INTERRUPT_I2C_MST_INT_BIT 3
#define MPU6050_INTERRUPT_PLL_RDY_INT_BIT 2
#define MPU6050_INTERRUPT_DMP_INT_BIT 1
#define MPU6050_INTERRUPT_DATA_RDY_BIT 0
// TODO: figure out what these actually do
// UMPL source code is not very obivous
#define MPU6050_DMPINT_5_BIT 5
#define MPU6050_DMPINT_4_BIT 4
#define MPU6050_DMPINT_3_BIT 3
#define MPU6050_DMPINT_2_BIT 2
#define MPU6050_DMPINT_1_BIT 1
#define MPU6050_DMPINT_0_BIT 0
#define MPU6050_MOTION_MOT_XNEG_BIT 7
#define MPU6050_MOTION_MOT_XPOS_BIT 6
#define MPU6050_MOTION_MOT_YNEG_BIT 5
#define MPU6050_MOTION_MOT_YPOS_BIT 4
#define MPU6050_MOTION_MOT_ZNEG_BIT 3
#define MPU6050_MOTION_MOT_ZPOS_BIT 2
#define MPU6050_MOTION_MOT_ZRMOT_BIT 0
#define MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT 7
#define MPU6050_DELAYCTRL_I2C_SLV4_DLY_EN_BIT 4
#define MPU6050_DELAYCTRL_I2C_SLV3_DLY_EN_BIT 3
#define MPU6050_DELAYCTRL_I2C_SLV2_DLY_EN_BIT 2
#define MPU6050_DELAYCTRL_I2C_SLV1_DLY_EN_BIT 1
#define MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT 0
#define MPU6050_PATHRESET_GYRO_RESET_BIT 2
#define MPU6050_PATHRESET_ACCEL_RESET_BIT 1
#define MPU6050_PATHRESET_TEMP_RESET_BIT 0
#define MPU6050_DETECT_ACCEL_ON_DELAY_BIT 5
#define MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH 2
#define MPU6050_DETECT_FF_COUNT_BIT 3
#define MPU6050_DETECT_FF_COUNT_LENGTH 2
#define MPU6050_DETECT_MOT_COUNT_BIT 1
#define MPU6050_DETECT_MOT_COUNT_LENGTH 2
#define MPU6050_DETECT_DECREMENT_RESET 0x0
#define MPU6050_DETECT_DECREMENT_1 0x1
#define MPU6050_DETECT_DECREMENT_2 0x2
#define MPU6050_DETECT_DECREMENT_4 0x3
#define MPU6050_USERCTRL_DMP_EN_BIT 7
#define MPU6050_USERCTRL_FIFO_EN_BIT 6
#define MPU6050_USERCTRL_I2C_MST_EN_BIT 5
#define MPU6050_USERCTRL_I2C_IF_DIS_BIT 4
#define MPU6050_USERCTRL_DMP_RESET_BIT 3
#define MPU6050_USERCTRL_FIFO_RESET_BIT 2
#define MPU6050_USERCTRL_I2C_MST_RESET_BIT 1
#define MPU6050_USERCTRL_SIG_COND_RESET_BIT 0
#define MPU6050_PWR1_DEVICE_RESET_BIT 7
#define MPU6050_PWR1_SLEEP_BIT 6
#define MPU6050_PWR1_CYCLE_BIT 5
#define MPU6050_PWR1_TEMP_DIS_BIT 3
#define MPU6050_PWR1_CLKSEL_BIT 2
#define MPU6050_PWR1_CLKSEL_LENGTH 3
#define MPU6050_CLOCK_INTERNAL 0x00
#define MPU6050_CLOCK_PLL_XGYRO 0x01
#define MPU6050_CLOCK_PLL_YGYRO 0x02
#define MPU6050_CLOCK_PLL_ZGYRO 0x03
#define MPU6050_CLOCK_PLL_EXT32K 0x04
#define MPU6050_CLOCK_PLL_EXT19M 0x05
#define MPU6050_CLOCK_KEEP_RESET 0x07
#define MPU6050_PWR2_LP_WAKE_CTRL_BIT 7
#define MPU6050_PWR2_LP_WAKE_CTRL_LENGTH 2
#define MPU6050_PWR2_STBY_XA_BIT 5
#define MPU6050_PWR2_STBY_YA_BIT 4
#define MPU6050_PWR2_STBY_ZA_BIT 3
#define MPU6050_PWR2_STBY_XG_BIT 2
#define MPU6050_PWR2_STBY_YG_BIT 1
#define MPU6050_PWR2_STBY_ZG_BIT 0
#define MPU6050_WAKE_FREQ_1P25 0x0
#define MPU6050_WAKE_FREQ_2P5 0x1
#define MPU6050_WAKE_FREQ_5 0x2
#define MPU6050_WAKE_FREQ_10 0x3
#define MPU6050_BANKSEL_PRFTCH_EN_BIT 6
#define MPU6050_BANKSEL_CFG_USER_BANK_BIT 5
#define MPU6050_BANKSEL_MEM_SEL_BIT 4
#define MPU6050_BANKSEL_MEM_SEL_LENGTH 5
#define MPU6050_WHO_AM_I_BIT 6
#define MPU6050_WHO_AM_I_LENGTH 6
#define MPU6050_TASK_PRIO 3
#define MPU6050_STK_SIZE 256
extern short gyro[3], accel[3];
extern int Deviation_Count;
extern short Deviation_gyro[3],Original_gyro[3];
extern short Deviation_accel[3],Original_accel[3];
extern int16_t Gx_offset,Gy_offset,Gz_offset;
extern float Acc1G_Values;
extern float Roll,Pitch,Yaw;
//供外部调用的API
u8 MPU6050_initialize(void); //初始化
uint8_t MPU6050_testConnection(void); //检测MPU6050是否存在
//读取ADC值
void MPU6050_getMotion6(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz);
void MPU6050_getlastMotion6(int16_t* ax, int16_t* ay,
int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz);
uint8_t MPU6050_getDeviceID(void); //读取MPU6050的ID
void MPU6050_InitGyro_Offset(void);//初始化陀螺仪偏置
void DMP_Init(void);
void Read_DMP(void);
int Read_Temperature(void);
void MPU6050_task(void *pvParameters);
unsigned char MPU6050_Set_LPF(u16 lpf);
unsigned char MPU6050_Set_Rate(u16 rate);
void MPU_Get_Gyroscope(void);
void MPU_Get_Accelscope(void);
#endif