6-axis speedometer/gyroscope MPU6050 module C51 microcontroller I2C program C code


Download

https://pan.baidu.com/s/15QGGG


Product parameters
Name: MPU-6050 module (three-axis gyroscope + three-axis acceleration)
Chip used: MPU-6050
Power supply: 3-5V (internal low dropout voltage regulator)
Communication method: standard IIC communication protocol
chip built-in 16bit AD converter , 16- bit data output
Gyroscope range: ±250 500 1000 2000 °/
s   

The MPU-6000 is the world's first integrated 6-axis motion processing unit. Compared with the multi-component solution, it avoids the problem of the difference between the axes when combining the gyroscope and the accelerator, and reduces a lot of packaging space. The MPU-6000 integrates a 3-axis gyroscope, a 3-axis accelerometer, and includes a digital motion processing (DMP: Digital Motion Processor) hardware acceleration that can be connected to accelerators of other brands, magnetic sensors, or other sensors through the second I2C port The engine, in the form of a single data stream from the main I2C port, outputs a complete 9-axis fusion algorithm technology
InvenSense motion processing database to the application side, which can process the complex data of motion sensing and reduce the load of motion processing operations on the operating system , and provide a structured API for application development.
The MPU-6000's angular velocity full-frame sensing range is ±250, ±500, ±1000, and ±2000°/sec (dps), which can accurately track fast and slow motion, and a user-programmable accelerator full-frame sensing The measuring range is ±2g, ±4g ±8g and ±16g. Product transmission can be via I2C up to 400kHz or SPI up to 20MHz.
MPU-6000 can work under different voltages. The VDD supply voltage is between 2.5V±5%, 3.0V±5% or 3.3V±5%, and the logic interface VVDIO power supply is 1.8V±5%. The package size of the MPU-6000 is 4x4x0.9mm (QFN), which is a revolutionary size in the industry. Other features include a built-in temperature sensor, including an oscillator that varies only ±1% in the operating environment.

Applications
Motion Sensing Gaming
Augmented Reality
Electronic Image Stabilization (EIS: Electronic Image Stabilization)
Optical Image Stabilization (OIS: Optical Image Stabilization)
Pedestrian Navigator
"Zero Touch" Gesture User Interface Gesture
Shortcuts
Authentication

 

Features
The fusion calculation data of 6-axis or 9-axis rotation matrix, quaternion, and Euler angle format is output digitally.
3-axis angular velocity sensor (gyroscope) with 131 LSBs/°/sec sensitivity and full-frame sensing ranges of ±250, ±500, ±1000 and ±2000°/sec.
Programmable 3-axis accelerator with program control ranges of ±2g, ±4g, ±8g and ±16g.
Removed sensitivity between accelerometer and gyroscope axes, reducing the effect of settings and sensor drift.
Digital Motion Processing (DMP: Digital Motion Processing) engine can reduce the load of complex fusion calculation data, sensor synchronization, posture sensing, etc.
The motion processing database supports Android, Linux and Windows.
The built-in operating time deviation and magnetic sensor calibration calculation technology eliminates the need for customers to perform additional calibration.
Temperature sensor with digital output.
The digital input sync pin (Sync pin) supports video electronic image stabilization technology and GPS.
Programmable interrupts support gesture recognition, panning, zooming in and out, scrolling, fast descent interrupts, high-G interrupts, zero motion sensing, touch sensing, and shaking sensing.
VDD supply voltage is 2.5V±5%, 3.0V±5%, 3.3V±5%; VDDIO is 1.8V±5%.
Gyro operating current: 5mA, gyroscope standby current: 5μA; accelerator operating current: 350μA, accelerator power saving mode current: 20μA@10Hz.
Fast-mode I2C up to 400kHz, or SPI serial host interface up to 20MHz.

The built-in frequency generator has only ±1% frequency variation over the full temperature range.
Tested by users themselves.
10,000 g crash tolerance.

The smallest and thinnest package (4x4x0.9mm QFN) tailored for portable products.
Compliant with RoHS and environmental standards.

【Serial port】

