MPU6050的STM32数据读取

news2024/11/23 17:15:18

目录

  • 1. 概述
  • 2. STM32G030对MPU6050的读取
  • 3. STM32F1xx对MPU6050的读取

1. 概述

项目中,往往需要根据不同的环境使用不同的芯片处理某些数据,当使用不同的芯片对六轴陀螺仪芯片MPU6050进行数据处理中,硬件的连接、I/O口的设置往往需要根据相应的情况进行处理。

2. STM32G030对MPU6050的读取

开发环境: STM32CubeIDE
芯片型号:STM32G031F8P6

在这里插入图片描述

时钟配置,不使用外部时钟

在这里插入图片描述

定时器配置,1ms中断,陀螺仪dt = 20ms

在这里插入图片描述

开启串口2

在这里插入图片描述

文件列表

在这里插入图片描述

my_iic.c 文件

#include "my_delay.h"
#include "main.h"
#include "my_iic.h"


void i2c_NAck(void);
void  i2c_Ack(void);

#define       I2C_SCL_1()         	   	HAL_GPIO_WritePin(GPIOB, IIC_SCL_Pin, 1)   //SCL=1
#define       I2C_SCL_0()           	 	HAL_GPIO_WritePin(GPIOB, IIC_SCL_Pin, 0)   //SCL=0

#define       I2C_SDA_1()           	HAL_GPIO_WritePin(GPIOB, IIC_SDA_Pin, 1)  //SDA=1
#define       I2C_SDA_0()           	HAL_GPIO_WritePin(GPIOB, IIC_SDA_Pin, 0)  //SDA=0

#define       I2C_SDA_READ()       HAL_GPIO_ReadPin(GPIOB, IIC_SDA_Pin)   //读数据线状态

#define  		 I2C_WR	 					 0
#define   	 I2C_RD	  					 1



//延时 64MHz 频率慢一些,72MHz设置为10
static void i2c_Delay(void)
{
	for (int i = 0; i < 9; i++);
}
/*
 * IIC start 发起总线起始信号
 *
 * */
void i2c_Start(void)
{
	I2C_SDA_1();
	I2C_SCL_1();
	i2c_Delay();
	I2C_SDA_0();
	i2c_Delay();
	I2C_SCL_0();
	i2c_Delay();
}
//停止信号
void i2c_Stop(void)
{
	I2C_SDA_0();
	I2C_SCL_1();
	i2c_Delay();
	I2C_SDA_1();
}
//字节发送
void i2c_SendByte(uint8_t _ucByte)
{
	uint8_t i;

	for (i = 0; i < 8; i++)
	{
		if (_ucByte & 0x80)
		{
			I2C_SDA_1();
		}
		else
		{
			I2C_SDA_0();
		}
		i2c_Delay();
		I2C_SCL_1();
		i2c_Delay();
		I2C_SCL_0();
		if (i == 7)
		{
			 I2C_SDA_1();
		}
		_ucByte <<= 1;
		i2c_Delay();
	}
}
//字节读取
uint8_t  i2c_ReadByte(uint8_t ack)
{
	uint8_t i;
	uint8_t value;

	value = 0;
	for (i = 0; i < 8; i++)
	{
		value <<= 1;
		I2C_SCL_1();
		i2c_Delay();
		if (I2C_SDA_READ())
		{
			value++;
		}
		I2C_SCL_0();
		i2c_Delay();
	}
	if(ack==0)
		i2c_NAck();
	else
		i2c_Ack();
	return value;
}
//等待
uint8_t i2c_WaitAck(void)
{
	uint8_t re;

	I2C_SDA_1();	/* CPUÊÍ·ÅSDA×ÜÏß */
	i2c_Delay();
	I2C_SCL_1();	/* CPUÇý¶¯SCL = 1, ´ËʱÆ÷¼þ»á·µ»ØACKÓ¦´ð */
	i2c_Delay();
	if (I2C_SDA_READ())	/* CPU¶ÁÈ¡SDA¿ÚÏß״̬ */
	{
		re = 1;
	}
	else
	{
		re = 0;
	}
	I2C_SCL_0();
	i2c_Delay();
	return re;
}
//ACK
void  i2c_Ack(void)
{
	I2C_SDA_0();	/* CPUÇý¶¯SDA = 0 */
	i2c_Delay();
	I2C_SCL_1();	/* CPU²úÉú1¸öʱÖÓ */
	i2c_Delay();
	I2C_SCL_0();
	i2c_Delay();
	I2C_SDA_1();	/* CPUÊÍ·ÅSDA×ÜÏß */
}
//NACK
void i2c_NAck(void)
{
	I2C_SDA_1();	/* CPUÇý¶¯SDA = 1 */
	i2c_Delay();
	I2C_SCL_1();	/* CPU²úÉú1¸öʱÖÓ */
	i2c_Delay();
	I2C_SCL_0();
	i2c_Delay();
}
//检查
uint8_t i2c_CheckDevice(uint8_t _Address)
{
	uint8_t ucAck;
	i2c_Stop();

	i2c_Start();

	i2c_SendByte(_Address|I2C_WR);
	ucAck = i2c_WaitAck();

	i2c_Stop();

	return ucAck;
}

