MPU6050 / MPU6000配置中斷寄存器後INT電平一直不變(為高),解決辦法:
第一步:初始化子產品
//初始化MPU6050
//傳回值: 0,成功
// 其他,錯誤代碼
uint8_t MPU_Init(void)
{
uint8_t res;
MCU6000_INT_Init()
IIC_Init(); //初始化IIC總線
MPU_Write_Byte(MPU6050_RA_PWR_MGMT_1,0X80); //複位MPU6050
delay_ms(100);
MPU_Write_Byte(MPU6050_RA_PWR_MGMT_1,0X00); //喚醒MPU6050
MPU_Set_Gyro_Fsr(3); //陀螺儀傳感器,±2000dps
MPU_Set_Accel_Fsr(0); //加速度傳感器 ±2g
MPU_Set_Rate(200); //設定采樣率200-50HZ
MPU_Write_Byte(MPU6050_RA_INT_ENABLE,0X00); //關閉所有中斷
MPU_Write_Byte(MPU6050_RA_USER_CTRL,0X00); //I2C主模式關閉
MPU_Write_Byte(MPU6050_RA_FIFO_EN,0X00); //關閉FIFO
MPU_Write_Byte(MPU6050_RA_INT_PIN_CFG,0X80); //中斷的邏輯電平模式,設定為0,中斷信号為高電;設定為1,中斷信号為低電平時。
res=MPU_Read_Byte(MPU6050_RA_WHO_AM_I);
if(res==MPU_ADDR) //器件ID正确
{
MPU_Write_Byte(MPU6050_RA_PWR_MGMT_1,0X02); //設定CLKSEL,PLL X 軸為參考
MPU_Write_Byte(MPU6050_RA_PWR_MGMT_2,0X00); //加速度陀螺儀都工作
MPU_Set_Rate(200); //設定采樣率為200-50HZ
}else return 1;
return 0;
}
第二部:設定中斷
void MPU_INT_Init(void)
{
//資料就緒中斷
// MPU_Write_Byte(MPU6050_RA_CONFIG,0x06); //配置外部引腳采樣和DLPF數字低通濾波器
// MPU_Write_Byte(MPU6050_RA_INT_PIN_CFG,0X1C); //INT引腳低電平平時
// MPU_Write_Byte(MPU6050_RA_INT_ENABLE,0x01); //中斷使能寄存器
//自由落體、運動、靜止中斷 三選一
// Free_Fall_Interrupt(); //自由落體中斷
Motion_Interrupt(); //運動中斷
// Zero_Motion_Interrupt(); //靜止中斷
MPU_Write_Byte(MPU6050_RA_CONFIG,0x04); //配置外部引腳采樣和DLPF數字低通濾波器
MPU_Write_Byte(MPU6050_RA_ACCEL_CONFIG,0x1C); //加速度傳感器量程和高通濾波器配置
MPU_Write_Byte(MPU6050_RA_INT_PIN_CFG,0X1C); //INT引腳低電平平時
MPU_Write_Byte(MPU6050_RA_INT_ENABLE,0x40); //中斷使能寄存器
}
void Free_Fall_Interrupt(void) //自由落體中斷
{
MPU_Write_Byte(MPU6050_RA_FF_THR,0x01); //自由落體門檻值
MPU_Write_Byte(MPU6050_RA_FF_DUR,0x01); //自由落體檢測時間20ms 機關1ms 寄存器0X20
}
void Motion_Interrupt(void) //運動中斷
{
MPU_Write_Byte(MPU6050_RA_MOT_THR,0x01); //運動門檻值
MPU_Write_Byte(MPU6050_RA_MOT_DUR,0x14); //檢測時間20ms 機關1ms 寄存器0X20
}
void Zero_Motion_Interrupt(void) //靜止中斷
{
MPU_Write_Byte(MPU6050_RA_ZRMOT_THR,0x20); //靜止門檻值
MPU_Write_Byte(MPU6050_RA_ZRMOT_DUR,0x20); //靜止檢測時間20ms 機關1ms 寄存器0X20
}
應用層調用代碼:
MPU_Init();
MPU_INT_Init();
進入低功耗:
MPU_Set_Low_power();
中斷配置關鍵位置:
MPU_Write_Byte(MPU6050_RA_CONFIG,0×04); //配置外部引腳采樣和DLPF數字低通濾波器
資料就緒中斷使能中斷配置MPU_Write_Byte(MPU6050_RA_CONFIG,0x06); //此次我開啟加速度與陀螺儀
運動檢測中斷配置MPU_Write_Byte(MPU6050_RA_CONFIG,0x04); //開啟加速度
/ *配置外部引腳采樣和DLPF數字低通濾波器* /
#define MPU6050_RA_CONFIG 0x1A
// bit5-bit3一個連接配接到FSYNC端口的外部信号可以通過配置EXT_SYNC_SET來采樣
//也就是說,這裡設定之後,FSYNC的電平0或1進入最終資料
寄存器,具體如下// 0不使用
// 1 FSYNC電平進入所有資料
寄存器
// 2 FSYNC電平進入GYRO_XOUT_L // 3 FSYNC電平進入GYRO_YOUT_L
// 4 FSYNC電平進入GYRO_ZOUT_L
// 5 FSYNC電平進入ACCEL_XOUT_L
// 6 FSYNC電平進入ACCEL_YOUT_L
// 7 FSYNC電平進入SYNC_ACCEL_ZOUT_L
// bit2-bit0數字低通濾波器用于濾除高頻幹擾高于這個頻率的幹擾被濾除掉
/ *對應關系如下
* * | 加速度傳感器| 陀螺儀
* * DLPF_CFG | 帶寬| 延遲| 帶寬| 延遲| 采樣率
* ------------- + -------- + ------- + -------- + ------ + - -----------
* 0 | 260Hz | 0ms | 256Hz | 0.98ms | 8kHz
* 1 | 184Hz | 2.0ms | 188Hz | 1.9ms | 1kHz
* 2 | 94Hz | 3.0ms | 98Hz | 2.8ms | 1kHz
* 3 | 44Hz | 4.9ms | 42Hz | 4.8ms | 1kHz
* 4 | 21Hz | 8.5ms | 20Hz | 8.3ms | 1kHz
* 5 | 10Hz | 13.8ms | 10Hz | 13.4ms | 1kHz
* 6 | 5Hz | 19.0ms | 5Hz | 18.6ms | 1kHz
* 7 | 保留| 保留| 保留
* * /
其他代碼:
//設定MPU6050陀螺儀傳感器滿量程範圍
//fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
//傳回值:0,設定成功
// 其他,設定失敗
uint8_t MPU_Set_Gyro_Fsr(uint8_t fsr)
{
return MPU_Write_Byte(MPU6050_RA_GYRO_CONFIG,fsr<<3); //設定陀螺儀滿量程範圍
}
//設定MPU6050加速度傳感器滿量程範圍
//fsr:0,±2g;1,±4g;2,±8g;3,±16g
//傳回值:0,設定成功
// 其他,設定失敗
uint8_t MPU_Set_Accel_Fsr(uint8_t fsr)
{
return MPU_Write_Byte(MPU6050_RA_ACCEL_CONFIG,fsr<<3); //設定加速度傳感器滿量程範圍
}
//設定MPU6050的數字低通濾波器
//lpf:數字低通濾波頻率(Hz)
//傳回值:0,設定成功
// 其他,設定失敗
uint8_t MPU_Set_LPF(uint16_t lpf)
{
uint8_t data=0;
if(lpf>=188) data=1;
else if(lpf>=98) data=2;
else if(lpf>=42) data=2;
else if(lpf>=42) data=3;
else if(lpf>=20) data=4;
else if(lpf>=10) data=5;
else data=6;
return MPU_Write_Byte(MPU6050_RA_CONFIG,data); //設定數字低通濾波器
}
//設定MPU6050的采樣率(假定Fs=1KHz)
//rate:4~1000(Hz)
//傳回值:0,設定成功
// 其他,設定失敗
uint8_t MPU_Set_Rate(uint16_t rate)
{
uint8_t data;
if(rate>1000)rate=1000;
if(rate<4)rate=4;
data=1000/rate-1;
data=MPU_Write_Byte(MPU6050_RA_SMPLRT_DIV,data); //設定數字低通濾波器
return MPU_Set_LPF(rate/2); //自動設定LPF為采樣率的一半
}
//IIC寫一個位元組
//reg: 寄存器位址
//data: 資料
//傳回值: 0,正常
// 其他,錯誤代碼
uint8_t MPU_Write_Byte(uint8_t reg,uint8_t data)
{
IIC_Start();
IIC_Send_Byte((MPU_ADDR<<1)|0);//發送器件位址+寫指令
if(IIC_Wait_Ack()) //等待應答
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg); //寫寄存器位址
IIC_Wait_Ack(); //等待應答
IIC_Send_Byte(data);//發送資料
if(IIC_Wait_Ack()) //等待ACK
{
IIC_Stop();
return 1;
}
IIC_Stop();
return 0;
}
//IIC讀一個位元組
//reg:寄存器位址
//傳回值:讀到的資料
uint8_t MPU_Read_Byte(uint8_t reg)
{
uint8_t res;
IIC_Start();
IIC_Send_Byte((MPU_ADDR<<1)|0);//發送器件位址+寫指令
IIC_Wait_Ack();//等待應答
IIC_Send_Byte(reg);//寫寄存器位址
IIC_Wait_Ack();//等待應答
IIC_Start();
IIC_Send_Byte((MPU_ADDR<<1)|1);//發送期間位址+讀指令
IIC_Wait_Ack();//等待應答
res=IIC_Read_Byte(0);//讀取資料,發送nACK
IIC_Stop();//産生一個停止條件
return res;
}
//IIC連續寫
//addr:器件位址
//reg: 寄存器位址
//len: 寫入長度
//buf: 資料區
//傳回值: 0,正常
// 其他,錯誤代碼
uint8_t MPU_Write_Len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
{
uint8_t i;
IIC_Start();
IIC_Send_Byte((addr<<1)|0);//發送器件位址+寫指令
if(IIC_Wait_Ack())//等待應答
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg);//寫寄存器位址
IIC_Wait_Ack();//等待應答
for(i=0;i<len;i++)
{
IIC_Send_Byte(buf[i]);//發送資料
if(IIC_Wait_Ack())//等待ACK
{
IIC_Stop();
return 1;
}
}
IIC_Stop();
return 0;
}
//IIC連續讀
//addr:器件位址
//reg:要讀取的寄存器位址
//len:要讀取得長度
//buf:讀取到的資料存儲區
//傳回值: 0,正常
// 其他,錯誤代碼
uint8_t MPU_Read_Len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
{
IIC_Start();
IIC_Send_Byte((addr<<1)|0);//發送器件位址+寫指令
if(IIC_Wait_Ack())//等待應答
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg);//寫寄存器位址
IIC_Wait_Ack();//等待應答
IIC_Start();
IIC_Send_Byte((addr<<1)|1);//發送器件位址+讀指令
IIC_Wait_Ack();//等待應答
while(len)
{
if(len==1) *buf=IIC_Read_Byte(0);//讀資料,發送nACK
else *buf=IIC_Read_Byte(1);//讀資料,發送ACK
len--;
buf++;
}
IIC_Stop();//産生一個停止條件
return 0;
}
//得到溫度值
//傳回值:溫度值(擴大了100倍)
short MPU_Get_Temperature(void)
{
uint8_t buf[2];
short raw;
float temp;
MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf);
raw=((uint16_t)buf[0]<<8)|buf[1];
temp=36.53+((double)raw)/340;
return temp*100;
}
//得到陀螺儀值(原始值)
//gx,gy,gz:陀螺儀x,y,z軸的原始讀數(帶符号)
//傳回值:0,成功
// 其他,錯誤代碼
uint8_t MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
{
uint8_t buf[6],res;
res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);
if(res==0)
{
*gx=((uint16_t)buf[0]<<8)|buf[1];
*gy=((uint16_t)buf[2]<<8)|buf[3];
*gz=((uint16_t)buf[4]<<8)|buf[5];
}
return res;
}
//得到加速度值(原始值)
//ax,ay,az:陀螺儀x,y,z軸的原始讀數(帶符号)
//傳回值:0,成功
// 其他,錯誤代碼
uint8_t MPU_Get_Accelerometer(short *ax,short *ay,short *az)
{
uint8_t buf[6],res;
res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);
if(res==0)
{
*ax=((uint16_t)buf[0]<<8)|buf[1];
*ay=((uint16_t)buf[2]<<8)|buf[3];
*az=((uint16_t)buf[4]<<8)|buf[5];
}
return res;;
}