//****************************************
// Update to MPU6050 by shinetop
// MCU: STC89C52
// 功能: 显示加速度计和陀螺仪的10位原始数据
//****************************************
// GY-52 MPU3050 IIC测试程序
// 使用单片机STC89C51 
// 晶振:11.0592M
// 显示:LCD1602
// 编译环境 Keil uVision2
//****************************************
#include <REG52.H>  
#include <math.h>    //Keil library  
#include <stdio.h>   //Keil library 
#include <INTRINS.H>
typedef unsigned char  uchar;
typedef unsigned short ushort;
typedef unsigned int   uint;
//****************************************
// 定义51单片机端口
//****************************************
#define DataPort P0       //LCD1602数据端口
sbit    SCL=P1^0;           //IIC时钟引脚定义
sbit    SDA=P1^1;           //IIC数据引脚定义
sbit    LCM_RS=P2^0;        //LCD1602命令端口      
sbit    LCM_RW=P2^1;        //LCD1602命令端口      
sbit    LCM_EN=P2^2;        //LCD1602命令端口 
//****************************************
// 定义MPU6050内部地址
//****************************************
#define SMPLRT_DIV      0x19    //陀螺仪采样率,典型值:0x07(125Hz)
#define CONFIG          0x1A    //低通滤波频率,典型值:0x06(5Hz)
#define GYRO_CONFIG     0x1B    //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define ACCEL_CONFIG    0x1C    //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define ACCEL_XOUT_H    0x3B
#define ACCEL_XOUT_L    0x3C
#define ACCEL_YOUT_H    0x3D
#define ACCEL_YOUT_L    0x3E
#define ACCEL_ZOUT_H    0x3F
#define ACCEL_ZOUT_L    0x40
#define TEMP_OUT_H      0x41
#define TEMP_OUT_L      0x42
#define GYRO_XOUT_H     0x43
#define GYRO_XOUT_L     0x44   
#define GYRO_YOUT_H     0x45
#define GYRO_YOUT_L     0x46
#define GYRO_ZOUT_H     0x47
#define GYRO_ZOUT_L     0x48
#define PWR_MGMT_1      0x6B    //电源管理,典型值:0x00(正常启用)
#define WHO_AM_I            0x75    //IIC地址寄存器(默认数值0x68,只读)
#define SlaveAddress    0xD0    //IIC写入时的地址字节数据,+1为读取
//****************************************
//定义类型及变量
//****************************************
uchar dis[6];                          //显示数字(-511至512)的字符数组
int dis_data;                       //变量
//int   Temperature,Temp_h,Temp_l;  //温度及高低位数据
//****************************************
//函数声明
//****************************************
void  delay(unsigned int k);                                        //延时                       
void  lcd_printf(uchar *s,int temp_data);
 
//MPU6050操作函数
void  InitMPU6050();                                                  //初始化MPU6050
void  Delay5us();
void  I2C_Start();
void  I2C_Stop();
void  I2C_SendACK(bit ack);
bit   I2C_RecvACK();
void  I2C_SendByte(uchar dat);
uchar I2C_RecvByte();
void  I2C_ReadPage();
void  I2C_WritePage();
void  display_ACCEL_x();
void  display_ACCEL_y();
void  display_ACCEL_z();
uchar Single_ReadI2C(uchar REG_Address);                      //读取I2C数据
void  Single_WriteI2C(uchar REG_Address,uchar REG_data);    //向I2C写入数据
//****************************************
//整数转字符串
//****************************************
void lcd_printf(uchar *s,int temp_data)
{
    if(temp_data<0)
    {
        temp_data=-temp_data;
        *s='-';
    }
    else *s=' ';
 
    *++s =temp_data/10000+0x30;
    temp_data=temp_data%10000;     //取余运算
 
    *++s =temp_data/1000+0x30;
    temp_data=temp_data%1000;     //取余运算
 
    *++s =temp_data/100+0x30;
    temp_data=temp_data%100;     //取余运算
    *++s =temp_data/10+0x30;
    temp_data=temp_data%10;      //取余运算
    *++s =temp_data+0x30;    
}
//****************************************
 
void  SeriPushSend(uchar send_data)
{
    SBUF=send_data;  
    while(!TI);TI=0;      
}
//****************************************
//延时
//****************************************
void delay(unsigned int k)  
{                      
    unsigned int i,j;            
    for(i=0;i<k;i++)
    {          
        for(j=0;j<121;j++);
    }                      
}
 