my_iic.h 文件

void i2c_Start(void);
void i2c_Stop(void);
void i2c_SendByte(uint8_t _ucByte);
uint8_t i2c_ReadByte(uint8_t ack);
uint8_t i2c_WaitAck(void);
void i2c_Ack(void);
void i2c_NAck(void);
uint8_t i2c_CheckDevice(uint8_t _Address);
void i2c_GPIO_Config(void);

my_mpu6050.c 文件

#include "my_delay.h"
#include "main.h"
#include "my_iic.h"
#include "my_mpu6050.h"
#include "stdio.h"


写寄存器
void MPU6050_WriteReg(uint8_t reg_add,uint8_t reg_dat)
{
	i2c_Start();
	i2c_SendByte(MPU6050_SLAVE_ADDRESS);
	i2c_WaitAck();
	i2c_SendByte(reg_add);
	i2c_WaitAck();
	i2c_SendByte(reg_dat);
	i2c_WaitAck();
	i2c_Stop();
}
//读数据
void MPU6050_ReadData(uint8_t reg_add,unsigned char*Read,uint8_t num)
{
	unsigned char i;

	i2c_Start();
	i2c_SendByte(MPU6050_SLAVE_ADDRESS);
	i2c_WaitAck();
	i2c_SendByte(reg_add);
	i2c_WaitAck();

	i2c_Start();
	i2c_SendByte(MPU6050_SLAVE_ADDRESS+1);
	i2c_WaitAck();

	for(i=0;i<(num-1);i++){
		*Read=i2c_ReadByte(1);
		Read++;
	}
	*Read=i2c_ReadByte(0);
	i2c_Stop();
}

初始化
void MPU6050_Init(void)
{
  int i=0,j=0;

  for(i=0;i<1000;i++)
  {
    for(j=0;j<1000;j++)
    {
      ;
    }
  }
	MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x00);	    //½â³ýÐÝÃß״̬
	MPU6050_WriteReg(MPU6050_RA_SMPLRT_DIV , 0x07);	    //ÍÓÂÝÒDzÉÑùÂÊ£¬1KHz
	MPU6050_WriteReg(MPU6050_RA_CONFIG , 0x06);	        //µÍͨÂ˲¨Æ÷µÄÉèÖ㬽ØֹƵÂÊÊÇ1K£¬´ø¿íÊÇ5K
	MPU6050_WriteReg(MPU6050_RA_ACCEL_CONFIG , 0x00);	  //ÅäÖüÓËٶȴ«¸ÐÆ÷¹¤×÷ÔÚ2Gģʽ£¬²»×Ô¼ì
	MPU6050_WriteReg(MPU6050_RA_GYRO_CONFIG, 0x18);     //ÍÓÂÝÒÇ×Լ켰²âÁ¿·¶Î§£¬µäÐÍÖµ£º0x18(²»×Լ죬2000deg/s)
}

//读6050的ID
uint8_t MPU6050ReadID(void)
{
	unsigned char Re = 0;
    MPU6050_ReadData(MPU6050_RA_WHO_AM_I,&Re,1);    //¶ÁÆ÷¼þµØÖ·
	if(Re != 0x68)
	{
		printf("MPU6050 dectected error! --%d \r\n", Re);
		return 0;
	}
	else
	{
		printf("MPU6050 ID = %d\r\n",Re);
		return 1;
	}
}
//读加速度
void MPU6050ReadAcc(short *accData)
{
	uint8_t buf[6];
    MPU6050_ReadData(MPU6050_ACC_OUT, buf, 6);
    accData[0] = (buf[0] << 8) | buf[1];
    accData[1] = (buf[2] << 8) | buf[3];
    accData[2] = (buf[4] << 8) | buf[5];
}
//读角速度
void MPU6050ReadGyro(short *gyroData)
{
	uint8_t buf[6];
    MPU6050_ReadData(MPU6050_GYRO_OUT,buf,6);
    gyroData[0] = (buf[0] << 8) | buf[1];
    gyroData[1] = (buf[2] << 8) | buf[3];
    gyroData[2] = (buf[4] << 8) | buf[5];
}

