【STM32】STM32学习笔记-软件I2C读写MPU6050(33)

这篇具有很好参考价值的文章主要介绍了【STM32】STM32学习笔记-软件I2C读写MPU6050(33)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

00. 目录

01. I2C简介

I2C(Inter-Integrated Circuit)总线是一种由NXP(原PHILIPS)公司开发的两线式串行总线,用于连接微控制器及其外围设备。多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。

串行的 8 位双向数据传输位速率在标准模式下可达 100kbit/s,快速模式下可达 400kbit/s,高速模式下可达 3.4Mbit/s。

I2C是一个多主机的总线,每个设备既可以当主控器或被控器,又可作为发送器或接收器,一条总线上可以有多个主机,但同一时刻只允许一个主机工作。

02. MPU6050参数

  • 16位ADC采集传感器的模拟信号,量化范围:-32768~32767
  • 加速度计满量程选择:±2、±4、±8、±16(g)
  • 陀螺仪满量程选择: ±250、±500、±1000、±2000(°/sec)
  • 可配置的数字低通滤波器
  • 可配置的时钟源
  • 可配置的采样分频
  • I2C从机地址:1101000(AD0=0) 1101001(AD0=1)

03. 软件I2C接线图

【STM32】STM32学习笔记-软件I2C读写MPU6050(33),STM32F103,stm32,学习,笔记,江科大,江科大stm32,MPU6050,I2C

04. I2C模拟应答时序示例

i2c.h

#ifndef __I2C_H__

#define __I2C_H__

#include "stm32f10x.h"   


#include "i2c.h"
#include "delay.h"


void i2c_W_SCL(uint8_t value);
void i2c_W_SDA(uint8_t value);
uint8_t i2c_R_SDA(void);

//I2C初始化
void i2c_init(void);
//起始条件
void i2c_start(void);
//结束条件
void i2c_stop(void);
//发送一个字节
void i2c_send_byte(uint8_t value);
//接收一个字节
uint8_t i2c_recv_byte(void);
//发送ACK
void i2c_send_ACK(uint8_t ack);
//接收一个字节
uint8_t i2c_recv_ACK(void);


#endif /*__I2C_H__*/

i2c.c

#include "i2c.h"
#include "delay.h"


void i2c_W_SCL(uint8_t value)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)value);
	delay_us(10);
}

void i2c_W_SDA(uint8_t value)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)value);
	delay_us(10);
}

uint8_t i2c_R_SDA(void)
{
	uint8_t value;

	value = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11);
	delay_us(10);
	
	return value;
}


//I2C初始化
void i2c_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	//使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	//SCL B10  SDA B11
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStruct);

	//初始状态为高电平
	GPIO_SetBits(GPIOB, GPIO_Pin_10 | GPIO_Pin_11);
}


//起始条件
void i2c_start(void)
{
	i2c_W_SDA(1);
	i2c_W_SCL(1);
	i2c_W_SDA(0);	
	i2c_W_SCL(0);
}


//结束条件
void i2c_stop(void)
{
	i2c_W_SDA(0);
	i2c_W_SCL(1);
	i2c_W_SDA(1);
}

//发送一个字节
void i2c_send_byte(uint8_t value)
{
	uint8_t i = 0;

	for (i = 0; i < 8; i++)
	{
		i2c_W_SDA(value & (0x80 >> i));
		i2c_W_SCL(1);
		//delay_us(5);
		i2c_W_SCL(0);	
	}
}


//接收一个字节
uint8_t i2c_recv_byte(void)
{
	uint8_t i = 0;
	uint8_t value = 0;

	//主设备释放SDL
	i2c_W_SDA(1);

	for (i = 0; i < 8; i++)
	{
		i2c_W_SCL(1);
		if (i2c_R_SDA() == 1)
		{
			value = value | 0x80 >> i;
		}
		
		i2c_W_SCL(0);
	}

	return value;
}


//发送ACK
void i2c_send_ACK(uint8_t ack)
{
	i2c_W_SDA(ack);
	i2c_W_SCL(1);
	//delay_us(5);
	i2c_W_SCL(0);	
}


//接收一个字节
uint8_t i2c_recv_ACK(void)
{
	uint8_t value = 0;

	//主设备释放SDL
	i2c_W_SDA(1);

	i2c_W_SCL(1);
	value = i2c_R_SDA();
		
	i2c_W_SCL(0);

	return value;
}