//**************************************
//延时5微秒(STC90C52RC@12M)
//不同的工作环境,需要调整此函数
//当改用1T的MCU时,请调整此延时函数
//**************************************
void Delay5us()
{
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
}
//**************************************
//I2C起始信号
//**************************************
void I2C_Start()
{
    SDA = 1;                    //拉高数据线
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SDA = 0;                    //产生下降沿
    Delay5us();                 //延时
    SCL = 0;                    //拉低时钟线
}
//**************************************
//I2C停止信号
//**************************************
void I2C_Stop()
{
    SDA = 0;                    //拉低数据线
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SDA = 1;                    //产生上升沿
    Delay5us();                 //延时
}
//**************************************
//I2C发送应答信号
//入口参数:ack (0:ACK 1:NAK)
//**************************************
void I2C_SendACK(bit ack)
{
    SDA = ack;                  //写应答信号
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SCL = 0;                    //拉低时钟线
    Delay5us();                 //延时
}
//**************************************
//I2C接收应答信号
//**************************************
bit I2C_RecvACK()
{
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    CY = SDA;                   //读应答信号
    SCL = 0;                    //拉低时钟线
    Delay5us();                 //延时
    return CY;
}
//**************************************
//向I2C总线发送一个字节数据
//**************************************
void I2C_SendByte(uchar dat)
{
    uchar i;
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;              //移出数据的最高位
        SDA = CY;               //送数据口
        SCL = 1;                //拉高时钟线
        Delay5us();             //延时
        SCL = 0;                //拉低时钟线
        Delay5us();             //延时
    }
    I2C_RecvACK();
}
//**************************************
//从I2C总线接收一个字节数据
//**************************************
uchar I2C_RecvByte()
{
    uchar i;
    uchar dat = 0;
    SDA = 1;                    //使能内部上拉,准备读取数据,
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;
        SCL = 1;                //拉高时钟线
        Delay5us();             //延时
        dat |= SDA;             //读数据               
        SCL = 0;                //拉低时钟线
        Delay5us();             //延时
    }
    return dat;
}
//**************************************
//向I2C设备写入一个字节数据
//**************************************
void Single_WriteI2C(uchar REG_Address,uchar REG_data)
{
    I2C_Start();                  //起始信号
    I2C_SendByte(SlaveAddress);   //发送设备地址+写信号
    I2C_SendByte(REG_Address);    //内部寄存器地址,
    I2C_SendByte(REG_data);       //内部寄存器数据,
    I2C_Stop();                   //发送停止信号
}
//**************************************
//从I2C设备读取一个字节数据
//**************************************
uchar Single_ReadI2C(uchar REG_Address)
{
    uchar REG_data;
    I2C_Start();                   //起始信号
    I2C_SendByte(SlaveAddress);    //发送设备地址+写信号
    I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始
    I2C_Start();                   //起始信号
    I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号
    REG_data=I2C_RecvByte();       //读出寄存器数据
    I2C_SendACK(1);                //接收应答信号
    I2C_Stop();                    //停止信号
    return REG_data;
}
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050()
{
    Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态
    Single_WriteI2C(SMPLRT_DIV, 0x07);
    Single_WriteI2C(CONFIG, 0x06);
    Single_WriteI2C(GYRO_CONFIG, 0x18);
    Single_WriteI2C(ACCEL_CONFIG, 0x01);
}
//**************************************
//合成数据
//**************************************
int GetData(uchar REG_Address)
{
    uchar H,L;
    H=Single_ReadI2C(REG_Address);
    L=Single_ReadI2C(REG_Address+1);
    return (H<<8)+L;   //合成数据
}
//**************************************
//在1602上显示10位数据
//**************************************
void Display10BitData(int value,uchar x,uchar y)
{  uchar i;
//  value/=64;                          //转换为10位数据
    lcd_printf(dis, value);            //转换数据显示
    for(i=0;i<6;i++)
    {
    SeriPushSend(dis[i]);
    }
 
  //     DisplayListChar(x,y,dis,4); //启始列,行,显示数组,显示长度
}
//**************************************
//显示温度
//**************************************
//void display_temp()
//{ 
//  Temp_h=Single_ReadI2C(TEMP_OUT_H); //读取温度
//  Temp_l=Single_ReadI2C(TEMP_OUT_L); //读取温度
//  Temperature=Temp_h<<8|Temp_l;     //合成温度
//  Temperature = 35+ ((double) (Temperature + 13200)) / 280; // 计算出温度
//  lcd_printf(dis,Temperature);     //转换数据显示
//  DisplayListChar(11,1,dis,4);     //启始列,行,显示数组,显示位数
//}
 