void MPU6050ReadTemp(short *tempData)
{
	uint8_t buf[2];
    MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //¶ÁȡζÈÖµ
    *tempData = (buf[0] << 8) | buf[1];
}

void MPU6050_ReturnTemp(float *Temperature)
{
	short temp3;
	uint8_t buf[2];

	MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //¶ÁȡζÈÖµ
  temp3= (buf[0] << 8) | buf[1];
	*Temperature=((double) temp3/340.0)+36.53;


my_mpu6050.h 文件

#define MPU6050_SLAVE_ADDRESS  (0x68<<1)      //MPU6050Æ÷¼þ¶ÁµØÖ·



#define MPU6050_WHO_AM_I        0x75
#define MPU6050_SMPLRT_DIV      0  //8000Hz
#define MPU6050_DLPF_CFG        0
#define MPU6050_GYRO_OUT        0x43     //MPU6050ÍÓÂÝÒÇÊý¾Ý¼Ä´æÆ÷µØÖ·
#define MPU6050_ACC_OUT         0x3B     //MPU6050¼ÓËÙ¶ÈÊý¾Ý¼Ä´æÆ÷µØÖ·



#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_DMP_MEMORY_BANKS        8
#define MPU6050_DMP_MEMORY_BANK_SIZE    256
#define MPU6050_DMP_MEMORY_CHUNK_SIZE   16

void MPU6050ReadTemp(short *tempData);
void MPU6050ReadGyro(short *gyroData);
void MPU6050ReadAcc(short *accData);
void MPU6050_ReturnTemp(float *Temperature);
void MPU6050_Init(void);
uint8_t MPU6050ReadID(void);
void PMU6050_ReadData(uint8_t reg_add,unsigned char*Read,uint8_t num);
void PMU6050_WriteReg(uint8_t reg_add,uint8_t reg_dat);

void MPU6050_PWR_MGMT_1_INIT(void);

my_kalman.c 文件

#include "my_kalman.h"
#include "my_delay.h"
#include "main.h"
#include "my_iic.h"
#include "my_mpu6050.h"
#include "stdio.h"
#include "string.h"
#include "math.h"


extern uint16_t kalman_printf_cnt;

/* MPU6050Êý¾Ý */
short Accel[3];
short Gyro[3];
float Temp;

float accel_x;	     		//X
float accel_y;	    		//Y
float accel_z;	     		//Z
float gyro_x;						//X
float gyro_y;        		//
float gyro_z;		 				//

float pitch_raw;  		 	//
float pitch_kalman; 	 	//
float roll_raw;  		   	//
float roll_kalman; 		 	//

static float Q_angle = 0.003;		//
static float Q_gyro  = 0.0025;		//
static float R_angle = 0.3;		//
static float dt = 0.02;




void Kalman_Cal_Pitch(float acc,float gyro)
{
	static float QQ_bias;
	static float KK_0, KK_1;
	static float PPP[2][2] = { { 1, 0 },{ 0, 1 } };
	pitch_kalman += (gyro - QQ_bias) * dt;

	PPP[0][0] = PPP[0][0] + Q_angle - (PPP[0][1] + PPP[1][0])*dt;
	PPP[0][1] = PPP[0][1] - PPP[1][1]*dt;
	PPP[1][0] = PPP[1][0] - PPP[1][1]*dt;
	PPP[1][1] = PPP[1][1] + Q_gyro;

	KK_0 = PPP[0][0] / (PPP[0][0] + R_angle);
	KK_1 = PPP[1][0] / (PPP[0][0] + R_angle);

	pitch_kalman = pitch_kalman + KK_0 * (acc - pitch_kalman);
	QQ_bias = QQ_bias + KK_1 * (acc - pitch_kalman);

	PPP[0][0] = PPP[0][0] - KK_0 * PPP[0][0];
	PPP[0][1] = PPP[0][1] - KK_0 * PPP[0][1];
	PPP[1][0] = PPP[1][0] - KK_1 * PPP[0][0];
	PPP[1][1] = PPP[1][1] - KK_1 * PPP[0][1];
}



void Kalman_Cal_Roll(float acc,float gyro)
{
	static float Q_bias;	//
	static float K_0, K_1;	//
	static float PP[2][2] = { { 1, 0 },{ 0, 1 } };//
	roll_kalman += (gyro - Q_bias) * dt; //
	PP[0][0] = PP[0][0] + Q_angle - (PP[0][1] + PP[1][0])*dt;
	PP[0][1] = PP[0][1] - PP[1][1]*dt;
	PP[1][0] = PP[1][0] - PP[1][1]*dt;
	PP[1][1] = PP[1][1] + Q_gyro;
	K_0 = PP[0][0] / (PP[0][0] + R_angle);
	K_1 = PP[1][0] / (PP[0][0] + R_angle);
	roll_kalman = roll_kalman + K_0 * (acc - roll_kalman);
	Q_bias = Q_bias + K_1 * (acc - roll_kalman);
	PP[0][0] = PP[0][0] - K_0 * PP[0][0];
	PP[0][1] = PP[0][1] - K_0 * PP[0][1];
	PP[1][0] = PP[1][0] - K_1 * PP[0][0];
	PP[1][1] = PP[1][1] - K_1 * PP[0][1];
}



void MPU6050_DATA_DEL(void)
{
	float accx,accy,accz;

	MPU6050ReadAcc(Accel);
	MPU6050ReadGyro(Gyro);

	accel_x = Accel[0];
	accel_y = Accel[1];
	accel_z = Accel[2];
	gyro_x  = Gyro[0];
	gyro_y  = Gyro[1];
	gyro_z  = Gyro[2];

	if(accel_x<32764)
	{
		accx=accel_x/(16384.0); //0-1g
	}
	else
	{
		accx=1-(accel_x-49152)/16384.0;
	}
	if(accel_y<32764)
	{
		accy=accel_y/16384.0;
	}
	else
	{
		accy=1-(accel_y-49152)/16384.0;
	}
	if(accel_z<32764)
	{
		accz=accel_z/16384.0;
	}
	else
	{
		accz=(accel_z-49152)/16384.0;
	}

	pitch_raw=(atan(accy/accz))*180/3.14;
//	roll_raw=(atan(accx/accz))*180/3.14;
	roll_raw= atan2(accx,accz)*180/3.14;

	if(accel_y<32764)
	{
		pitch_raw = +pitch_raw;
	}
	if(accel_y>32764)
	{
		pitch_raw = -pitch_raw;
	}

	if(gyro_x<32768)
	{
		gyro_x=-(gyro_x/16.4);
	}
	if(gyro_x>32768)
	{
		gyro_x=+(65535-gyro_x)/16.4;
	}
	if(gyro_y<32768)
	{
		gyro_y=-(gyro_y/16.4);
	}
	if(gyro_y>32768)
	{
		gyro_y=+(65535-gyro_y)/16.4;
	}
	if(gyro_z<32768)
	{
		gyro_z=-(gyro_z/16.4);
	}
	if(gyro_z>32768)
	{
		gyro_z=+(65535-gyro_z)/16.4;
	}

//	Kalman_Cal_Pitch(pitch_raw, gyro_x);  //
	Kalman_Cal_Roll(roll_raw, gyro_y); 		 //

	if(kalman_printf_cnt > 49)
	{
	  kalman_printf_cnt = 0;
	  printf("p_kalman: %.1f, r_kalman: %.1f \r\n", pitch_raw, roll_kalman);
	}
}

my_kalman.h 文件

void MPU6050_DATA_DEL(void);

main.c 文件

#include <stdio.h>
#include "my_delay.h"
#include "my_mpu6050.h"
#include "my_iic.h"
#include "my_kalman.h"

uint8_t   dt_kalman = 0;
uint16_t kalman_printf_cnt = 0;  //20ms

int main(void)
{	
	  //定时器中断20ms 对应dt - 0.02
	  HAL_TIM_Base_Start_IT(&htim3);
	  //mpu6050初始化
	  MPU6050_Init();
	  //循环读取ID
	  while(MPU6050ReadID() == 0)
	  {
		  HAL_Delay(500);
	  }
	  while (1)
	  {
			  if(dt_kalman)
			  {
				  MPU6050_DATA_DEL();
				  dt_kalman = 0;
			  }
	  }
}

stm32g0xx_it.c 文件

extern uint16_t kalman_printf_cnt;  //20ms
extern uint8_t dt_kalman;
uint8_t dt_kalman_cnt=0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == htim3.Instance)
	{
		dt_kalman_cnt++;
		if(dt_kalman_cnt > 19)  //20ms
		{
			dt_kalman_cnt = 0;
			dt_kalman = 1;
			kalman_printf_cnt++;
		}
	}
}

