STM32H743实现与多个mpu6050进行通讯

本文介绍了如何通过I2CChose和AD0变量控制多个mpu6050传感器的级联和地址,利用宏定义减少对原有单I2C驱动的修改,同时处理了DMP库中的地址设置。作者展示了在STM32H743平台上异步读取和数据打包的示例,实现高精度动态数据采集。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mpu6050的AD0引脚可以通过给高地电平来控制它的地址(0X68或0X69),mpu6050只支持2个级联,如果要连接更多就需要开起格外的I2C组了。如果我想同时采集10个mpu6050的数据怎么办,可以俩个分一组,用5组i2c线连接就行了。

我定义了2个全局变量I2CChose和AD0,用这2个变量来控制选择和谁通讯,这里主要考虑了对现有代码的利用,为了尽量少修改原来的单I2C驱动程序,选择使用修改宏定义的方式来修改地址和用哪根总线,代码如下

#define GPIO_PORT_IIC     (I2CChose==1?(GPIOA):(I2CChose==2?(GPIOE):(I2CChose==3?(GPIOD):(I2CChose==4?(GPIOD):(I2CChose==5?(GPIOD):(I2CChose==6?(GPIOA):(I2CChose==7?(GPIOE):(GPIOC))))))))                       /* GPIO端口 */
#define RCC_IIC_ENABLE    __HAL_RCC_GPIOE_CLK_ENABLE()       /* GPIO端口时钟 */
#define IIC_SCL_PIN       (I2CChose==1?(GPIO_PIN_3):(I2CChose==2?(GPIO_PIN_3):(I2CChose==3?(GPIO_PIN_6):(I2CChose==4?(GPIO_PIN_4):(I2CChose==5?(GPIO_PIN_2):(I2CChose==6?(GPIO_PIN_5):(I2CChose==7?(GPIO_PIN_5):(GPIO_PIN_0))))))))                    /* 连接到SCL时钟线的GPIO */
#define IIC_SDA_PIN       (I2CChose==1?(GPIO_PIN_2):(I2CChose==2?(GPIO_PIN_2):(I2CChose==3?(GPIO_PIN_7):(I2CChose==4?(GPIO_PIN_5):(I2CChose==5?(GPIO_PIN_3):(I2CChose==6?(GPIO_PIN_4):(I2CChose==7?(GPIO_PIN_4):(GPIO_PIN_5))))))))                   /* 连接到SDA数据线的GPIO */
#define IIC_SCL_1()  HAL_GPIO_WritePin(GPIO_PORT_IIC, IIC_SCL_PIN, GPIO_PIN_SET)		/* SCL = 1 */
#define IIC_SCL_0()  HAL_GPIO_WritePin(GPIO_PORT_IIC, IIC_SCL_PIN, GPIO_PIN_RESET)		/* SCL = 0 */

#define IIC_SDA_1()  HAL_GPIO_WritePin(GPIO_PORT_IIC, IIC_SDA_PIN, GPIO_PIN_SET)		/* SDA = 1 */
#define IIC_SDA_0()  HAL_GPIO_WritePin(GPIO_PORT_IIC, IIC_SDA_PIN, GPIO_PIN_RESET)		/* SDA = 0 */
#define IIC_SDA_READ()  HAL_GPIO_ReadPin(GPIO_PORT_IIC, IIC_SDA_PIN)	/* 读SDA口线状态 */

对原来的驱动程序不需要进行过多的修改就可以通过I2CChose来更改使用那一条模拟总线。

对应AD0也是如此

//如果AD0脚(9脚)接地,IIC地址为0X68(不包含最低位).
//如果接V3.3,则IIC地址为0X69(不包含最低位).

#define MPU_ADDR				(AD0==0?0X68:0X69)   //原0X68

顺便说一下,具体修改可能要根据你自己手里的mpu6050驱动进行修改,有些驱动里可能设置了const常量,导致你不能动态更改,要找出进行去掉,还有DMP库里的地址也要进行修改,官方的DMP库没有用宏定义的方式进行地址定义,用的是结构体,可以用下面的代码设置

    if(AD0==1){
    	st.hw->addr = 0X69;
    }else{
    	st.hw->addr = 0X68;
    }

st.hw->addr 就是DMP库的存储器件地址的结构体成员

如上我们实现了I2CChose和AD0控制选择哪个mpu6050了,在主函数中写

  //f1
  I2CChose=1;
  AD0=0;
  while(MPU_Init()){}
  while(mpu_dmp_init()){
	  len=sprintf(strtest,"mpu_dmp_init........f11\r\n");  //虚拟串口打印数据
	  CDC_Transmit_FS((uint8_t*)strtest,len);
  }
  I2CChose=1;
  AD0=1;
  while(MPU_Init()){}
  while(mpu_dmp_init()){
	  len=sprintf(strtest,"mpu_dmp_init.........f12\r\n");  //虚拟串口打印数据
	  CDC_Transmit_FS((uint8_t*)strtest,len);
  }
  //f2
  I2CChose=2;
  AD0=0;
  while(MPU_Init()){}
  while(mpu_dmp_init()){
    len=sprintf(strtest,"mpu_dmp_init........f21\r\n");  //虚拟串口打印数据
    CDC_Transmit_FS((uint8_t*)strtest,len);
  }
  I2CChose=2;
  AD0=1;
  while(MPU_Init()){}
  while(mpu_dmp_init()){
    len=sprintf(strtest,"mpu_dmp_init.........f22\r\n");  //虚拟串口打印数据
    CDC_Transmit_FS((uint8_t*)strtest,len);
  }

进行异步初始化,然后在主函数的while()里面写

	  //mpu6050测试
	  I2CChose=1;
	  AD0=0;
	  //HAL_Delay(35);
	  while(mpu_dmp_get_data(&f11p, &f11r, &f11y));	  //必须要用while等待,才能正常读取
	  I2CChose=1;
	  AD0=1;
	  //HAL_Delay(35);
	  while(mpu_dmp_get_data(&f12p, &f12r, &f12y));	  //必须要用while等待,才能正常读取
	  I2CChose=2;
	  AD0=0;
	  //HAL_Delay(35);
	  while(mpu_dmp_get_data(&f21p, &f21r, &f21y));	  //必须要用while等待,才能正常读取
	  I2CChose=2;
	  AD0=1;
	  //HAL_Delay(35);
	  while(mpu_dmp_get_data(&f22p, &f22r, &f22y));	  //必须要用while等待,才能正常读取

进行数据的读取,之后再用H743的虚拟串口功能进行打印输出

	  //打包所有数据
	  len=sprintf(str,"f11p:%.1lf  f11r:%.1lf  f11y:%.1lf\r\nf12p:%.1lf  f12r:%.1lf  f12y:%.1lf\r\n"
			           "f21p:%.1lf  f21r:%.1lf  f21y:%.1lf\r\nf22p:%.1lf  f22r:%.1lf  f22y:%.1lf\r\n",
			            f11p,f11r,f11y,f12p,f12r,f12y,f21p,f21r,f21y,f22p,f22r,f22y);  //虚拟串口打印数据
	  CDC_Transmit_FS((uint8_t*)str,len);
	  HAL_Delay(30);
	  len=sprintf(str,"\r\n\r\n**********\r\n\r\n");  //虚拟串口打印数据
	  CDC_Transmit_FS((uint8_t*)str,len);


可以看见串口助手成功接收到了数据,而且H743本身的性能强劲,10秒接收并输出1万次,可以实现高精度的动态采集。
以上是我自己的学习笔录,需要源码的朋友可以私信联系我。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值