void init_uart()
{
    TMOD=0x21;             
    TH1=0xfd;              
    TL1=0xfd;      
         
    SCON=0x50;
    PS=1;      //串口中断设为高优先级别
    TR0=1;     //启动定时器          
    TR1=1;
    ET0=1;     //打开定时器0中断         
    ES=1;  
    EA=1;
}
 
//*********************************************************
//主程序
//*********************************************************
void main()
{ 
    delay(500);     //上电延时     
//  InitLcd();      //液晶初始化
     init_uart();
    InitMPU6050();  //初始化MPU6050
    delay(150);
    while(1)
    {
     
        Display10BitData(GetData(ACCEL_XOUT_H),2,0);    //显示X轴加速度
        Display10BitData(GetData(ACCEL_YOUT_H),7,0);    //显示Y轴加速度
        Display10BitData(GetData(ACCEL_ZOUT_H),12,0);   //显示Z轴加速度
        Display10BitData(GetData(GYRO_XOUT_H),2,1); //显示X轴角速度
        Display10BitData(GetData(GYRO_YOUT_H),7,1); //显示Y轴角速度
        Display10BitData(GetData(GYRO_ZOUT_H),12,1);    //显示Z轴角速度
      
        SeriPushSend(0x0d); 
        SeriPushSend(0x0a);//换行,回车
        delay(100);
    }
}

 

lcd1602

//****************************************
// Update to MPU6050 by shinetop
// MCU: STC89C52
// 功能: 显示加速度计和陀螺仪的10位原始数据
//****************************************
// GY-52 MPU6050 IIC测试程序
// 使用单片机STC89C51 
// 晶振:11.0592M
// 显示:LCD1602
// 编译环境 Keil uVision3
//****************************************
#include <REG52.H>  
#include <math.h>    //Keil library  
#include <stdio.h>   //Keil library 
#include <INTRINS.H>
typedef unsigned char  uchar;
typedef unsigned short ushort;
typedef unsigned int   uint;
//****************************************
// 定义51单片机端口
//****************************************
#define DataPort P0       //LCD1602数据端口
sbit    SCL=P1^0;           //IIC时钟引脚定义
sbit    SDA=P1^1;           //IIC数据引脚定义
sbit    LCM_RS=P3^3;        //LCD1602命令端口      
sbit    LCM_RW=P3^4;        //LCD1602命令端口      
sbit    LCM_EN=P3^5;        //LCD1602命令端口 
//****************************************
// 定义MPU6050内部地址
//****************************************
#define SMPLRT_DIV      0x19    //陀螺仪采样率,典型值:0x07(125Hz)
#define CONFIG          0x1A    //低通滤波频率,典型值:0x06(5Hz)
#define GYRO_CONFIG     0x1B    //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define ACCEL_CONFIG    0x1C    //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define ACCEL_XOUT_H    0x3B
#define ACCEL_XOUT_L    0x3C
#define ACCEL_YOUT_H    0x3D
#define ACCEL_YOUT_L    0x3E
#define ACCEL_ZOUT_H    0x3F
#define ACCEL_ZOUT_L    0x40
#define TEMP_OUT_H      0x41
#define TEMP_OUT_L      0x42
#define GYRO_XOUT_H     0x43
#define GYRO_XOUT_L     0x44   
#define GYRO_YOUT_H     0x45
#define GYRO_YOUT_L     0x46
#define GYRO_ZOUT_H     0x47
#define GYRO_ZOUT_L     0x48
#define PWR_MGMT_1      0x6B    //电源管理,典型值:0x00(正常启用)
#define WHO_AM_I            0x75    //IIC地址寄存器(默认数值0x68,只读)
#define SlaveAddress    0xD0    //IIC写入时的地址字节数据,+1为读取
//****************************************
//定义类型及变量
//****************************************
uchar dis[4];                          //显示数字(-511至512)的字符数组
int dis_data;                       //变量
//int   Temperature,Temp_h,Temp_l;  //温度及高低位数据
//****************************************
//函数声明
//****************************************
void  delay(unsigned int k);                                        //延时
//LCD相关函数
void  InitLcd();                                                      //初始化lcd1602
void  lcd_printf(uchar *s,int temp_data);
void  WriteDataLCM(uchar dataW);                                 //LCD数据
void  WriteCommandLCM(uchar CMD,uchar Attribc);             //LCD指令
void  DisplayOneChar(uchar X,uchar Y,uchar DData);         //显示一个字符
void  DisplayListChar(uchar X,uchar Y,uchar *DData,L); //显示字符串
//MPU6050操作函数
void  InitMPU6050();                                                  //初始化MPU6050
void  Delay5us();
void  I2C_Start();
void  I2C_Stop();
void  I2C_SendACK(bit ack);
bit   I2C_RecvACK();
void  I2C_SendByte(uchar dat);
uchar I2C_RecvByte();
void  I2C_ReadPage();
void  I2C_WritePage();
void  display_ACCEL_x();
void  display_ACCEL_y();
void  display_ACCEL_z();
uchar Single_ReadI2C(uchar REG_Address);                      //读取I2C数据
void  Single_WriteI2C(uchar REG_Address,uchar REG_data);    //向I2C写入数据
//****************************************
//整数转字符串
//****************************************
void lcd_printf(uchar *s,int temp_data)
{
    if(temp_data<0)
    {
        temp_data=-temp_data;
        *s='-';
    }
    else *s=' ';
    *++s =temp_data/100+0x30;
    temp_data=temp_data%100;     //取余运算
    *++s =temp_data/10+0x30;
    temp_data=temp_data%10;      //取余运算
    *++s =temp_data+0x30;    
}
//****************************************
//延时
//****************************************
void delay(unsigned int k)  
{                      
    unsigned int i,j;            
    for(i=0;i<k;i++)
    {          
        for(j=0;j<121;j++);
    }                      
}
//****************************************
//LCD1602初始化
//****************************************
void InitLcd()            
{          
    WriteCommandLCM(0x38,1);   
    WriteCommandLCM(0x08,1);   
    WriteCommandLCM(0x01,1);   
    WriteCommandLCM(0x06,1);   
    WriteCommandLCM(0x0c,1);
    DisplayOneChar(0,0,'A');
    DisplayOneChar(0,1,'G');
}          
//****************************************
//LCD1602写允许
//****************************************
void WaitForEnable(void)  
{                  
    DataPort=0xff;     
    LCM_RS=0;LCM_RW=1;_nop_();
    LCM_EN=1;_nop_();_nop_();
    while(DataPort&0x80);  
    LCM_EN=0;              
}                  
//****************************************
//LCD1602写入命令
//****************************************
void WriteCommandLCM(uchar CMD,uchar Attribc)
{                  
    if(Attribc)WaitForEnable();
    LCM_RS=0;LCM_RW=0;_nop_();
    DataPort=CMD;_nop_();  
    LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}                  