3. STM32F1xx对MPU6050的读取

芯片:STM32F105RBT6
相对与STM32G030,F105RBT6需要注意几点:

  1. SCL,SDA和INT的引脚调整;
  2. IIC延时delay设置72MHz计数10次,64MHz计数9次左右;
  3. IIC_SCL和IIC_SDA的输出方式为开漏输出,不要使用推挽输出,推挽输出为强上下拉,这样从机就没法改变数据线的电平了。

G030里面的配置是推挽却没有问题,可以正常读取,开漏作为数据线更好。

推挽输出

在这里插入图片描述
开漏输出
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1987311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【HarmonyOS NEXT星河版开发学习】小型测试案例05-得物列表项

个人主页→VON 收录专栏→鸿蒙开发小型案例总结​​​​​ 基础语法部分会发布于github 和 gitee上面&#xff08;暂未发布&#xff09; 前言 鸿蒙操作系统通过其先进的分布式架构和开发工具&#xff0c;以及灵活的界面布局和样式控制&#xff0c;为开发者提供了丰富的开发资源…

设计模式- 数据源架构模式

活动记录&#xff08;Active Record&#xff09; 一个对象&#xff0c;它包装数据库表或视图中的某一行&#xff0c;封装数据库访问&#xff0c;并在这些数据上增加了领域逻辑 对象中既有数据又有行为。这些数据大多是持久数据、并且需要保存到数据库。 运行机制 活动记录的…

Iris for mac 好用的录屏软件

Iris 是一款高性能屏幕录像机&#xff0c;可录制到 h.264。Iris 在可用时利用板载 GPU 加速。它可以选择包括来自摄像头和最多两个麦克风的视频。 兼容性 所有功能在macOS 11.0-14上完全支持&#xff0c;包括macOS Sonoma。 简单编码 直接录制为h.264、h.265、ProRes或Motion…

WPF学习(10)-Label标签+TextBlock文字块+TextBox文本框+RichTextBox富文本框

Label标签 Label控件继承于ContentControl控件&#xff0c;它是一个文本标签&#xff0c;如果您想修改它的标签内容&#xff0c;请设置Content属性。我们曾提过ContentControl的Content属性是object类型&#xff0c;意味着Label的Content也是可以设置为任意的引用类型的。 案…

游戏ID统一管理器DEMO

一般游戏的角色ID、名字&#xff0c;工会ID、名字&#xff0c;等最好统一创建&#xff0c;方便合服处理&#xff0c;可以以此基础&#xff0c;动态配置生成ID 这个也可以用openresty 作个&#xff0c;可能更专业点&#xff0c; 1&#xff1a;go1.20 最后一版支持win7的 mongod…

微信小程序乡村医疗系统,源码、部署+讲解

目录 摘 要 Abstract 1 绪论 1.1 研究背景及意义 1.2 研究现状 1.3 研究内容 2 相关技术介绍 2.1 Java 语言 2.2 MySQL 数据库 2.3 Spring Boot 框架 2.4 B/S 结构 2.5 微信小程序 3 系统分析 3.1 可行性分析 3.1.1 经济可行性 3.1.2 技术可行性…

4.MySQL数据类型

目录 数据类型 ​编辑数值类型 tinyint类型 bit类型 float类型 decimal类型 字符串类型 char类型 varchar varchar和char的区别 日期和时间类型 数据类型 数值类型 说明一下&#xff1a;MySQL本身是不支持bool类型的&#xff0c;当把一个数据设置成bool类型时&#x…

【ThreadLocal总结】

文章目录 为什么使用ThreadLocalThreadLocal核心ThreadLocal内部结构ThreadLocal内存泄漏解决内存泄漏 为什么使用ThreadLocal 在并发编程中&#xff0c;多个线程同时访问和修改共享变量是一个常见的场景。这种情况下&#xff0c;可能会出现线程安全问题&#xff0c;即多个线程…

