通过MPU6050测温来进行I2C的验证学习
关于MPU6050寄存器相关可以参考https://blog.youkuaiyun.com/he__yuan/article/details/76559569
I2C时序很多,我是直接以原子I2C的程序结合MPU6050来进行测温实验
# include "MPU6050.H"
# include "delay.h"
# include "usart.h"
其中MPU6050.H文件也只是简单的定义了一些我用到的地址
#ifndef __MPU6050_H
#define __MPU6050_H
#include "I2C.H"
# define Slave_Addr 0x68
# define Power_Register_Addr 0x6B//电源寄存器地址
# define Write_Bit 0
# define Read_Bit 1
# define Power_Register_Addr_ResetNum 0x80
函数的声明我没粘贴进去
之后就是整个代码
# include "MPU6050.H"
# include "delay.h"
# include "usart.h"
//初始化IIC接口
void MPU6050_Init(void)
{
int temp = 0;
IIC_Init();
MPU6050_WriteOneByte(Power_Register_Addr,Power_Register_Addr_Reset);//电源管理寄存器复位
delay_ms(100);
MPU6050_WriteOneByte(Power_Register_Addr,0x00);//唤醒MPU6050
}
u8 MPU6050_ReadOneByte(u16 ReadAddr)
{
u8 temp=0;
IIC_Start();
IIC_Send_Byte((Slave_Addr<<1) | Write_Bit);//发送器件地址0X68,写数据
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr%256);//发送低地址
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte((Slave_Addr<<1) | Read_Bit);//进入接收模式
IIC_Wait_Ack();
temp=IIC_Read_Byte(0);
IIC_Stop();//产生一个停止条件
return temp;
}
//WriteAddr :写入数据的目的地址
//DataToWrite:要写入的数据
void MPU6050_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{
IIC_Start();
IIC_Send_Byte((Slave_Addr<<1) | Write_Bit); //发送器件地址0X68,写数据
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr%256); //发送低地址
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite); //发送字节
IIC_Wait_Ack();
IIC_Stop();//产生一个停止条件
delay_ms(10);
}
//该函数用于写入16bit或者32bit的数据.
//WriteAddr :开始写入的地址
//DataToWrite:数据数组首地址
//Len :要写入数据的长度2,4
void MPU6050_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
{
u8 t;
for(t=0;t<Len;t++)
{
MPU6050_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
}
}
//该函数用于读出16bit或者32bit的数据.
//ReadAddr :开始读出的地址
//返回值 :数据
//Len :要读出数据的长度2,4
u32 MPU6050_ReadLenByte(u16 ReadAddr,u8 Len)
{
u8 t;
u32 temp=0;
for(t=0;t<Len;t++)
{
temp<<=8;
temp+=MPU6050_ReadOneByte(ReadAddr+Len-t-1);
}
return temp;
}
//ReadAddr :开始读出的地址 对24c02为0~255
//pBuffer :数据数组首地址
//NumToRead:要读出数据的个数
void MPU6050_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
while(NumToRead)
{
*pBuffer++=MPU6050_ReadOneByte(ReadAddr++);
NumToRead--;
}
}
//在指定地址开始写入指定个数的数据
//WriteAddr :开始写入的地址 对24c02为0~255
//pBuffer :数据数组首地址
//NumToWrite:要写入数据的个数
void MPU6050_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{
while(NumToWrite--)
{
MPU6050_WriteOneByte(WriteAddr,*pBuffer);
WriteAddr++;
pBuffer++;
}
}
void IIC_Delay(void)
{
delay_us(2);
}
u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{
IIC_Start();
IIC_Send_Byte((Slave_Addr<<1) | Write_Bit);//发送器件地址+写命令
if(IIC_Wait_Ack()) //等待应答
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg); //写寄存器地址
IIC_Wait_Ack(); //等待应答
IIC_Start();
IIC_Send_Byte((Slave_Addr<<1) | Read_Bit);//发送器件地址+读命令
IIC_Wait_Ack(); //等待应答
while(len)
{
if(len==1)*buf=IIC_Read_Byte(0);//读数据,发送nACK
else *buf=IIC_Read_Byte(1); //读数据,发送ACK
len--;
buf++;
}
IIC_Stop(); //产生一个停止条件
return 0;
}
short MPU_Get_Temperature(void)
{
u8 buf[2];
short raw;
float temp;
MPU_Read_Len(Slave_Addr,0x41,2,buf);
raw=((u16)buf[0]<<8)|buf[1];
temp=36.53+((double)raw)/340;
return temp*100;
}
其中MPU6050初始化时,一定要唤醒MPU6050.温度处理函数是网上的,不知道temp=36.53+((double)raw)/340具体是·什么含义,温度处理函数只是将温度寄存器0x41,0x42读出的值合成一个变量,我尝试用原子编写的读数据函数来进行更改,但数据有问题。再此记录一下,学学之后再来解决这个问题,