常用通信协议——IIC协议实战项目(二)(STM32+MPU6050+AT24C02)

前面讲了IIC协议的介绍IIC协议的编程实现,接下来我们来做一个关于IIC的小项目。

一、项目的实现功能:

1、使用STM32单片机用IIC协议对AT24C02进行数据写入
2、使用STM32单片机用IIC协议对MPU6050、AT24C02进行数据的循环读取

我们将分三章对本项目进行详细阐述。本章是第二章主要是实现功能:

1、使用STM32单片机用IIC协议对MPU6050进行数据读取

二、本章使用模块简介:

1、MPU6050模块简介

本章实验使用的是正点原子家的ATK-MPU6050六轴传感器模块。实物图片如下:
在这里插入图片描述
原理图如下:
在这里插入图片描述

从图 2.1.2 可以看出, 模块自带了 3.3V 超低压差稳压芯片,给 MPU6050 供电,因此外
部供电可以选择: 3.3V / 5V 都可以。 模块通过 P1 排针与外部连接,引出了 VCC、 GND、
IIC_SDA、 IIC_SCL、 MPU_INT 和 MPU_AD0 等信号,其中, IIC_SDA 和 IIC_SCL 带了 4.7K
上拉电阻,外部可以不用再加上拉电阻了,另外 MPU_AD0 自带了 10K 下拉电阻,当 AD0
悬空时,默认 IIC 地址为(0X68)。
ATK-MPU6050 六轴传感器模块通过一个 1*6 的排针(P1)同外部电路连接,各引脚的
详细描述如表 2.1.1 所示:
在这里插入图片描述
模块仅通过一个 IIC 接口与外部通信,并可以通过 MPU_AD0 设置模块的 IIC 地址,当 MPU_AD0 悬空/接 GND 的时候,模块的 IIC 从机地址为:0X68;当 MPU_AD0 接 VCC的时候,模块的 IIC 从机地址为:0X69。

2、MPU6050重要寄存器简介

MPU6050 内部总共有好几十个寄存器, 这里,我们仅介绍 MPU6050 使用时的几个重要寄存器,其他的请大家参考: MPU-6000 and MPU-6050 Register Map and Descriptions.pdf这个文档。

我们使用的寄存器有:
设置参数使用的寄存器:
(1)电源管理寄存器1、(2)陀螺仪配置寄存器、(3)加速度传感器配置寄存器、(4)FIFO 使能寄存器、(5)陀螺仪采样率分频寄存器、(6)配置寄存器、(7)电源管理寄存器2
读取数据使用的寄存器:(8)温度输出寄存器、(9)陀螺仪输出寄存器、(10)加速度输出寄存器。

(1)电源管理寄存器1

在这里插入图片描述

(2)陀螺仪配置寄存器

在这里插入图片描述

(3)加速度传感器配置寄存器

在这里插入图片描述

(4)FIFO 使能寄存器

在这里插入图片描述

(5)陀螺仪采样率分频寄存器

在这里插入图片描述

(6)配置寄存器

在这里插入图片描述

(7)电源管理寄存器2

在这里插入图片描述
(8)温度输出寄存器
在这里插入图片描述

(9)陀螺仪输出寄存器
在这里插入图片描述

(10)加速度输出寄存器
在这里插入图片描述

三、编程实现

编程主要实现的是5个部分,如下:
序列
1MPU6050 IIC接口驱动
2MPU_Init函数
3读取数据
3.1MPU_Get_Gyroscope函数
3.2MPU_Get_Accelerometer函数
3.3MPU_Get_Temperature函数
1、MPU6050 IIC接口驱动

这个部分可参照之前几章IIC协议编程实现IIC协议实战项目(一)

2、MPU6050的初始化
(1)MPU6050的初始化过程:

在这里插入图片描述

(2)在各步骤使用的寄存器
寄存器种类功能地址对应的步骤
电源管理寄存器1复位MPU60500X6B2
陀螺仪配置寄存器设置角速度传感器的满量程范围0X1B3
加速度传感器配置寄存器设置加速度传感器的满量程范围0X1C3
中断使能寄存器配置中断0X384
用户控制寄存器设置AUX IIC接口0X6A4
FIFO使能寄存器设置FIFO0X234
采样率分频寄存器陀螺仪采样率0X194
配置寄存器设置数字低通滤波器0X1A4
电源管理寄存器1设置系统时钟0X6B5
电源管理寄存器2使能角速度传感器(陀螺仪)和加速度传感器0X6C6
(3)程序与流程对应

在这里插入图片描述

(4)对各个寄存器进行写入(以设置陀螺传感器满量量程为例)

实现原理还是和前两张IIC原理类似,如下图:
在这里插入图片描述