main.c

#include "stm32f10x.h"

#include "delay.h"
#include "oled.h"
#include "i2c.h"


 int main(void)
 {	 
	 uint8_t ack;
	 //初始化
	 OLED_Init();
	 
	 i2c_init();

	 i2c_start();
	 i2c_send_byte(0xD0);
	 
	 ack = i2c_recv_ACK();
	 
	 i2c_stop();
	 
	 OLED_ShowNum(1, 1, ack, 2);
	 
 
	 while(1)
	 {
		 
	 }
	 
	 return 0;
 }


 

05. I2C读取MPU6050程序示例

i2c.h

#ifndef __I2C_H__

#define __I2C_H__

#include "stm32f10x.h"   


#include "i2c.h"
#include "delay.h"


void i2c_W_SCL(uint8_t value);
void i2c_W_SDA(uint8_t value);
uint8_t i2c_R_SDA(void);

//I2C初始化
void i2c_init(void);
//起始条件
void i2c_start(void);
//结束条件
void i2c_stop(void);
//发送一个字节
void i2c_send_byte(uint8_t value);
//接收一个字节
uint8_t i2c_recv_byte(void);
//发送ACK
void i2c_send_ACK(uint8_t ack);
//接收一个字节
uint8_t i2c_recv_ACK(void);


#endif /*__I2C_H__*/

i2c.c

#include "i2c.h"
#include "delay.h"


void i2c_W_SCL(uint8_t value)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)value);
	delay_us(10);
}

void i2c_W_SDA(uint8_t value)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)value);
	delay_us(10);
}

uint8_t i2c_R_SDA(void)
{
	uint8_t value;

	value = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11);
	delay_us(10);
	
	return value;
}


//I2C初始化
void i2c_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	//使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	//SCL B10  SDA B11
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStruct);

	//初始状态为高电平
	GPIO_SetBits(GPIOB, GPIO_Pin_10 | GPIO_Pin_11);
}


//起始条件
void i2c_start(void)
{
	i2c_W_SDA(1);
	i2c_W_SCL(1);
	i2c_W_SDA(0);	
	i2c_W_SCL(0);
}


//结束条件
void i2c_stop(void)
{
	i2c_W_SDA(0);
	i2c_W_SCL(1);
	i2c_W_SDA(1);
}

//发送一个字节
void i2c_send_byte(uint8_t value)
{
	uint8_t i = 0;

	for (i = 0; i < 8; i++)
	{
		i2c_W_SDA(value & (0x80 >> i));
		i2c_W_SCL(1);
		//delay_us(5);
		i2c_W_SCL(0);	
	}
}


//接收一个字节
uint8_t i2c_recv_byte(void)
{
	uint8_t i = 0;
	uint8_t value = 0;

	//主设备释放SDL
	i2c_W_SDA(1);

	for (i = 0; i < 8; i++)
	{
		i2c_W_SCL(1);
		if (i2c_R_SDA() == 1)
		{
			value = value | 0x80 >> i;
		}
		
		i2c_W_SCL(0);
	}

	return value;
}


//发送ACK
void i2c_send_ACK(uint8_t ack)
{
	i2c_W_SDA(ack);
	i2c_W_SCL(1);
	//delay_us(5);
	i2c_W_SCL(0);	
}


//接收一个字节
uint8_t i2c_recv_ACK(void)
{
	uint8_t value = 0;

	//主设备释放SDL
	i2c_W_SDA(1);

	i2c_W_SCL(1);
	value = i2c_R_SDA();
		
	i2c_W_SCL(0);

	return value;
}

MPU6050.h

#ifndef __MPU6050_H__

#define __MPU6050_H__


#include "mpu6050.h"
#include "i2c.h"


#define MPU6050_ADDRESS		    0xD0

#define	MPU6050_SMPLRT_DIV		0x19
#define	MPU6050_CONFIG			0x1A
#define	MPU6050_GYRO_CONFIG		0x1B
#define	MPU6050_ACCEL_CONFIG	0x1C

#define	MPU6050_ACCEL_XOUT_H	0x3B
#define	MPU6050_ACCEL_XOUT_L	0x3C
#define	MPU6050_ACCEL_YOUT_H	0x3D
#define	MPU6050_ACCEL_YOUT_L	0x3E
#define	MPU6050_ACCEL_ZOUT_H	0x3F
#define	MPU6050_ACCEL_ZOUT_L	0x40
#define	MPU6050_TEMP_OUT_H		0x41
#define	MPU6050_TEMP_OUT_L		0x42
#define	MPU6050_GYRO_XOUT_H		0x43
#define	MPU6050_GYRO_XOUT_L		0x44
#define	MPU6050_GYRO_YOUT_H		0x45
#define	MPU6050_GYRO_YOUT_L		0x46
#define	MPU6050_GYRO_ZOUT_H		0x47
#define	MPU6050_GYRO_ZOUT_L		0x48

#define	MPU6050_PWR_MGMT_1		0x6B
#define	MPU6050_PWR_MGMT_2		0x6C
#define	MPU6050_WHO_AM_I		0x75




void MPU6050_WriteReg(uint8_t regAddr, uint8_t data);
uint8_t MPU6050_ReadReg(uint8_t regAddr);
void MPU6050_init(void);
uint8_t MPU6050_getId(void);
void MPU6050_getData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, 
						int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);


#endif /*__MPU6050_H__*/

MPU6050.c

#include "mpu6050.h"
#include "i2c.h"


void MPU6050_WriteReg(uint8_t regAddr, uint8_t data)
{
	
	i2c_start();
	
	i2c_send_byte(MPU6050_ADDRESS);
	
	i2c_recv_ACK();
	
	i2c_send_byte(regAddr);
	i2c_recv_ACK();
	
	i2c_send_byte(data);
	i2c_recv_ACK();
	
	i2c_stop();
}

uint8_t MPU6050_ReadReg(uint8_t regAddr)
{
	uint8_t data = 0;
	
	i2c_start();
	
	i2c_send_byte(MPU6050_ADDRESS);
	
	i2c_recv_ACK();
	
	i2c_send_byte(regAddr);
	i2c_recv_ACK();

	i2c_start();
	
	i2c_send_byte(MPU6050_ADDRESS | 0x1);
	
	i2c_recv_ACK();
	
	data = i2c_recv_byte();
	i2c_send_ACK(1);
	
	i2c_stop();
	
	return data;
}


void MPU6050_init(void)
{
	i2c_init();
	
	MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);
	MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00);
	MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);
	MPU6050_WriteReg(MPU6050_CONFIG, 0x06);
	MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);
	MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);
}

uint8_t MPU6050_getId(void)
{
	return MPU6050_ReadReg(MPU6050_WHO_AM_I);
}

void MPU6050_getData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, 
						int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
	uint8_t DataH, DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);
	*AccX = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);
	*AccY = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);
	*AccZ = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);
	*GyroX = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);
	*GyroY = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);
	*GyroZ = (DataH << 8) | DataL;
}

main.c

#include "stm32f10x.h"

#include "delay.h"
#include "oled.h"
#include "mpu6050.h"


 int main(void)
 {	 
	 uint8_t data = 0;
	 int16_t AX, AY, AZ, GX, GY, GZ;

	 //初始化
	 OLED_Init();
	 MPU6050_init();
	 
	 data = MPU6050_getId();
	 OLED_ShowString(1, 1, "ID: ");
	 OLED_ShowHexNum(1, 5, data, 3);
	 
 
	 while(1)
	 {
		MPU6050_getData(&AX, &AY, &AZ, &GX, &GY, &GZ);
		OLED_ShowSignedNum(2, 1, AX, 5);
		OLED_ShowSignedNum(3, 1, AY, 5);
		OLED_ShowSignedNum(4, 1, AZ, 5);
		OLED_ShowSignedNum(2, 8, GX, 5);
		OLED_ShowSignedNum(3, 8, GY, 5);
		OLED_ShowSignedNum(4, 8, GZ, 5);
		 
		 delay_ms(100);
		 
	 }
	 
	 return 0;
 }


 

06. 程序下载

27-软件I2C时序模拟.rar

28-软件I2C.rar

07. 附录

参考: 【STM32】江科大STM32学习笔记汇总文章来源地址https://www.toymoban.com/news/detail-810802.html

