mpu6050对应i2c地址是什么_如何读取数据

发布者:美好梦想最新更新时间:2024-06-19 来源: elecfans关键字:mpu6050  读取数据  STM32 手机看文章 扫描二维码
随时随地手机看文章

  MPU6050其实就是一个 I2C 器件,里面有很多寄存器(但是我们用到的只有几个),我们通过读写寄存器来操作这个芯片。所以首要问题就是 STM32 和 MPU6050 的 I2C 通信。

  1、配置 STM32 (用I2C1:PB6——SCL;PB7——SDA)

  1)时钟 RCC

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 , ENABLE);

  2)GPIO 配置

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //两个引脚都加 4.7K 上拉电阻

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  3)I2C 配置

  void I2C_Configuration(void)

  {

  I2C_InitTypeDef I2C_InitStructure;

  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

  I2C_InitStructure.I2C_OwnAddress1 =0xc0; // STM32 的自身地址,不与从器件相同即可

  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

  I2C_InitStructure.I2C_ClockSpeed = 100000;

  I2C_Init(I2C1, &I2C_InitStructure);

  I2C_Cmd(I2C1, ENABLE);

  }

  至此,STM32 已配置完毕,其实不是那么难。

  2、初始化 MPU6050

  void MPU6050_Initialize() //初始化过程 ,其实就是写 5个寄存器

  {

  MPU6050_I2C_ByteWrite(0xd0,0x00,MPU6050_RA_PWR_MGMT_1); // reg107, 唤醒,8M内部时钟源

  MPU6050_I2C_ByteWrite(0xd0,0x07,MPU6050_RA_SMPLRT_DIV); //采用频率 1000

  MPU6050_I2C_ByteWrite(0xd0,0x06,MPU6050_RA_CONFIG);

  MPU6050_I2C_ByteWrite(0xd0,0x01,MPU6050_RA_ACCEL_CONFIG); //加速度量程 2g

  MPU6050_I2C_ByteWrite(0xd0,0x18,MPU6050_RA_GYRO_CONFIG); //角速度量程 2000度/s

  }

  注:0xD0 表示 MPU6050 的地址。我们知道 I2C从器件(在此当然是指 MPU6050)有 8 位的地址,前 7 位由 WHO AM I 确定,第 8 位由 AD0 的电平决定。WHO AM I 默认值是 0x68H(1101000B),AD0 接低电平,所以 MPU6050 的 I2C 地址是 0xD0H(11010000B)。

  3、I2C 核心程序 ( 读/写)

  1)写入寄存器

  一次写操作分为几个步骤: 发送开始信号 -》 起始成功?(可能描述的不太准确) -》 发送 MPU6050 地址、状态(写)-》 写地址成功? -》 发送 MPU6050内部某个待写寄存器地址 -》 发送成功? -》 发送要写入的内容 -》 发送成功? -》 发送结束信号

  总结:先写 MPU6050 地址,再写 寄存器地址,最后写 内容,且每次都要验证(应该和应答信号有关)。这就像寄快递一样,先写市县地址,再写街道地址,最后写门牌号。

  再看下面的程序就会更容易理解一些。

  void MPU6050_I2C_ByteWrite(u8 slaveAddr, u8 pBuffer, u8 writeAddr)

  {

  /* Send START condition */

  I2C_GenerateSTART(I2C1, ENABLE); //发送开始信号

  /* Test on EV5 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  /* Send MPU6050 address for write */

  I2C_Send7bitAddress(I2C1, slaveAddr, I2C_Direction_Transmitter); // 发送 MPU6050 地址、状态(写)

  /* Test on EV6 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  /* Send the MPU6050‘s internal address to write to */

  I2C_SendData(I2C1, writeAddr); //发送 MPU6050内部某个待写寄存器地址

  /* Test on EV8 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Send the byte to be written */

  I2C_SendData(I2C1, pBuffer); //发送要写入的内容

  /* Test on EV8 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Send STOP condition */

  I2C_GenerateSTOP(I2C1, ENABLE); //发送结束信号

  }


  2)读寄存器

  因为 加速度值和角速度值都在寄存器里,所以必须读它才能获得数据。

  附上程序

  如:MPU6050_I2C_BufferRead(0xd0, receive_data, MPU6050_RA_WHO_AM_I, 1); //读 WHO_AM_I 寄存器的值(0x68)

  如:

  void MPU6050_GetRawAccelGyro(s16* AccelGyro) //读加速度值 和 角速度值

  {

  u8 tmpBuffer[14],i;

  MPU6050_I2C_BufferRead(0xd0, tmpBuffer, MPU6050_RA_ACCEL_XOUT_H, 14);

  /* Get acceleration */

  for(i=0; i《3; i++)

  AccelGyro=((s16)((u16)tmpBuffer[2*i] 《《 8) + tmpBuffer[2*i+1]);

  /* Get Angular rate */

  for(i=4; i《7; i++) //在此跳过温度寄存器,不需要温度值

  AccelGyro[i-1]=((s16)((u16)tmpBuffer[2*i] 《《 8) + tmpBuffer[2*i+1]);

  }

  注:

  #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

  I2C 读核心程序:

  void MPU6050_I2C_BufferRead(u8 slaveAddr, u8* pBuffer, u8 readAddr, u16 NumByteToRead)

  {

  /* While the bus is busy */

  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

  /* Send START condition */

  I2C_GenerateSTART(I2C1, ENABLE);

  /* Test on EV5 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  /* Send MPU6050 address for write */

  I2C_Send7bitAddress(I2C1, slaveAddr, I2C_Direction_Transmitter);

  /* Test on EV6 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  /* Clear EV6 by setting again the PE bit */

  I2C_Cmd(I2C1, ENABLE);

  /* Send the MPU6050’s internal address to write to */

  I2C_SendData(I2C1, readAddr);

  /* Test on EV8 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Send STRAT condition a second time */

  I2C_GenerateSTART(I2C1, ENABLE);

  /* Test on EV5 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  /* Send MPU6050 address for read */

  I2C_Send7bitAddress(I2C1, slaveAddr, I2C_Direction_Receiver);

  /* Test on EV6 and clear it */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

  /* While there is data to be read */

  while(NumByteToRead)

  {

  if(NumByteToRead == 1)

  {

  /* Disable Acknowledgement */

  I2C_AcknowledgeConfig(I2C1, DISABLE);

  /* Send STOP Condition */

  I2C_GenerateSTOP(I2C1, ENABLE);

  }

  /* Test on EV7 and clear it */

  if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))

  {

  /* Read a byte from the MPU6050 */

  *pBuffer = I2C_ReceiveData(I2C1);

  /* Point to the next location where the byte read will be saved */

  pBuffer++;

  /* Decrement the read bytes counter */

  NumByteToRead--;

  }

  }

  /* Enable Acknowledgement to be ready for another reception */

  I2C_AcknowledgeConfig(I2C1, ENABLE);

  }

  最后,把六个值 printf 出来就行。

  