AWS生成式AI项目的全生命周期管理

随着人工智能技术的迅速发展&#xff0c;生成式 AI 已成为当今最具创新性和影响力的领域之一。生成式 AI 能够创建新的内容&#xff0c;如文本、图像、音频等&#xff0c;具有广泛的应用前景&#xff0c;如自然语言处理、计算机视觉、创意设计等。然而&#xff0c;构建一个成功…

【Python】pandas:计算,统计,比较

pandas是Python的扩展库&#xff08;第三方库&#xff09;&#xff0c;为Python编程语言提供 高性能、易于使用的数据结构和数据分析工具。 pandas官方文档&#xff1a;User Guide — pandas 2.2.2 documentation 帮助&#xff1a;可使用help(...)查看函数说明文档&#xff0…

文本编辑器小型架构

C字体库开发之字体列表设计七-CSDN博客 创作不易&#xff0c;小小的支持一下吧&#xff01;

odoo from样式更新

.xodoo_form {.o_form_sheet {padding-bottom: 0 !important;border-style: solid !important;border-color: white;}.o_inner_group {/* 线框的样式 *//*--line-box-border: 1px solid #666;*//*box-shadow: 0 1px 0 #e6e6e6;*/margin: 0;}.grid {display: grid;gap: 0;}.row …

【数据结构】排序 —— 归并排序(mergeSort)、计数排序、基数排序

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;数据结构、LeetCode专栏 &#x1f4da;本系…

【数据结构】哈希应用-STL-位图

目录 1、位图的概念 2、位图的设计与实现 2.1 set 2.2 reset 2.3 test 3、C库中的位图 4、位图的优缺点 5、位图相关题目 1、位图的概念 面试题&#xff1a;给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这4…

【Material-UI】按钮组件中的实验性API:Loading按钮详解

文章目录 一、LoadingButton 组件概述1. 组件介绍2. 基本用法 二、LoadingButton 组件的高级用法1. 自定义加载指示器2. 图标与加载位置 三、已知问题与解决方法1. Chrome 翻译工具与 LoadingButton 的兼容性问题 四、实用性与未来展望1. 应用场景2. 未来展望 五、总结 Materia…

共享内存的原理及初识线程

char *str"hello world"; *str-H; 运行时报错&#xff0c;RWX只有R权限。 外设和内存交互以4KB为单位。 虚拟地址32位的划分为10 10 12 前10位对应页表的页目录。 在10位即为页表&#xff0c;页表中存放指定页框的起始物理地址虚拟地址的低12位作为页内偏移。 共…

RedLock算法分析

Redis分布式锁-RedLock算法 手写分布式锁的缺点 Redlock算法设计理念 Redis也提供了Redlock算法&#xff0c;用来实现基于多个实例的分布式锁。 锁变量由多个实例维护&#xff0c;即使有实例发生了故障&#xff0c;锁变量仍然是存在的&#xff0c;客户端还是可以完成锁操作。…

第一篇Linux介绍

目录 1、操作系统 2、Windows和Linux操作系统的区别 3、 Linux 的发行版本 4、 linux 分支 5、 Linux 的含义 6、Linux 特点 1、操作系统 常见操作系统有&#xff1a;Windows、MacOS、Unix/Linux。 类 UNIX Windows&#xff1a;其是微软公司研发的收费操作系统&#xff…

【漏洞复现】JBoss 中间件漏洞

JBoss介绍 JBoss是⼀个基于J2EE的开发源代码的应⽤服务器。JBoss代码遵循LGPL许可&#xff0c;可以在任何商业应⽤中免费使⽤。JBoss是⼀个管理EJB的容器和服务器&#xff0c;⽀持EJB1.1、EJB 2.0和EJB3的规范。但JBoss核⼼服务不包括⽀持servlet/JSP的WEB容器&#xff0c;⼀般…

QTableView使用示例-Qt模型视图委托(MVD)(Model-View-Delegate)

模型视图委托&#xff08;MVD&#xff09;是Qt中特有的设计模式&#xff0c;类似MVC设计模式&#xff0c;将MVC设计模式中的Controller当做MVD中的Delegate&#xff0c;两者的概念基本相同。不同的是委托不是独立存在&#xff0c;而是包含在视图里面。 模型视图委托设计模式中&…