到了这里,关于【STM32】STM32学习笔记-软件I2C读写MPU6050(33)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32学习笔记(十)丨I2C通信(使用I2C实现MPU6050和STM32之间通信)

    ​  本次课程采用单片机型号为STM32F103C8T6。(鉴于笔者实验时身边只有STM32F103ZET6,故本次实验使基于ZET6进行的) ​  课程链接:江协科技 STM32入门教程   往期笔记链接:   STM32学习笔记(一)丨建立工程丨GPIO 通用输入输出   STM32学习笔记(二)丨STM32程序调试

    2024年01月19日
    浏览(26)
  • STM32软件I2C驱动MPU6050

    这里没有什么复杂的地方,采用MPU6050的现成模块.模块的SCL接B10,SDA接B11,这里连接了一个OLED显示屏,用于显示获取到的数据. 注意:这里使用的模块自带上拉电阻 首先在工程目录里创建: \\\"MyI2C.h\\\"和\\\"MyI2C.c\\\"文件,用于软件驱动I2C. \\\"MPU6050.h\\\",\\\"MPU6050.c\\\"和\\\"MPU6050Reg.h\\\"文件,用于MPU6050的驱动. 在

    2024年02月15日
    浏览(18)
  • 01_STM32软件+硬件I2C读取MPU6050(HAL库)

    目录 1、I2C简介 2、I2C时序单元 2.1 起始条件 2.2 终止条件 2.3 发送一个字节 2.4 接收一个字节 2.5 发送应答 2.6 接收应答 3、I2C完整时序 3.1 指定地址写一个字节 3.2 当前地址读一个字节 3.2 指定地址读一个字节 4、简单软件I2C代码(HAL) 4.1 软件I2C 4.2 软件I2C读MPU6050寄存器 5、ST

    2024年04月17日
    浏览(21)
  • STM32--MPU6050与I2C外设

    在51单片机专栏中,用过I2C通信来进行实现AT24C02的数据存储; 里面介绍的是 利用程序的编程来实现I2C的时序 ,进而实现AT24C02与单片机之间的关系连接; 本章将介绍使用I2C的硬件外设来实现I2C通信,和介绍MPU6050,利用I2C通信实现STM32对MPU6050的控制. I2C通信软件实现程序链接

    2024年02月11日
    浏览(23)
  • STM32 I2C通讯+MPU6050通讯演示

    1.I2C通讯简介 I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线; 两根通信线:SCL(Serial Clock)、SDA(Serial Data); 同步,半双工,带数据应答; 支持总线挂载多设备(一主多从、多主多从) 2.硬件电路 所有I2C设备的SCL连在一起,SDA连在一起; 设备的SCL和SDA均要配置

    2024年01月21日
    浏览(25)
  • 【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪

    MPU-6000(6050)为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时间轴之差的问题,减少了大量的封装空间。当连接到三轴磁强计时,MPU-60X0提供完整的9轴运动融合输出到其主I2C或SPI端口(SPI仅在MPU-6000上可用)。 寄存器地址 寄存器内容 0X3B

    2024年02月16日
    浏览(20)
  • STM32F407硬件I2C实现MPU6050通讯(CUBEIDE)

    工程代码 https://download.csdn.net/download/weixin_52849254/87886714 I2C1通道可选择三种不同的通讯协议:I2C、SMBus-Alert-mode、SMBus-two-wire-Interface。 SMBus (System Management Bus,系统管理总线), 为系统和电源管理这样的任务提供了一条控制总线,SMBus与I2C总线之间在时序特性上存在一些差别 修改

    2024年02月09日
    浏览(22)
  • 26、江科大stm32视频学习笔记——I2C读写W25Q64

    一、W25Q64简介 1、W25Q64的内存空间结构:  一页256字节,4K(4096 字节)为一个扇区,16个扇区为1块,容量为8M字节,共有128个块,2048 个扇区。   2、W25Q64每页大小由256字节组成,每页的256字节用一次页编程指令即可完成。 3、擦除指令分别支持: 16页(1个扇区)、128页、256页、全片

    2024年01月25日
    浏览(27)
  • 【STM32】STM32学习笔记-I2C通信外设(34)

    I2C(Inter-Integrated Circuit)总线 是一种由NXP(原PHILIPS)公司开发的两线式串行总线,用于连接微控制器及其外围设备。多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。 串行的 8 位双向数据传输位速率在标准模式下可

    2024年01月17日
    浏览(26)
  • 【STM32】STM32学习笔记-I2C通信协议(31)

    I2C(Inter-Integrated Circuit)总线 是一种由NXP(原PHILIPS)公司开发的两线式串行总线,用于连接微控制器及其外围设备。多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。 串行的 8 位双向数据传输位速率在标准模式下可

    2024年01月23日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包