//****************************************
//LCD1602写入数据
//****************************************
void WriteDataLCM(uchar dataW)
{                  
    WaitForEnable();       
    LCM_RS=1;LCM_RW=0;_nop_();
    DataPort=dataW;_nop_();
    LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}      
//****************************************
//LCD1602写入一个字符
//****************************************
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{                      
    Y&=1;                      
    X&=15;                     
    if(Y)X|=0x40;                  
    X|=0x80;           
    WriteCommandLCM(X,0);      
    WriteDataLCM(DData);       
}                      
//****************************************
//LCD1602显示字符串
//****************************************
void DisplayListChar(uchar X,uchar Y,uchar *DData,L)
{
    uchar ListLength=0; 
    Y&=0x1;                
    X&=0xF;                
    while(L--)             
    {                       
        DisplayOneChar(X,Y,DData[ListLength]);
        ListLength++;  
        X++;                        
    }    
}
//**************************************
//延时5微秒(STC90C52RC@12M)
//不同的工作环境,需要调整此函数
//当改用1T的MCU时,请调整此延时函数
//**************************************
void Delay5us()
{
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
}
//**************************************
//I2C起始信号
//**************************************
void I2C_Start()
{
    SDA = 1;                    //拉高数据线
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SDA = 0;                    //产生下降沿
    Delay5us();                 //延时
    SCL = 0;                    //拉低时钟线
}
//**************************************
//I2C停止信号
//**************************************
void I2C_Stop()
{
    SDA = 0;                    //拉低数据线
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SDA = 1;                    //产生上升沿
    Delay5us();                 //延时
}
//**************************************
//I2C发送应答信号
//入口参数:ack (0:ACK 1:NAK)
//**************************************
void I2C_SendACK(bit ack)
{
    SDA = ack;                  //写应答信号
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SCL = 0;                    //拉低时钟线
    Delay5us();                 //延时
}
//**************************************
//I2C接收应答信号
//**************************************
bit I2C_RecvACK()
{
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    CY = SDA;                   //读应答信号
    SCL = 0;                    //拉低时钟线
    Delay5us();                 //延时
    return CY;
}
//**************************************
//向I2C总线发送一个字节数据
//**************************************
void I2C_SendByte(uchar dat)
{
    uchar i;
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;              //移出数据的最高位
        SDA = CY;               //送数据口
        SCL = 1;                //拉高时钟线
        Delay5us();             //延时
        SCL = 0;                //拉低时钟线
        Delay5us();             //延时
    }
    I2C_RecvACK();
}
//**************************************
//从I2C总线接收一个字节数据
//**************************************
uchar I2C_RecvByte()
{
    uchar i;
    uchar dat = 0;
    SDA = 1;                    //使能内部上拉,准备读取数据,
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;
        SCL = 1;                //拉高时钟线
        Delay5us();             //延时
        dat |= SDA;             //读数据               
        SCL = 0;                //拉低时钟线
        Delay5us();             //延时
    }
    return dat;
}
//**************************************
//向I2C设备写入一个字节数据
//**************************************
void Single_WriteI2C(uchar REG_Address,uchar REG_data)
{
    I2C_Start();                  //起始信号
    I2C_SendByte(SlaveAddress);   //发送设备地址+写信号
    I2C_SendByte(REG_Address);    //内部寄存器地址,
    I2C_SendByte(REG_data);       //内部寄存器数据,
    I2C_Stop();                   //发送停止信号
}
//**************************************
//从I2C设备读取一个字节数据
//**************************************
uchar Single_ReadI2C(uchar REG_Address)
{
    uchar REG_data;
    I2C_Start();                   //起始信号
    I2C_SendByte(SlaveAddress);    //发送设备地址+写信号
    I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始
    I2C_Start();                   //起始信号
    I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号
    REG_data=I2C_RecvByte();       //读出寄存器数据
    I2C_SendACK(1);                //接收应答信号
    I2C_Stop();                    //停止信号
    return REG_data;
}
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050()
{
    Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态
    Single_WriteI2C(SMPLRT_DIV, 0x07);
    Single_WriteI2C(CONFIG, 0x06);
    Single_WriteI2C(GYRO_CONFIG, 0x18);
    Single_WriteI2C(ACCEL_CONFIG, 0x01);
}
//**************************************
//合成数据
//**************************************
int GetData(uchar REG_Address)
{
    char H,L;
    H=Single_ReadI2C(REG_Address);
    L=Single_ReadI2C(REG_Address+1);
    return (H<<8)+L;   //合成数据
}
//**************************************
//在1602上显示10位数据
//**************************************
void Display10BitData(int value,uchar x,uchar y)
{
    value/=64;                          //转换为10位数据
    lcd_printf(dis, value);            //转换数据显示
    DisplayListChar(x,y,dis,4); //启始列,行,显示数组,显示长度
}
//**************************************
//显示温度
//**************************************
//void display_temp()
//{ 
//  Temp_h=Single_ReadI2C(TEMP_OUT_H); //读取温度
//  Temp_l=Single_ReadI2C(TEMP_OUT_L); //读取温度
//  Temperature=Temp_h<<8|Temp_l;     //合成温度
//  Temperature = 35+ ((double) (Temperature + 13200)) / 280; // 计算出温度
//  lcd_printf(dis,Temperature);     //转换数据显示
//  DisplayListChar(11,1,dis,4);     //启始列,行,显示数组,显示位数
//}
//*********************************************************
//主程序
//*********************************************************
void main()
{ 
    delay(500);     //上电延时     
    InitLcd();      //液晶初始化
    InitMPU6050();  //初始化MPU6050
    delay(150);
    while(1)
    {
        Display10BitData(GetData(ACCEL_XOUT_H),2,0);    //显示X轴加速度
        Display10BitData(GetData(ACCEL_YOUT_H),7,0);    //显示Y轴加速度
        Display10BitData(GetData(ACCEL_ZOUT_H),12,0);   //显示Z轴加速度
        Display10BitData(GetData(GYRO_XOUT_H),2,1); //显示X轴角速度
        Display10BitData(GetData(GYRO_YOUT_H),7,1); //显示Y轴角速度
        Display10BitData(GetData(GYRO_ZOUT_H),12,1);    //显示Z轴角速度
        delay(500);
    }
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324441930&siteId=291194637
I2C