//IIC写一个字节 
//reg:寄存器地址
//data:数据
//返回值:0,正常
//    其他,错误代码
u8 MPU_Write_Byte(u8 reg,u8 data) 				 
{ 
    MPU_IIC_Start(); 
	MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令	
	if(MPU_IIC_Wait_Ack())	//等待应答
	{
		MPU_IIC_Stop();		 
		return 1;		
	}
    MPU_IIC_Send_Byte(reg);	//写寄存器地址
    MPU_IIC_Wait_Ack();		//等待应答 
	MPU_IIC_Send_Byte(data);//发送数据
	if(MPU_IIC_Wait_Ack())	//等待ACK
	{
		MPU_IIC_Stop();	 
		return 1;		 
	}		 
    MPU_IIC_Stop();	 
	return 0;
}
//IIC连续写
//addr:器件地址 
//reg:寄存器地址
//len:写入长度
//buf:数据区
//返回值:0,正常
//    其他,错误代码
u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{
	u8 i; 
    MPU_IIC_Start(); 
	MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令	
	if(MPU_IIC_Wait_Ack())	//等待应答
	{
		MPU_IIC_Stop();		 
		return 1;		
	}
    MPU_IIC_Send_Byte(reg);	//写寄存器地址
    MPU_IIC_Wait_Ack();		//等待应答
	for(i=0;i<len;i++)
	{
		MPU_IIC_Send_Byte(buf[i]);	//发送数据
		if(MPU_IIC_Wait_Ack())		//等待ACK
		{
			MPU_IIC_Stop();	 
			return 1;		 
		}		
	}    
    MPU_IIC_Stop();	 
	return 0;	
} 
3、读取数据
温度值、陀螺仪值(原始值)、加速度值(原始值)都被分别被存储在对应的寄存器中。分别是温度输出寄存器、陀螺仪输出寄存器、加速度输出寄存器。
(1)IIC读一个字节
//IIC读一个字节 
//reg:寄存器地址 
//返回值:读到的数据
u8 MPU_Read_Byte(u8 reg)
{
	u8 res;
    MPU_IIC_Start(); 
	MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令	
	MPU_IIC_Wait_Ack();		//等待应答 
    MPU_IIC_Send_Byte(reg);	//写寄存器地址
    MPU_IIC_Wait_Ack();		//等待应答
    MPU_IIC_Start();
	MPU_IIC_Send_Byte((MPU_ADDR<<1)|1);//发送器件地址+读命令	
    MPU_IIC_Wait_Ack();		//等待应答 
	res=MPU_IIC_Read_Byte(0);//读取数据,发送nACK 
    MPU_IIC_Stop();			//产生一个停止条件 
	return res;		
}
(2)IIC连续读函数

因为温度值、陀螺仪值(原始值)、加速度值(原始值)都是十六位数据(分程两个相邻的8位寄存器存储)故读取数据使用的函数返回值为16位数据。

//IIC连续读
//addr:器件地址
//reg:要读取的寄存器地址
//len:要读取的长度
//buf:读取到的数据存储区
//返回值:0,正常
//    其他,错误代码
u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{ 
 	MPU_IIC_Start(); 
	MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令	
	if(MPU_IIC_Wait_Ack())	//等待应答
	{
		MPU_IIC_Stop();		 
		return 1;		
	}
    MPU_IIC_Send_Byte(reg);	//写寄存器地址
    MPU_IIC_Wait_Ack();		//等待应答
    MPU_IIC_Start();
	MPU_IIC_Send_Byte((addr<<1)|1);//发送器件地址+读命令	
    MPU_IIC_Wait_Ack();		//等待应答 
	while(len)
	{
		if(len==1)*buf=MPU_IIC_Read_Byte(0);//读数据,发送nACK 
		else *buf=MPU_IIC_Read_Byte(1);		//读数据,发送ACK  
		len--;
		buf++; 
	}    
    MPU_IIC_Stop();	//产生一个停止条件 
	return 0;	
}
(3)温度输出

温度读取需要将0X41(高8位)和0X42(低8位)寄存器的数据组合。

//得到温度值
//返回值:温度值(扩大了100倍)
short MPU_Get_Temperature(void)/*short 16位*/
{
    u8 buf[2]; 
    short raw;
	float temp;
	MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf); 
    raw=((u16)buf[0]<<8)|buf[1];  
    temp=36.53+((double)raw)/340;  
    return temp*100;;
}
(4)陀螺仪输出

陀螺仪输出X/Y/Z三个轴的陀螺仪传感器数据,高字节在前,低字节在后,每个轴的数据也是16位。

//得到陀螺仪值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
short MPU_Get_Temperature(void)/*short 16位*/
{
    u8 buf[2]; 
    short raw;
	float temp;
	MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf); 
    raw=((u16)buf[0]<<8)|buf[1];  
    temp=36.53+((double)raw)/340;  
    return temp*100;;
}
(5)加速度输出

输出X/Y/Z三个轴的加速度传感器值,高字节在前,低字节在后,每个轴的数据也是16位。

//得到加速度值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
{
    u8 buf[6],res;  
	res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);
	if(res==0)
	{
		*ax=((u16)buf[0]<<8)|buf[1];  
		*ay=((u16)buf[2]<<8)|buf[3];  
		*az=((u16)buf[4]<<8)|buf[5];
	} 	
    return res;;
}

由于本章为IIC协议的实战项目,关于MPU6050后序的DMP使用,本章不做论述。

接下来一章,则需要实现IIC对AT24C02和MPU6050两个设备进行循环的读取写入。

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值