123bac 发表于 2013-1-31 20:40:08

mpu6050数据分析

{:sad:} 那位大师能把它改成串口调试助手显示数据的#include <REG52.H>       
#include <math.h>    //Keil library
#include <stdio.h>   //Keil library       
#include <INTRINS.H>
typedef unsigned charuchar;
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^6;                //LCD1602命令端口               
sbit    LCM_RW=P2^5;                //LCD1602命令端口               
sbit    LCM_EN=P2^7;                //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;                                                        //显示数字(-511至512)的字符数组
int        dis_data;                                                //变量
//int        Temperature,Temp_h,Temp_l;        //温度及高低位数据
//****************************************
//函数声明
//****************************************
voiddelay(unsigned int k);                                                                                //延时
//LCD相关函数
voidInitLcd();                                                                                                                //初始化lcd1602
voidlcd_printf(uchar *s,int temp_data);
voidWriteDataLCM(uchar dataW);                                                                        //LCD数据
voidWriteCommandLCM(uchar CMD,uchar Attribc);                                //LCD指令
voidDisplayOneChar(uchar X,uchar Y,uchar DData);                        //显示一个字符
voidDisplayListChar(uchar X,uchar Y,uchar *DData,L);        //显示字符串
//MPU6050操作函数
voidInitMPU6050();                                                                                                        //初始化MPU6050
voidDelay5us();
voidI2C_Start();
voidI2C_Stop();
voidI2C_SendACK(bit ack);
bit   I2C_RecvACK();
voidI2C_SendByte(uchar dat);
uchar I2C_RecvByte();
voidI2C_ReadPage();
voidI2C_WritePage();
voiddisplay_ACCEL_x();
voiddisplay_ACCEL_y();
voiddisplay_ACCEL_z();
uchar Single_ReadI2C(uchar REG_Address);                                                //读取I2C数据
voidSingle_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++;
                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(5000);
        }
}
       /*
    在论坛上潜水几个月了,跟大家学习两轮平衡车的制作,获益良多。
在调试传感器数据和滤波时写了一个串口工具,趁这个周末整理
了一下,共享出来,希望能对初学者们有所帮助。
    功能比较简单,主要是接收单片机发送来的3个整型数据,以图形显示。
可以向单片机发送几个字节,用作控制目的。单片机发送的数据以0xFF作为
帧结束标志,每个整型数以5个字节表示,具体参照下面的函数。
    没有经过全面测试,如果你想用但有bug,可以反馈给我 :)

                                           小皮2005
                                           2012.12.08                                                                                  


=============================================================
void Print_Show(int data1, int data2, int data3)
{
        SeriPush2Bytes(data1);             
        SeriPush2Bytes(data2);             
        SeriPush2Bytes(data3);             
        uart_transmit(0xff);
}


void SeriPush2Bytes(int value)
{
        unsigned char t_char;
        if(value < 0) {
                value = -value;
                uart_transmit(0xf0);
        }
        else {
                uart_transmit(0xf5);
        }
        t_char = value/256;
        if(t_char > 127)        uart_transmit(0x80);
        else        uart_transmit(0x00);
        uart_transmit(t_char & 0x7f);
        t_char = value%256;
        if(t_char > 127)        uart_transmit(0x80);
        else        uart_transmit(0x00);
        uart_transmit(t_char & 0x7f);
}

void uart_transmit(char c)
{
        while (!(UCSRA & DATA_REGISTER_EMPTY));
        UDR=c;
}

123bac 发表于 2013-1-31 21:44:27

不太成熟,希望多讨论和指点,谢谢大家。{:lol:}

liuhengpeng123 发表于 2013-1-31 22:08:53

给一堆代码就想吃现成饭?

123bac 发表于 2013-2-1 08:01:39

{:sad:}{:sad:}

123bac 发表于 2013-2-1 13:39:26

本帖最后由 123bac 于 2013-2-1 13:40 编辑

得到得的数据2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 0D 0A 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 20 30 30 35 31 31 2D 30 30 30 30 31 0D 0A 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 32 38 38 30 30 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 0D 0A 2D 30 30 31 32 39 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 0D 0A 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 31 35 33 37 30 0D 0A 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 32 31 31 2D 30 30 30 30 31 2D 30 30 30 30 31 0D 0A 2D 30 30 30 30 31 2D 30 32 33 30 35 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 0D 0A 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 0D 0A 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 34 37

123bac 发表于 2013-2-1 13:52:14

123bac 发表于 2013-2-1 13:53:13

波形{:smile:}{:huffy:}

30zero 发表于 2013-3-3 10:23:21

Mark学习了去

30zero 发表于 2013-3-3 11:25:32

123bac 发表于 2013-2-1 13:53 static/image/common/back.gif
波形

有没有波形那个软件

cgzasa 发表于 2013-4-1 09:21:35

123bac 发表于 2013-2-1 13:39 static/image/common/back.gif
得到得的数据2D 30 30 30 30 31 2D 30 30 30 30 31 2D 30 30 30 30 31 0D 0A 2D 30 30 30 30 31 2D 30 30 3 ...

你返回的数据,是16进制的数字,你以ascii码显示,或是字符方式显示,就是你能看懂的数值了。

cgzasa 发表于 2013-4-1 09:24:02

30zero 发表于 2013-3-3 11:25 static/image/common/back.gif
有没有波形那个软件

这有个波形软件,可以用,不知道能不能符合你要求。
英文网站,需要一点英文基础,看懂不难的。
https://code.google.com/p/serialchart/

shiruquaan23 发表于 2013-11-26 11:24:04

有没有角度补偿算法的呀

小四轴 发表于 2014-1-5 03:05:05

现在有个很好的显示波形的软件,匿名的四轴的上位机。我空间说说有图片,分别显示加速度和角度。
页: [1]
查看完整版本: mpu6050数据分析