技术标签: NUC970(ARM9) CortexM3(STM32) MPU6050 MPU60X0
使用的模拟IIC接口驱动的MPU6050,最后使用官方的mpu_dmp计算的最终数据存在偏移,估计是没有电子罗盘进行校准,时间长了方向偏移特别严重。
//MPU6050
/*************************************************************************************************************
* 文件名: MPU6050.c
* 功能: MPU6050驱动
* 作者: [email protected]
* 邮箱: [email protected]
* 创建时间: 2020-10-19
* 最后修改时间:2020-10-19
* 详细:
*************************************************************************************************************/
#include "SYSTEM.h"
#include "MPU6050.h"
#include "SoftwareIIC.h"
/*************************************************************************************************************************
*函数 : bool MPU6050_Init((MPU6050_HANDLE *pHandle, u8 SlaveAddr)
*功能 : MPU6050初始化
*参数 : pHandle:句柄;SlaveAddr:芯片IIC地址
*返回 : TRUE:初始化成功;FALSE:初始化失败
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-19
*最后修改时间 : 2020-10-19
*说明 : 需要先初始化IIC
*************************************************************************************************************************/
bool MPU6050_Init(MPU6050_HANDLE *pHandle, u8 SlaveAddr)
{
u8 id;
if(pHandle == NULL)
{
DEBUG("无效的句柄\r\n");
SYS_DelayMS(5000);
return FALSE;
}
pHandle->SlaveAddr = SlaveAddr; //记录通讯地址
MPU6050_WriteOneReg(pHandle, MPU6050_PWR_MGMT1_REG,0X80); //复位MPU6050
SYS_DelayMS(100);
MPU6050_WriteOneReg(pHandle, MPU6050_PWR_MGMT1_REG,0X00); //唤醒MPU6050
MPU6050_SetGyroFS(pHandle, MP6050_GYRO_FS_SEL_500); //MPU6050陀螺仪量程设置
MPU6050_SetAccelFS(pHandle, MP6050_ACCEL_FS_SEL_2g); //MPU6050加速度量程设置
MPU6050_SetRate(pHandle, 50); //设置采样率
MPU6050_WriteOneReg(pHandle, MPU6050_INT_EN_REG,0X00); //关闭所有中断
MPU6050_WriteOneReg(pHandle, MPU6050_USER_CTRL_REG,0X00); //I2C主模式关闭
MPU6050_WriteOneReg(pHandle, MPU6050_FIFO_EN_REG,0X00); //关闭FIFO
MPU6050_WriteOneReg(pHandle, MPU6050_INTBP_CFG_REG,0X80); //INT引脚低电平有效-此处并未使用INT
if(MPU6050_ReadOneReg(pHandle, MPU6050_DEVICE_ID_REG, &id) == FALSE)
{
DEBUG("MPU6050初始化失败,读取芯片ID失败\r\n");
return FALSE;
}
if(id==MPU6050_ADDR)//器件ID正确
{
MPU6050_WriteOneReg(pHandle, MPU6050_PWR_MGMT1_REG,0X01); //设置CLKSEL,PLL X轴为参考
MPU6050_WriteOneReg(pHandle, MPU6050_PWR_MGMT2_REG,0X00); //加速度与陀螺仪都工作
MPU6050_SetRate(pHandle, 50); //设置采样率为50Hz
uart_printf("MPU6050初始化成功,ID:0x%X\r\n", id);
return TRUE;
}
else
{
DEBUG("MPU6050初始化失败,无效的ID:0x%d\r\n", id);
return FALSE;
}
}
/*************************************************************************************************************************
*函数 : bool MPU6050_SetGyroFS(MPU6050_HANDLE *pHandle, MP6050_GYRO_FS fs)
*功能 : MPU6050陀螺仪量程设置
*参数 : pHandle:句柄;fs:量程设置,见MP6050_GYRO_FS
*返回 : 无
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-19
*最后修改时间 : 2020-10-19
*说明 :
*************************************************************************************************************************/
void MPU6050_SetGyroFS(MPU6050_HANDLE *pHandle, MP6050_GYRO_FS fs)
{
MPU6050_WriteOneReg(pHandle, MPU6050_GYRO_CFG_REG,(fs&0x03) << 3);
}
/*************************************************************************************************************************
*函数 : bool MPU6050_SetGyroFS(MPU6050_HANDLE *pHandle, MP6050_ACCEL_FS fs)
*功能 : MPU6050加速度量程设置
*参数 : pHandle:句柄;fs:量程设置,见MP6050_ACCEL_FS
*返回 : 无
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-19
*最后修改时间 : 2020-10-19
*说明 : 会关闭滤波器
*************************************************************************************************************************/
void MPU6050_SetAccelFS(MPU6050_HANDLE *pHandle, MP6050_ACCEL_FS fs)
{
MPU6050_WriteOneReg(pHandle, MPU6050_ACCEL_CFG_REG,(fs&0x03) << 3);
}
/*************************************************************************************************************************
*函数 : void MPU6050_SetRate(MPU6050_HANDLE *pHandle, u16 rate)
*功能 : MPU6050设置采样率
*参数 : pHandle:句柄;rate:采样率4-1000Hz
*返回 : 无
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-19
*最后修改时间 : 2020-10-19
*说明 : 需要将DLPF启用,将陀螺仪输出速率固定为1KHz
*************************************************************************************************************************/
void MPU6050_SetRate(MPU6050_HANDLE *pHandle, u16 rate)
{
u8 data;
if(rate>1000) rate=1000; //限制为4-1000Hz
if(rate<4) rate=4;
data=1000/rate-1;
MPU6050_WriteOneReg(pHandle, MPU6050_SAMPLE_DIV_REG, data);
MPU6050_SetDLPF(pHandle, rate/2); //MPU6050数字低通滤波器设置-设置为采样率的1/2
}
/*************************************************************************************************************************
*函数 : void MPU6050_SetDLPF(MPU6050_HANDLE *pHandle, u16 dlpf)
*功能 : MPU6050数字低通滤波器设置
*参数 : pHandle:句柄;rate:采样率4-1000Hz
*返回 : 无
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-19
*最后修改时间 : 2020-10-19
*说明 : DLPF_CFG = 1-6 对应FS频率为1KHz
*************************************************************************************************************************/
void MPU6050_SetDLPF(MPU6050_HANDLE *pHandle, u16 dlpf)
{
u8 data;
if(dlpf>=188)data=1;
else if(dlpf>=98)data=2;
else if(dlpf>=42)data=3;
else if(dlpf>=20)data=4;
else if(dlpf>=10)data=5;
else data=6;
MPU6050_WriteOneReg(pHandle, MPU6050_CFG_REG, data);
}
/*************************************************************************************************************************
*函数 : bool MPU6050_ReadOneReg(MPU6050_HANDLE *pHandle,u8 RegAddr, u8 *pData)
*功能 : MPU6050读取一个寄存器
*参数 : pHandle:句柄;RegAddr:寄存器地址;pData:寄存器值
*返回 : TRUE:读取成功;FALSE:读取失败
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-19
*最后修改时间 : 2020-10-19
*说明 :
*************************************************************************************************************************/
bool MPU6050_ReadOneReg(MPU6050_HANDLE *pHandle,u8 RegAddr, u8 *pData)
{
SIIC_Start(&pHandle->IIC_Handle); //产生IIC起始信号
if(SIIC_SendByte(&pHandle->IIC_Handle, pHandle->SlaveAddr) == FALSE) //发送设备地址+写信号
{
DEBUG("没有收到ACK\r\n");
return FALSE;
}
SIIC_SendByte(&pHandle->IIC_Handle, RegAddr); //发送寄存器地址
SIIC_Start(&pHandle->IIC_Handle); //产生IIC起始信号
SIIC_SendByte(&pHandle->IIC_Handle, pHandle->SlaveAddr|BIT0); //发送设备地址+读信号
*pData = SIIC_ReadByte(&pHandle->IIC_Handle, TRUE); //SIIC读取一个字节
SIIC_Stop(&pHandle->IIC_Handle); //产生IIC停止信号
return TRUE;
}
/*************************************************************************************************************************
*函数 : bool MPU6050_ReadMultReg(MPU6050_HANDLE *pHandle,u8 RegAddr, u8 RegNum, u8 DataBuff[])
*功能 : MPU6050读取多个寄存器
*参数 : pHandle:句柄;RegAddr:寄存器地址;RegNum:寄存器数量;DataBuff:返回结果缓冲区
*返回 : TRUE:读取成功;FALSE:读取失败
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-19
*最后修改时间 : 2020-10-19
*说明 :
*************************************************************************************************************************/
bool MPU6050_ReadMultReg(MPU6050_HANDLE *pHandle,u8 RegAddr, u8 RegNum, u8 DataBuff[])
{
u8 i;
SIIC_Start(&pHandle->IIC_Handle); //产生IIC起始信号
if(SIIC_SendByte(&pHandle->IIC_Handle, pHandle->SlaveAddr) == FALSE) //发送设备地址+写信号
{
DEBUG("没有收到ACK\r\n");
return FALSE;
}
SIIC_SendByte(&pHandle->IIC_Handle, RegAddr); //发送寄存器地址
SIIC_Start(&pHandle->IIC_Handle); //产生IIC起始信号
SIIC_SendByte(&pHandle->IIC_Handle, pHandle->SlaveAddr|BIT0); //发送设备地址+读信号
for(i = 0;i < RegNum;i ++)
{
if(i == (RegNum-1)) //最后一字节不响应ACK
{
DataBuff[i] = SIIC_ReadByte(&pHandle->IIC_Handle, FALSE); //SIIC读取一个字节-NAK
}
else
{
DataBuff[i] = SIIC_ReadByte(&pHandle->IIC_Handle, TRUE); //SIIC读取一个字节-ACK
}
}
SIIC_Stop(&pHandle->IIC_Handle); //产生IIC停止信号
return TRUE;
}
/*************************************************************************************************************************
*函数 : void MPU6050_WriteOneReg(MPU6050_HANDLE *pHandle,u8 RegAddr,u8 data)
*功能 : MPU6050写一个寄存器
*参数 : pHandle:句柄;RegAddr:寄存器地址;data:要写入的值
*返回 : TRUE:成功;FALSE:失败
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-19
*最后修改时间 : 2020-10-19
*说明 :
*************************************************************************************************************************/
bool MPU6050_WriteOneReg(MPU6050_HANDLE *pHandle,u8 RegAddr,u8 data)
{
SIIC_Start(&pHandle->IIC_Handle); //产生IIC起始信号
if(SIIC_SendByte(&pHandle->IIC_Handle, pHandle->SlaveAddr) == FALSE) //发送设备地址+写信号
{
DEBUG("没有收到ACK\r\n");
return FALSE;
}
SIIC_SendByte(&pHandle->IIC_Handle, RegAddr); //发送寄存器地址
SIIC_SendByte(&pHandle->IIC_Handle, data); //发送要写入的数据
SIIC_Stop(&pHandle->IIC_Handle); //产生IIC停止信号
return FALSE;
}
/*************************************************************************************************************************
*函数 : bool MPU6050_WriteMultReg(MPU6050_HANDLE *pHandle,u8 RegAddr, u8 RegNum, u8 DataBuff[])
*功能 : MPU6050写多个寄存器
*参数 : pHandle:句柄;RegAddr:寄存器地址;RegNum:寄存器数量;DataBuff:要写入的数据
*返回 : TRUE:成功;FALSE:失败
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-20
*最后修改时间 : 2020-10-20
*说明 :
*************************************************************************************************************************/
bool MPU6050_WriteMultReg(MPU6050_HANDLE *pHandle,u8 RegAddr, u8 RegNum, u8 DataBuff[])
{
u8 i;
SIIC_Start(&pHandle->IIC_Handle); //产生IIC起始信号
if(SIIC_SendByte(&pHandle->IIC_Handle, pHandle->SlaveAddr) == FALSE) //发送设备地址+写信号
{
DEBUG("没有收到ACK\r\n");
return FALSE;
}
SIIC_SendByte(&pHandle->IIC_Handle, RegAddr); //发送寄存器地址
for(i = 0;i < RegNum;i ++)
{
if(SIIC_SendByte(&pHandle->IIC_Handle, DataBuff[i]) == FALSE)
{
SIIC_Stop(&pHandle->IIC_Handle); //产生IIC停止信号
return FALSE;
}
}
SIIC_Stop(&pHandle->IIC_Handle); //产生IIC停止信号
return TRUE;
}
/*************************************************************************************************************************
*函数 : bool MPU6050_GetTemper(MPU6050_HANDLE *pHandle, s16 *pTemp)
*功能 : MPU6050读取温度
*参数 : pHandle:句柄;pTemp:读取的温度值,扩大100倍
*返回 : TRUE:成功;FALSE:失败
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-20
*最后修改时间 : 2020-10-20
*说明 :
*************************************************************************************************************************/
bool MPU6050_GetTemper(MPU6050_HANDLE *pHandle, s16 *pTemp)
{
u8 buff[2];
float ftemp;
if(MPU6050_ReadMultReg(pHandle, MPU6050_TEMP_OUTH_REG, 2, buff) == FALSE) return FALSE;
ftemp = ((u16)buff[0]<<8)|buff[1];
ftemp /= 340.0f;
ftemp += 36.53f;
*pTemp = ftemp*10;
return TRUE;
}
/*************************************************************************************************************************
*函数 : bool MPU6050_GetGyroData(MPU6050_HANDLE *pHandle, s16 *gx, s16 *gy ,s16 *gz)
*功能 : MPU6050读取陀螺仪原始数据
*参数 : pHandle:句柄;gx,gy,gz:三个轴原始数据
*返回 : TRUE:成功;FALSE:失败
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-20
*最后修改时间 : 2020-10-20
*说明 :
*************************************************************************************************************************/
bool MPU6050_GetGyroData(MPU6050_HANDLE *pHandle, s16 *gx, s16 *gy ,s16 *gz)
{
u8 buff[6];
if(MPU6050_ReadMultReg(pHandle, MPU6050_GYRO_XOUTH_REG, 6, buff) == FALSE) return FALSE;
*gx=((u16)buff[0]<<8)|buff[1];
*gy=((u16)buff[2]<<8)|buff[3];
*gz=((u16)buff[4]<<8)|buff[5];
return TRUE;
}
/*************************************************************************************************************************
*函数 : bool MPU6050_GetAccelData(MPU6050_HANDLE *pHandle, s16 *ax, s16 *ay ,s16 *az)
*功能 : MPU6050读取加速度原始数据
*参数 : pHandle:句柄;ax,ay,az:三个轴原始数据
*返回 : TRUE:成功;FALSE:失败
*依赖 : 底层宏定义
*作者 : [email protected]
*时间 : 2020-10-20
*最后修改时间 : 2020-10-20
*说明 :
*************************************************************************************************************************/
bool MPU6050_GetAccelData(MPU6050_HANDLE *pHandle, s16 *ax, s16 *ay ,s16 *az)
{
u8 buff[6];
if(MPU6050_ReadMultReg(pHandle, MPU6050_ACCEL_XOUTH_REG, 6, buff) == FALSE) return FALSE;
*ax=((u16)buff[0]<<8)|buff[1];
*ay=((u16)buff[2]<<8)|buff[3];
*az=((u16)buff[4]<<8)|buff[5];
return TRUE;
}
//MPU6050.h
/*************************************************************************************************************
* 文件名: MPU6050.h
* 功能: MPU6050驱动
* 作者: [email protected]
* 邮箱: [email protected]
* 创建时间: 2020-10-19
* 最后修改时间:2020-10-19
* 详细:
*************************************************************************************************************/
#ifndef __MPU6050_H_
#define __MPU6050_H_
#include "system.h"
#include "SoftwareIIC.h"
//MPU6050 句柄
typedef struct
{
SIIC_HANDLE IIC_Handle;
u8 SlaveAddr;
}MPU6050_HANDLE;
#define MPU6050_UX_VDDIO 0x01 //MP6050 IIC空闲高电平上拉电源设置,0:VLOGIC;1:VDD 由于都是3.3V,无所谓这个值的设置
#define MPU6050_SELF_TESTX_REG 0X0D //自检寄存器X
#define MPU6050_SELF_TESTY_REG 0X0E //自检寄存器Y
#define MPU6050_SELF_TESTZ_REG 0X0F //自检寄存器Z
#define MPU6050_SELF_TESTA_REG 0X10 //自检寄存器A
#define MPU6050_SAMPLE_DIV_REG 0X19 //采样频率分频器
#define MPU6050_CFG_REG 0X1A //配置寄存器
#define MPU6050_GYRO_CFG_REG 0X1B //陀螺仪配置寄存器
#define MPU6050_ACCEL_CFG_REG 0X1C //加速度计配置寄存器
#define MPU6050_MOTION_DET_REG 0X1F //运动检测阀值设置寄存器
#define MPU6050_FIFO_EN_REG 0X23 //FIFO使能寄存器
#define MPU6050_I2CMST_CTRL_REG 0X24 //IIC主机控制寄存器
#define MPU6050_I2CSLV0_ADDR_REG 0X25 //IIC从机0器件地址寄存器
#define MPU6050_I2CSLV0_REG 0X26 //IIC从机0数据地址寄存器
#define MPU6050_I2CSLV0_CTRL_REG 0X27 //IIC从机0控制寄存器
#define MPU6050_I2CSLV1_ADDR_REG 0X28 //IIC从机1器件地址寄存器
#define MPU6050_I2CSLV1_REG 0X29 //IIC从机1数据地址寄存器
#define MPU6050_I2CSLV1_CTRL_REG 0X2A //IIC从机1控制寄存器
#define MPU6050_I2CSLV2_ADDR_REG 0X2B //IIC从机2器件地址寄存器
#define MPU6050_I2CSLV2_REG 0X2C //IIC从机2数据地址寄存器
#define MPU6050_I2CSLV2_CTRL_REG 0X2D //IIC从机2控制寄存器
#define MPU6050_I2CSLV3_ADDR_REG 0X2E //IIC从机3器件地址寄存器
#define MPU6050_I2CSLV3_REG 0X2F //IIC从机3数据地址寄存器
#define MPU6050_I2CSLV3_CTRL_REG 0X30 //IIC从机3控制寄存器
#define MPU6050_I2CSLV4_ADDR_REG 0X31 //IIC从机4器件地址寄存器
#define MPU6050_I2CSLV4_REG 0X32 //IIC从机4数据地址寄存器
#define MPU6050_I2CSLV4_DO_REG 0X33 //IIC从机4写数据寄存器
#define MPU6050_I2CSLV4_CTRL_REG 0X34 //IIC从机4控制寄存器
#define MPU6050_I2CSLV4_DI_REG 0X35 //IIC从机4读数据寄存器
#define MPU6050_I2CMST_STA_REG 0X36 //IIC主机状态寄存器
#define MPU6050_INTBP_CFG_REG 0X37 //中断/旁路设置寄存器
#define MPU6050_INT_EN_REG 0X38 //中断使能寄存器
#define MPU6050_INT_STA_REG 0X3A //中断状态寄存器
#define MPU6050_ACCEL_XOUTH_REG 0X3B //加速度值,X轴高8位寄存器
#define MPU6050_ACCEL_XOUTL_REG 0X3C //加速度值,X轴低8位寄存器
#define MPU6050_ACCEL_YOUTH_REG 0X3D //加速度值,Y轴高8位寄存器
#define MPU6050_ACCEL_YOUTL_REG 0X3E //加速度值,Y轴低8位寄存器
#define MPU6050_ACCEL_ZOUTH_REG 0X3F //加速度值,Z轴高8位寄存器
#define MPU6050_ACCEL_ZOUTL_REG 0X40 //加速度值,Z轴低8位寄存器
#define MPU6050_TEMP_OUTH_REG 0X41 //温度值高八位寄存器
#define MPU6050_TEMP_OUTL_REG 0X42 //温度值低8位寄存器
#define MPU6050_GYRO_XOUTH_REG 0X43 //陀螺仪值,X轴高8位寄存器
#define MPU6050_GYRO_XOUTL_REG 0X44 //陀螺仪值,X轴低8位寄存器
#define MPU6050_GYRO_YOUTH_REG 0X45 //陀螺仪值,Y轴高8位寄存器
#define MPU6050_GYRO_YOUTL_REG 0X46 //陀螺仪值,Y轴低8位寄存器
#define MPU6050_GYRO_ZOUTH_REG 0X47 //陀螺仪值,Z轴高8位寄存器
#define MPU6050_GYRO_ZOUTL_REG 0X48 //陀螺仪值,Z轴低8位寄存器
#define MPU6050_I2CSLV0_DO_REG 0X63 //IIC从机0数据寄存器
#define MPU6050_I2CSLV1_DO_REG 0X64 //IIC从机1数据寄存器
#define MPU6050_I2CSLV2_DO_REG 0X65 //IIC从机2数据寄存器
#define MPU6050_I2CSLV3_DO_REG 0X66 //IIC从机3数据寄存器
#define MPU6050_I2CMST_DELAY_REG 0X67 //IIC主机延时管理寄存器
#define MPU6050_SIGPATH_RST_REG 0X68 //信号通道复位寄存器
#define MPU6050_MDETECT_CTRL_REG 0X69 //运动检测控制寄存器
#define MPU6050_USER_CTRL_REG 0X6A //用户控制寄存器
#define MPU6050_PWR_MGMT1_REG 0X6B //电源管理寄存器1
#define MPU6050_PWR_MGMT2_REG 0X6C //电源管理寄存器2
#define MPU6050_FIFO_CNTH_REG 0X72 //FIFO计数寄存器高八位
#define MPU6050_FIFO_CNTL_REG 0X73 //FIFO计数寄存器低八位
#define MPU6050_FIFO_RW_REG 0X74 //FIFO读写寄存器
#define MPU6050_DEVICE_ID_REG 0X75 //器件ID寄存器
//如果AD0脚(9脚)接地,IIC地址为0X68(不包含最低位).
//如果接V3.3,则IIC地址为0X69(不包含最低位).
#define MPU6050_ADDR 0X68
//陀螺仪满量程设置
typedef enum
{
MP6050_GYRO_FS_SEL_250 = 0, //±250°/s
MP6050_GYRO_FS_SEL_500 = 1, //±500°/s
MP6050_GYRO_FS_SEL_1000 = 2, //±1000°/s
MP6050_GYRO_FS_SEL_2000 = 3, //±2000°/s
}MP6050_GYRO_FS;
//加速度传感器满量程设置
typedef enum
{
MP6050_ACCEL_FS_SEL_2g = 0, //±2g
MP6050_ACCEL_FS_SEL_4g = 1, //±4g
MP6050_ACCEL_FS_SEL_8g = 2, //±8g
MP6050_ACCEL_FS_SEL_16g = 3, //±16g
}MP6050_ACCEL_FS;
bool MPU6050_Init(MPU6050_HANDLE *pHandle, u8 SlaveAddr); //MPU6050初始化
void MPU6050_SetGyroFS(MPU6050_HANDLE *pHandle, MP6050_GYRO_FS fs); //MPU6050陀螺仪量程设置
void MPU6050_SetAccelFS(MPU6050_HANDLE *pHandle, MP6050_ACCEL_FS fs); //MPU6050加速度量程设置
void MPU6050_SetRate(MPU6050_HANDLE *pHandle, u16 rate); //MPU6050设置采样率
void MPU6050_SetDLPF(MPU6050_HANDLE *pHandle, u16 dlpf); //MPU6050数字低通滤波器设置
bool MPU6050_GetTemper(MPU6050_HANDLE *pHandle, s16 *pTemp); //MPU6050读取温度
bool MPU6050_GetGyroData(MPU6050_HANDLE *pHandle, s16 *gx, s16 *gy ,s16 *gz); //MPU6050读取陀螺仪原始数据
bool MPU6050_GetAccelData(MPU6050_HANDLE *pHandle, s16 *ax, s16 *ay ,s16 *az); //MPU6050读取加速度原始数据
bool MPU6050_ReadOneReg(MPU6050_HANDLE *pHandle,u8 RegAddr, u8 *pData); //MPU6050读取一个寄存器
bool MPU6050_ReadMultReg(MPU6050_HANDLE *pHandle,u8 RegAddr, u8 RegNum, u8 DataBuff[]); //MPU6050读取多个寄存器
bool MPU6050_WriteOneReg(MPU6050_HANDLE *pHandle,u8 RegAddr,u8 data); //MPU6050写一个寄存器
bool MPU6050_WriteMultReg(MPU6050_HANDLE *pHandle,u8 RegAddr, u8 RegNum, u8 DataBuff[]); //MPU6050写多个寄存器
#endif //__MPU6050_H_
//官方数据融合所需接口
/*************************************************************************************************************
* 文件名: inv_mpu_interface.c
* 功能: MPU6050 dmp数据融合所需接口
* 作者: [email protected]
* 邮箱: [email protected]
* 创建时间: 2020-10-20
* 最后修改时间:2020-10-20
* 详细:
*************************************************************************************************************/
#include "typedef.h"
#include "inv_mpu_interface.h"
#include "mpu6050.h"
MPU6050_HANDLE g_MPU6050_Handle;
//IIC写数据接口(返回0:正常)
int i2c_write(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char const *data)
{
if(MPU6050_WriteMultReg(&g_MPU6050_Handle, reg_addr, length, (u8*)data) == TRUE) return 0;
else return 1;
}
//IIC读取数据接口(返回0:正常)
int i2c_read(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char *data)
{
if(MPU6050_ReadMultReg(&g_MPU6050_Handle, reg_addr, length, data) == TRUE) return 0;
else return 1;
}
//获取时间戳,单位ms
void get_ms(unsigned long *time)
{
unsigned long t = SYS_GetOSRunTime();
*time = t;
}
//延时接口
void delay_ms(u32 ms)
{
SYS_DelayMS(ms);
}
数据融合测试
//mpu6050测试
void mpu6050_test(void)
{
s16 Temp;
s16 GyroData[3];
s16 AccelData[3];
SIIC_Init(&g_MPU6050_Handle.IIC_Handle, GPIOG, GPIOG, 0, 1, 10); //软件IIC初始化
while(MPU6050_Init(&g_MPU6050_Handle, 0xD0) == FALSE) //MPU6050初始化
{
Sleep(1000);
}
if(MPU6050_GetTemper(&g_MPU6050_Handle, &Temp) == TRUE) //MPU6050读取温度
{
uart_printf("[MP6050]温度:%s%d.%02d℃\r\n",(Temp<0)?"-":"", abs(Temp)/100, abs(Temp)%100);
}
else
{
uart_printf("[MP6050]温度:ERROR\r\n");
}
if(MPU6050_GetGyroData(&g_MPU6050_Handle, &GyroData[0], &GyroData[1] , &GyroData[2]) == TRUE) //MPU6050读取陀螺仪原始数据
{
uart_printf("[MP6050]陀螺仪:%d %d %d\r\n", GyroData[0],GyroData[1],GyroData[2]);
}
else
{
uart_printf("[MP6050]陀螺仪:ERROR\r\n");
}
if(MPU6050_GetAccelData(&g_MPU6050_Handle, &AccelData[0], &AccelData[1] , &AccelData[2]) == TRUE) //MPU6050读取加速度原始数据
{
uart_printf("[MP6050]加速度:%d %d %d\r\n", AccelData[0],AccelData[1],AccelData[2]);
}
else
{
uart_printf("[MP6050]加速度:ERROR\r\n");
}
//数据融合测试
while(mpu_dmp_init())
{
uart_printf("mpu_dmp_init error\r\n");
Sleep(1000);
}
while(1)
{
if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)
{
uart_printf("俯仰角:%f ", pitch);
uart_printf("横滚角:%f ", roll);
uart_printf("航向角:%f \r\n", yaw);
}
Sleep(300);
}
}
文章浏览阅读3.5k次。C++ dll库只生成dll文件,而未生成lib文件,问题在于没有在接口函数前面加上前缀__declspec(dllexport)在VS的工程中,此前缀常常被宏定义为:工程名_API#ifdef RADONCUDA_EXPORTS#define RADONCUDA_API __declspec(dllexport)#else#define RADONCUDA_API __declspec..._c++生成dll的同时没有lib
文章浏览阅读846次。转载:https://github.com/Meituan-Dianping/walleWalle瓦力,Android Signature V2 Scheme签名下的新一代渠道包打包神器瓦力通过在Apk中的APK Signature Block区块添加自定义的渠道信息来生成渠道包,从而提高了渠道包生成效率,可以作为单机工具来使用,也可以部署在HTTP服务器上来实时处理渠道包Apk的升级网络请求。Q..._android walle打包原理
文章浏览阅读4.9k次。更好的阅读体验欢迎访问博客白嫖5T空间Onedrive并搭建下载站前言白嫖一个微软E5账号不仅能自己使用office全家桶,还能造福25个小伙伴,何乐而不为?这里借助onedirve的API和oneindexN项目搭建一个5T空间的公共下载站。一、获得E5账号打开Microsoft 365开发者中心点击立即加入,登陆或注册即可。公司和语言随便填写,填写信息时请自备科学上网工具,如果出现“由于存在大量请求,此服务暂时不可用”提示,需要换个时间或者换个账号再试。注册完成后打开OneDrive管理中_企业内部下载站搭建
文章浏览阅读2.1k次。2015年微信排行榜 body,.header,.header *,.com *,.tj_box *,.btnbox *{margin:0;padding:0;} .header,.header ul,.com ul,.tj_box ul,.btnbox ul,.header,.header li,.com li,.tj_box li,.btnbox li{list_top.indextool.xx()
文章浏览阅读506次,点赞24次,收藏5次。AI写作生成器作为一种高效的文本创造工具,在各行业中得以广泛应用。尽管它可提高工作效率与节约成本,但亦存在显著弊端。此文将多方面解析这一弊处,并探讨或许产生的不良后果。1.缺乏人文情感尽管人工智能撰写的文章生成器能够快速生成海量文本
文章浏览阅读817次,点赞18次,收藏26次。在此基础上,结合现有兽医站体系的特点,运用新技术,构建了以springboot为基础的兽医站信息化管理体系。首先,以需求为依据,根据需求分析结果进行了系统的设计,并将其划分为管理员和员工二种角色和多个主要模块:员工、考勤签到、动物类型、动物信息、动物日常、观察记录、健康检测、记录存档等。使用目前市场主流的技术springboot框架进行项目构建,基于B/S架构开发模式,使用Java开发语言和MySQL数据库对系统进行高内聚低耦合的设计,最终完成了兽医站管理系统的实现。
文章浏览阅读6.2k次,点赞5次,收藏23次。在Django框架开发中,request对象就是用来处理GET\POST请求的关键对象,而Flask框架也是一样的。下面来看看request对象的常用方法。request对象的常用方法request对象的导入:from flask import requestFlask 框架中的 request 对象保存了一次HTTP请求的一切信息。那么这个HTTP请求中可能会是GET..._request.files.get
文章浏览阅读8.2k次,点赞8次,收藏52次。作为一个前端初学者,公司项目中前端需要一个带分步式的进度条,查查Element-ui和Ant design Vue都只有_vue分段式进度条
文章浏览阅读494次。1.在adapter中:private RecyclerView rv;@Overridepublic void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); rv = recyclerView;}public_.rvonitemclicklistener.onclick(int)
文章浏览阅读605次,点赞12次,收藏27次。图文大模型量化部署
文章浏览阅读9.4k次,点赞12次,收藏82次。点击回顾之前的文章:《英飞凌 AURIX 系列单片机的HSM详解(1)——何为HSM》《英飞凌 AURIX 系列单片机的HSM详解(2)——与HSM相关的UCB和寄存器》本文以TC397为例,来介绍一下HSM的开发方法。1. 编译器HSM开发时分两个工程,一个工程是编译Tricore内核代码的,用到的编译器是Tasking for Tricore;另一个工程是编译HSM的ARM Cortex-M3内核的,用的是Tasking ARM for HSM。各个版本可以在下面Tasking的官网上找到_tc397 hsm
文章浏览阅读5.2k次,点赞27次,收藏80次。指向函数的指针详解,以及如何使用指向函数的指针变量做函数参数。指向函数的指针作为函数参数,是 C 语言实际应用中的一个比较深入的部分。_指向函数的指针