关键字:mpu6050  读取数据  STM32 引用地址:mpu6050对应i2c地址是什么_如何读取数据

上一篇:从单片机步入Linux之运行地址与加载地址
下一篇:SPI协议详解(以ADS1118为例)

推荐阅读最新更新时间:2024-11-07 00:01

STM32 JTAG复用相关方法
STM32F10x系列的MCU复位后,PA13/14/15 & PB3/4默认配置为JTAG功能。有时我们为了充分利用MCU I/O口的资源,会把这些端口设置为普通I/O口。具体方法如下: GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); // 改变指定管脚的映射 GPIO_Remap_SWJ_Disable SWJ 完全禁用(JTAG+SW-DP) GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); // 改变指定管脚的映射 GPIO_Remap_SWJ_JTAGDisable ,JTAG-DP
[单片机]
STM32基于固件库学习笔记(9)TM3产生PWM调LED亮度
PWM   脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号,也就是说对脉冲宽度的控制。   STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出,这样,STM32 最多可以同时产生 30 路 PWM 输出!    在TIMx_CCMRx寄存器中的OCxM位写入’110’(PWM模式1)或’111’(PWM模式2),能够独立地设置每个OCx输出通道产生一路PWM。必须设置TIMx_CCMRx寄存OCxPE
[单片机]
STM32的SPI1、SPI2、SPI3初始化及RF1101的应用(标准库与HAL库)
——基于STM32F103RCT6 ---- 标准库: 说明:相关文件共有两个:bsp_spi_cc1101.h;bsp_spi_cc1101.c;以SPI2为例。 1、“bsp_spi_cc1101.h”中的参数定义: #ifndef _BSP_SPI_1101_H_ #define _BSP_SPI_1101_H_ #include stdio.h #include stm32f10x.h #include misc.h #include os_cfg_app.h #include os.h #include core_cm3.h #include bsp.h #include stm32f10x_s
[单片机]
STM32 nvic 解释
朋友们,如果你需要在STM32上移植RTOS,那么首先必须深入理解它的中断系统。 什么是NVIC?即嵌套向量中断控制器(Nested Vectored Interrupt Controller)。STM32的中有一个强大而方便的NVIC,它是属于Cortex内核的器件,不可屏蔽中断 (NMI)和外部中断都由它来处理,而SYSTICK不是由 NVIC来控制的。 特性: ● 60个可屏蔽中断通道(不包含16个Cortex™-M3的中断线); ● 16个可编程的优先等级(使用了4位中断优先级); ● 低延迟的异常和中断处理; ● 电源管理控制; ● 系统控制寄存器的实现; 1.中断优先级分组 STM32(Cortex-M3)
[单片机]
<font color='red'>STM32</font> nvic 解释
STM32串口多机通信
从设备采用漏极开路方式级联,从设备的串口TX必须配置为漏极开路,不能是推挽方式,如果配置成推挽方式,会导致灌电流过大,低电平低不下去问题 STM32 的UART数据寄存器是9位,数据传输先传低位(LSB) --实际应用发现9位数据大时候有丢包错包问题?? 利用USART可以进行多机处理器通信,其原理就是使从机处于静默模式,由主机在需要的时候发送指令唤醒从机,并传输数据。STM32静默模式特点:1、所有接收状态位都不会被设置;2、所有的接收中断都被禁止;3、USART_CR1寄存器中的RWU位被置1,RUW可以硬件自动控制或者在某些条件下由软件写。 连接方法很简单,主机的TX输出与从机的RX端口直接相连,从机TX端口要经过与
[单片机]
STM32 基础系列教程 7 - 单脉冲PWM
前言 学习stm32 基本定时器的使用,用基本定时器实现产生一个PWM,实现单脉冲PWM的功能。 示例详解 基于硬件平台: STM32F10C8T6最小系统板, MCU 的型号是 STM32F103c8t6, 使用stm32cubemx 工具自动产生的配置工程,使用KEIL5编译代码。 本示例所用的最小系统板原理图: 从本节开始,关于CUBEMX工具及KEIL工具的操作将不再细讲,如果还有不熟悉的可以查看之前的教程文档。下面直接介绍工程配置: 系统时钟树 定时器配置 引脚配置 工程代码 在main.c 中加入如下图所示代码: 到此,单脉冲PWM实验就完成了,在本实验中可能看到PA
[单片机]
<font color='red'>STM32</font> 基础系列教程 7 - 单脉冲PWM
基于STM32的USB枚举过程学习笔记(二)
接下来介绍USB设备的枚举,枚举就是从设备读取各种描述符信息,这样主机就可以根据这些信息来加载合适的驱动,从而知道是什么样的设备,如何进行通信。 枚举过程使用的是控制传输。控制传输可以保证数据的正确性。控制传输分三个过程:建立过程,可选数据过程及状态过程。 下面介绍枚举的详细过程。 USB主机检测到USB设备插入后,就会先对设备复位,并通过一个带数据过程的控制传输完成设备描述符的获取。 第一步,USB主机会往地址0的端点0发送获取设备描述符的标准请求,发送请求属于控制传输的建立过程。建立过程是一个事务。首先是令牌包,即主机发送一个SETUP令牌,令牌的格式如上一篇描述的那样,有令牌的PID,地址和端点号等;其次是
[单片机]
基于<font color='red'>STM32</font>的USB枚举过程学习笔记(二)
STM32之Flash
1. 在默认情况下,只有执行FLASH设置(延迟,预取指,半周期)的函数式允许执行的。 如果想要执行FLASH编写/擦除/保护函数,必须在文件“stm32f10x_conf.h”中定义_FLASH_PROG如下: #define _FLASH_PROG 2.按照不同容量,存储器组织成32个1K字节/页(小容量)、128个1K字节/页(中容量),万利板子是中容量 #define FLASH_PAGE_SIZE ((u16)0x400) //一页为1024个字节 3. /* Get pages write protection status */ WRPR_Value = FLASH_GetWriteProte
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved