找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3327|回复: 3
收起左侧

MPU6050的DMP,如何根据FIFO的42位数据得到四元数,解出欧拉角?

[复制链接]
ID:297166 发表于 2018-9-19 23:22 | 显示全部楼层 |阅读模式
新手上路,紧急求助……
最近要用MPU6050测物体的翻转角度,用的是51单片机,stc12c5a60s2。官方的库看不懂,在网上找到一个用于51的DMP初始化,但是得到的是一个来自于FIFO的42位数据。请问这个数据要怎么处理才能得到四元数,解出欧拉角?
而且在不做任何改动的情况下串口接收到的都是乱码,如何处理呢?
自己实在搞不清楚了,来求助万能的坛友们,希望个位大佬能给点宝贵的意见……
多谢了

下面贴下源码,来自于blog.csdn点net/ksws0263785/article/details/46462991

  1. /*****************************************************
  2. 功能: 采集MPU6050 DMP 数据
  3. CPU: STC89C54RD+
  4. 晶震: 11.0592
  5. 环境: Keli2.0
  6. 语言: c
  7. 作者:XW1005
  8. 来源:移植 Jeff Jrowberg 公开的程序。
  9. 目的:
  10. sda 或则scl 为高时是:释放总线
  11. *****************************************************/
  12. #include <reg52.h>
  13. #include <intrins.h>
  14. bit ack; //应答标志位 0:ack 1:nak
  15. sbit scl = P2^0;
  16. sbit sda = P2^1;
  17. unsigned char dmpdatas[42]; //DMP数据
  18. #define SlaveAddress 0xD0 //IIC写入时的地址字节数据,+1为读取
  19. //#define SlaveAddress 0xae //i2c测试地址
  20. void SendByte(unsigned char dat);
  21. unsigned char i2cread(unsigned char addr,unsigned char *Data);
  22. unsigned char i2creads(unsigned char addr,unsigned char length,unsigned char *Data);
  23. //以下的 firmware 及 config update 数据来自于 Jeff Jrowberg 公开的程序
  24. code unsigned char dmpmemorydata[1929]={
  25. // bank 0, 256 bytes
  26.     0xFB, 0x00, 0x00, 0x3E, 0x00, 0x0B, 0x00, 0x36, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,
  27.     0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0xFA, 0x80, 0x00, 0x0B, 0x12, 0x82, 0x00, 0x01,
  28.     0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  29.     0x00, 0x28, 0x00, 0x00, 0xFF, 0xFF, 0x45, 0x81, 0xFF, 0xFF, 0xFA, 0x72, 0x00, 0x00, 0x00, 0x00,
  30.     0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7F, 0xFF, 0xFF, 0xFE, 0x80, 0x01,
  31.     0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  32.     0x00, 0x3E, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xCA, 0xE3, 0x09, 0x3E, 0x80, 0x00, 0x00,
  33.     0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
  34.     0x41, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x2A, 0x00, 0x00, 0x16, 0x55, 0x00, 0x00, 0x21, 0x82,
  35.     0xFD, 0x87, 0x26, 0x50, 0xFD, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x05, 0x80, 0x00,
  36.     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
  37.     0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x6F, 0x00, 0x02, 0x65, 0x32, 0x00, 0x00, 0x5E, 0xC0,
  38.     0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  39.     0xFB, 0x8C, 0x6F, 0x5D, 0xFD, 0x5D, 0x08, 0xD9, 0x00, 0x7C, 0x73, 0x3B, 0x00, 0x6C, 0x12, 0xCC,
  40.     0x32, 0x00, 0x13, 0x9D, 0x32, 0x00, 0xD0, 0xD6, 0x32, 0x00, 0x08, 0x00, 0x40, 0x00, 0x01, 0xF4,
  41.     0xFF, 0xE6, 0x80, 0x79, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xD6, 0x00, 0x00, 0x27, 0x10,
  42.     // bank 1, 256 bytes
  43.     0xFB, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  44.     0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
  45.     0x00, 0x00, 0xFA, 0x36, 0xFF, 0xBC, 0x30, 0x8E, 0x00, 0x05, 0xFB, 0xF0, 0xFF, 0xD9, 0x5B, 0xC8,
  46.     0xFF, 0xD0, 0x9A, 0xBE, 0x00, 0x00, 0x10, 0xA9, 0xFF, 0xF4, 0x1E, 0xB2, 0x00, 0xCE, 0xBB, 0xF7,
  47.     0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x0C,
  48.     0xFF, 0xC2, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xCF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00,
  49.     0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14,
  50.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  52.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  53.     0x00, 0x00, 0x00, 0x00, 0x03, 0x3F, 0x68, 0xB6, 0x79, 0x35, 0x28, 0xBC, 0xC6, 0x7E, 0xD1, 0x6C,
  54.     0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x6A, 0x00, 0x00, 0x00, 0x00,
  55.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x30,
  56.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  57.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  58.     0x00, 0x00, 0x25, 0x4D, 0x00, 0x2F, 0x70, 0x6D, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x0C, 0x02, 0xD0,
  59.     // bank 2, 256 bytes
  60.     0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  61.     0x00, 0x00, 0x01, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00,
  62.     0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xFF, 0xEF, 0x00, 0x00,
  63.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  64.     0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  65.     0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  66.     0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  67.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  68.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  69.     0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  70.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  71.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
  72.     0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  73.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  74.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  75.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  76.     // bank 3, 256 bytes
  77.     0xD8, 0xDC, 0xBA, 0xA2, 0xF1, 0xDE, 0xB2, 0xB8, 0xB4, 0xA8, 0x81, 0x91, 0xF7, 0x4A, 0x90, 0x7F,
  78.     0x91, 0x6A, 0xF3, 0xF9, 0xDB, 0xA8, 0xF9, 0xB0, 0xBA, 0xA0, 0x80, 0xF2, 0xCE, 0x81, 0xF3, 0xC2,
  79.     0xF1, 0xC1, 0xF2, 0xC3, 0xF3, 0xCC, 0xA2, 0xB2, 0x80, 0xF1, 0xC6, 0xD8, 0x80, 0xBA, 0xA7, 0xDF,
  80.     0xDF, 0xDF, 0xF2, 0xA7, 0xC3, 0xCB, 0xC5, 0xB6, 0xF0, 0x87, 0xA2, 0x94, 0x24, 0x48, 0x70, 0x3C,
  81.     0x95, 0x40, 0x68, 0x34, 0x58, 0x9B, 0x78, 0xA2, 0xF1, 0x83, 0x92, 0x2D, 0x55, 0x7D, 0xD8, 0xB1,
  82.     0xB4, 0xB8, 0xA1, 0xD0, 0x91, 0x80, 0xF2, 0x70, 0xF3, 0x70, 0xF2, 0x7C, 0x80, 0xA8, 0xF1, 0x01,
  83.     0xB0, 0x98, 0x87, 0xD9, 0x43, 0xD8, 0x86, 0xC9, 0x88, 0xBA, 0xA1, 0xF2, 0x0E, 0xB8, 0x97, 0x80,
  84.     0xF1, 0xA9, 0xDF, 0xDF, 0xDF, 0xAA, 0xDF, 0xDF, 0xDF, 0xF2, 0xAA, 0xC5, 0xCD, 0xC7, 0xA9, 0x0C,
  85.     0xC9, 0x2C, 0x97, 0x97, 0x97, 0x97, 0xF1, 0xA9, 0x89, 0x26, 0x46, 0x66, 0xB0, 0xB4, 0xBA, 0x80,
  86.     0xAC, 0xDE, 0xF2, 0xCA, 0xF1, 0xB2, 0x8C, 0x02, 0xA9, 0xB6, 0x98, 0x00, 0x89, 0x0E, 0x16, 0x1E,
  87.     0xB8, 0xA9, 0xB4, 0x99, 0x2C, 0x54, 0x7C, 0xB0, 0x8A, 0xA8, 0x96, 0x36, 0x56, 0x76, 0xF1, 0xB9,
  88.     0xAF, 0xB4, 0xB0, 0x83, 0xC0, 0xB8, 0xA8, 0x97, 0x11, 0xB1, 0x8F, 0x98, 0xB9, 0xAF, 0xF0, 0x24,
  89.     0x08, 0x44, 0x10, 0x64, 0x18, 0xF1, 0xA3, 0x29, 0x55, 0x7D, 0xAF, 0x83, 0xB5, 0x93, 0xAF, 0xF0,
  90.     0x00, 0x28, 0x50, 0xF1, 0xA3, 0x86, 0x9F, 0x61, 0xA6, 0xDA, 0xDE, 0xDF, 0xD9, 0xFA, 0xA3, 0x86,
  91.     0x96, 0xDB, 0x31, 0xA6, 0xD9, 0xF8, 0xDF, 0xBA, 0xA6, 0x8F, 0xC2, 0xC5, 0xC7, 0xB2, 0x8C, 0xC1,
  92.     0xB8, 0xA2, 0xDF, 0xDF, 0xDF, 0xA3, 0xDF, 0xDF, 0xDF, 0xD8, 0xD8, 0xF1, 0xB8, 0xA8, 0xB2, 0x86,
  93.     // bank 4, 256 bytes
  94.     0xB4, 0x98, 0x0D, 0x35, 0x5D, 0xB8, 0xAA, 0x98, 0xB0, 0x87, 0x2D, 0x35, 0x3D, 0xB2, 0xB6, 0xBA,
  95.     0xAF, 0x8C, 0x96, 0x19, 0x8F, 0x9F, 0xA7, 0x0E, 0x16, 0x1E, 0xB4, 0x9A, 0xB8, 0xAA, 0x87, 0x2C,
  96.     0x54, 0x7C, 0xB9, 0xA3, 0xDE, 0xDF, 0xDF, 0xA3, 0xB1, 0x80, 0xF2, 0xC4, 0xCD, 0xC9, 0xF1, 0xB8,
  97.     0xA9, 0xB4, 0x99, 0x83, 0x0D, 0x35, 0x5D, 0x89, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0xB5, 0x93, 0xA3,
  98.     0x0E, 0x16, 0x1E, 0xA9, 0x2C, 0x54, 0x7C, 0xB8, 0xB4, 0xB0, 0xF1, 0x97, 0x83, 0xA8, 0x11, 0x84,
  99.     0xA5, 0x09, 0x98, 0xA3, 0x83, 0xF0, 0xDA, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xD8, 0xF1, 0xA5,
  100.     0x29, 0x55, 0x7D, 0xA5, 0x85, 0x95, 0x02, 0x1A, 0x2E, 0x3A, 0x56, 0x5A, 0x40, 0x48, 0xF9, 0xF3,
  101.     0xA3, 0xD9, 0xF8, 0xF0, 0x98, 0x83, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0x97, 0x82, 0xA8, 0xF1,
  102.     0x11, 0xF0, 0x98, 0xA2, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xDA, 0xF3, 0xDE, 0xD8, 0x83, 0xA5,
  103.     0x94, 0x01, 0xD9, 0xA3, 0x02, 0xF1, 0xA2, 0xC3, 0xC5, 0xC7, 0xD8, 0xF1, 0x84, 0x92, 0xA2, 0x4D,
  104.     0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9,
  105.     0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0x93, 0xA3, 0x4D,
  106.     0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9,
  107.     0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0xA8, 0x8A, 0x9A,
  108.     0xF0, 0x28, 0x50, 0x78, 0x9E, 0xF3, 0x88, 0x18, 0xF1, 0x9F, 0x1D, 0x98, 0xA8, 0xD9, 0x08, 0xD8,
  109.     0xC8, 0x9F, 0x12, 0x9E, 0xF3, 0x15, 0xA8, 0xDA, 0x12, 0x10, 0xD8, 0xF1, 0xAF, 0xC8, 0x97, 0x87,
  110.     // bank 5, 256 bytes
  111.     0x34, 0xB5, 0xB9, 0x94, 0xA4, 0x21, 0xF3, 0xD9, 0x22, 0xD8, 0xF2, 0x2D, 0xF3, 0xD9, 0x2A, 0xD8,
  112.     0xF2, 0x35, 0xF3, 0xD9, 0x32, 0xD8, 0x81, 0xA4, 0x60, 0x60, 0x61, 0xD9, 0x61, 0xD8, 0x6C, 0x68,
  113.     0x69, 0xD9, 0x69, 0xD8, 0x74, 0x70, 0x71, 0xD9, 0x71, 0xD8, 0xB1, 0xA3, 0x84, 0x19, 0x3D, 0x5D,
  114.     0xA3, 0x83, 0x1A, 0x3E, 0x5E, 0x93, 0x10, 0x30, 0x81, 0x10, 0x11, 0xB8, 0xB0, 0xAF, 0x8F, 0x94,
  115.     0xF2, 0xDA, 0x3E, 0xD8, 0xB4, 0x9A, 0xA8, 0x87, 0x29, 0xDA, 0xF8, 0xD8, 0x87, 0x9A, 0x35, 0xDA,
  116.     0xF8, 0xD8, 0x87, 0x9A, 0x3D, 0xDA, 0xF8, 0xD8, 0xB1, 0xB9, 0xA4, 0x98, 0x85, 0x02, 0x2E, 0x56,
  117.     0xA5, 0x81, 0x00, 0x0C, 0x14, 0xA3, 0x97, 0xB0, 0x8A, 0xF1, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9,
  118.     0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x84, 0x0D, 0xDA, 0x0E, 0xD8, 0xA3, 0x29, 0x83, 0xDA,
  119.     0x2C, 0x0E, 0xD8, 0xA3, 0x84, 0x49, 0x83, 0xDA, 0x2C, 0x4C, 0x0E, 0xD8, 0xB8, 0xB0, 0xA8, 0x8A,
  120.     0x9A, 0xF5, 0x20, 0xAA, 0xDA, 0xDF, 0xD8, 0xA8, 0x40, 0xAA, 0xD0, 0xDA, 0xDE, 0xD8, 0xA8, 0x60,
  121.     0xAA, 0xDA, 0xD0, 0xDF, 0xD8, 0xF1, 0x97, 0x86, 0xA8, 0x31, 0x9B, 0x06, 0x99, 0x07, 0xAB, 0x97,
  122.     0x28, 0x88, 0x9B, 0xF0, 0x0C, 0x20, 0x14, 0x40, 0xB8, 0xB0, 0xB4, 0xA8, 0x8C, 0x9C, 0xF0, 0x04,
  123.     0x28, 0x51, 0x79, 0x1D, 0x30, 0x14, 0x38, 0xB2, 0x82, 0xAB, 0xD0, 0x98, 0x2C, 0x50, 0x50, 0x78,
  124.     0x78, 0x9B, 0xF1, 0x1A, 0xB0, 0xF0, 0x8A, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x8B, 0x29, 0x51, 0x79,
  125.     0x8A, 0x24, 0x70, 0x59, 0x8B, 0x20, 0x58, 0x71, 0x8A, 0x44, 0x69, 0x38, 0x8B, 0x39, 0x40, 0x68,
  126.     0x8A, 0x64, 0x48, 0x31, 0x8B, 0x30, 0x49, 0x60, 0xA5, 0x88, 0x20, 0x09, 0x71, 0x58, 0x44, 0x68,
  127.     // bank 6, 256 bytes
  128.     0x11, 0x39, 0x64, 0x49, 0x30, 0x19, 0xF1, 0xAC, 0x00, 0x2C, 0x54, 0x7C, 0xF0, 0x8C, 0xA8, 0x04,
  129.     0x28, 0x50, 0x78, 0xF1, 0x88, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xAC, 0x8C, 0x02, 0x26, 0x46, 0x66,
  130.     0xF0, 0x89, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31,
  131.     0xA9, 0x88, 0x09, 0x20, 0x59, 0x70, 0xAB, 0x11, 0x38, 0x40, 0x69, 0xA8, 0x19, 0x31, 0x48, 0x60,
  132.     0x8C, 0xA8, 0x3C, 0x41, 0x5C, 0x20, 0x7C, 0x00, 0xF1, 0x87, 0x98, 0x19, 0x86, 0xA8, 0x6E, 0x76,
  133.     0x7E, 0xA9, 0x99, 0x88, 0x2D, 0x55, 0x7D, 0x9E, 0xB9, 0xA3, 0x8A, 0x22, 0x8A, 0x6E, 0x8A, 0x56,
  134.     0x8A, 0x5E, 0x9F, 0xB1, 0x83, 0x06, 0x26, 0x46, 0x66, 0x0E, 0x2E, 0x4E, 0x6E, 0x9D, 0xB8, 0xAD,
  135.     0x00, 0x2C, 0x54, 0x7C, 0xF2, 0xB1, 0x8C, 0xB4, 0x99, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0x81, 0x91,
  136.     0xAC, 0x38, 0xAD, 0x3A, 0xB5, 0x83, 0x91, 0xAC, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, 0x48, 0xD8,
  137.     0x6D, 0xD9, 0x68, 0xD8, 0x8C, 0x9D, 0xAE, 0x29, 0xD9, 0x04, 0xAE, 0xD8, 0x51, 0xD9, 0x04, 0xAE,
  138.     0xD8, 0x79, 0xD9, 0x04, 0xD8, 0x81, 0xF3, 0x9D, 0xAD, 0x00, 0x8D, 0xAE, 0x19, 0x81, 0xAD, 0xD9,
  139.     0x01, 0xD8, 0xF2, 0xAE, 0xDA, 0x26, 0xD8, 0x8E, 0x91, 0x29, 0x83, 0xA7, 0xD9, 0xAD, 0xAD, 0xAD,
  140.     0xAD, 0xF3, 0x2A, 0xD8, 0xD8, 0xF1, 0xB0, 0xAC, 0x89, 0x91, 0x3E, 0x5E, 0x76, 0xF3, 0xAC, 0x2E,
  141.     0x2E, 0xF1, 0xB1, 0x8C, 0x5A, 0x9C, 0xAC, 0x2C, 0x28, 0x28, 0x28, 0x9C, 0xAC, 0x30, 0x18, 0xA8,
  142.     0x98, 0x81, 0x28, 0x34, 0x3C, 0x97, 0x24, 0xA7, 0x28, 0x34, 0x3C, 0x9C, 0x24, 0xF2, 0xB0, 0x89,
  143.     0xAC, 0x91, 0x2C, 0x4C, 0x6C, 0x8A, 0x9B, 0x2D, 0xD9, 0xD8, 0xD8, 0x51, 0xD9, 0xD8, 0xD8, 0x79,
  144.     // bank 7, 138 bytes (remainder)
  145.     0xD9, 0xD8, 0xD8, 0xF1, 0x9E, 0x88, 0xA3, 0x31, 0xDA, 0xD8, 0xD8, 0x91, 0x2D, 0xD9, 0x28, 0xD8,
  146.     0x4D, 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x83, 0x93, 0x35, 0x3D, 0x80, 0x25, 0xDA,
  147.     0xD8, 0xD8, 0x85, 0x69, 0xDA, 0xD8, 0xD8, 0xB4, 0x93, 0x81, 0xA3, 0x28, 0x34, 0x3C, 0xF3, 0xAB,
  148.     0x8B, 0xF8, 0xA3, 0x91, 0xB6, 0x09, 0xB4, 0xD9, 0xAB, 0xDE, 0xFA, 0xB0, 0x87, 0x9C, 0xB9, 0xA3,
  149.     0xDD, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x95, 0xF1, 0xA3, 0xA3, 0xA3, 0x9D, 0xF1, 0xA3, 0xA3, 0xA3,
  150.     0xA3, 0xF2, 0xA3, 0xB4, 0x90, 0x80, 0xF2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
  151.     0xA3, 0xB2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xB0, 0x87, 0xB5, 0x99, 0xF1, 0xA3, 0xA3, 0xA3,
  152.     0x98, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x97, 0xA3, 0xA3, 0xA3, 0xA3, 0xF3, 0x9B, 0xA3, 0xA3, 0xDC,
  153.     0xB9, 0xA7, 0xF1, 0x26, 0x26, 0x26, 0xD8, 0xD8, 0xFF
  154. };
  155. code unsigned char dmpcfgupddata[192] = {
  156. //  dmp config
  157. //  BANK    OFFSET  LENGTH  [DATA]
  158.     0x03,   0x7B,   0x03,   0x4C, 0xCD, 0x6C,         
  159.     0x03,   0xAB,   0x03,   0x36, 0x56, 0x76,         
  160.     0x00,   0x68,   0x04,   0x02, 0xCB, 0x47, 0xA2,   
  161.     0x02,   0x18,   0x04,   0x00, 0x05, 0x8B, 0xC1,   
  162.     0x01,   0x0C,   0x04,   0x00, 0x00, 0x00, 0x00,   
  163.     0x03,   0x7F,   0x06,   0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97,
  164.     0x03,   0x89,   0x03,   0x26, 0x46, 0x66,         
  165.     0x00,   0x6C,   0x02,   0x20, 0x00,               
  166.     0x02,   0x40,   0x04,   0x00, 0x00, 0x00, 0x00,   
  167.     0x02,   0x44,   0x04,   0x00, 0x00, 0x00, 0x00,   
  168.     0x02,   0x48,   0x04,   0x00, 0x00, 0x00, 0x00,   
  169.     0x02,   0x4C,   0x04,   0x00, 0x00, 0x00, 0x00,   
  170.     0x02,   0x50,   0x04,   0x00, 0x00, 0x00, 0x00,   
  171.     0x02,   0x54,   0x04,   0x00, 0x00, 0x00, 0x00,  
  172.     0x02,   0x58,   0x04,   0x00, 0x00, 0x00, 0x00,  
  173.     0x02,   0x5C,   0x04,   0x00, 0x00, 0x00, 0x00,  
  174.     0x02,   0xBC,   0x04,   0x00, 0x00, 0x00, 0x00,   
  175.     0x01,   0xEC,   0x04,   0x00, 0x00, 0x40, 0x00,  
  176.     0x03,   0x7F,   0x06,   0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97,
  177.     0x04,   0x02,   0x03,   0x0D, 0x35, 0x5D,         
  178.     0x04,   0x09,   0x04,   0x87, 0x2D, 0x35, 0x3D,   
  179.     0x00,   0xA3,   0x01,   0x00,                    
  180.     0x00,   0x00,   0x00,   0x01,  //这里是开启DMP的特殊中断的
  181.     //原程序中此行代码为(这里不一定错)
  182.     //0x00,   0x00,   0x00,   0x01,  即LENGTH=0x00,有错

  183.     0x07,   0x86,   0x01,   0xFE,                     
  184.     0x07,   0x41,   0x05,   0xF1, 0x20, 0x28, 0x30, 0x38,
  185.     0x07,   0x7E,   0x01,   0x30,                  
  186.     0x07,   0x46,   0x01,   0x9A,                    
  187.     0x07,   0x47,   0x04,   0xF1, 0x28, 0x30, 0x38,   
  188.     0x07,   0x6C,   0x04,   0xF1, 0x28, 0x30, 0x38,  
  189.     0x02,   0x16,   0x02,   0x00, 0x01,              
  190. /* 上行最后一个数据调整FIFO rate :0x01=100HZ,0x02=66HZ,0x03=50HZ ,0x04=40HZ,0x05=33.33HZ,
  191. // 可从 datasheet 公式推算
  192. //dmp updates
  193.     0x01,   0xB2,   0x02,   0xFF, 0xFF,
  194.     0x01,   0x90,   0x04,   0x09, 0x23, 0xA1, 0x35,
  195.     0x01,   0x6A,   0x02,   0x06, 0x00,
  196.     0x01,   0x60,   0x08,   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  197.     0x00,   0x60,   0x04,   0x40, 0x00, 0x00, 0x00,
  198.     0x01,   0x62,   0x02,   0x00, 0x00,
  199.     0x00,   0x60,   0x04,   0x00, 0x40, 0x00, 0x00*/
  200. };
  201. code unsigned char dmpUpdates[47]={

  202.     0x01,   0xB2,   0x02,   0xFF, 0xFF,
  203.     0x01,   0x90,   0x04,   0x09, 0x23, 0xA1, 0x35,
  204.     0x01,   0x6A,   0x02,   0x06, 0x00,
  205.     0x01,   0x60,   0x08,   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  206.     0x00,   0x60,   0x04,   0x40, 0x00, 0x00, 0x00,
  207.     0x01,   0x62,   0x02,   0x00, 0x00,
  208.     0x00,   0x60,   0x04,   0x00, 0x40, 0x00, 0x00

  209. };
  210. void DelayUs2x(unsigned char t) //延时1
  211. {   
  212. while(--t);
  213. }

  214. void DelayMs(unsigned char t) //延时2
  215. {

  216. while(t--)
  217. {
  218.      //大致延时1mS
  219.      DelayUs2x(245);
  220.   DelayUs2x(245);
  221. }
  222. }

  223. /*i2c基本协议*/
  224. /*i2c基本协议*/
  225. void i2_qs(void) //启始信号
  226. {
  227. sda = 1;
  228. scl = 1;
  229. _nop_();
  230. sda = 0;
  231. _nop_();_nop_();
  232. _nop_();_nop_();
  233. scl = 0;
  234. }

  235. void i2_tz() //停止信号
  236. {
  237. sda = 0;
  238. scl = 1;
  239. _nop_();_nop_();
  240. _nop_();_nop_();
  241. sda = 1;
  242. _nop_();
  243. }
  244. void i2_fs(unsigned char Data) //发送8位数据
  245. {
  246. unsigned char i=0;
  247. for(;i<8;i++)
  248. {
  249.   Data <<= 1;
  250.   sda = CY;
  251.   scl = 1;
  252.   _nop_();_nop_();
  253.   _nop_();_nop_();
  254.   scl = 0;

  255. }
  256. //下面是接收从设备发回的应答信号
  257. sda = 1;
  258. scl = 1;
  259. _nop_();_nop_();
  260. _nop_();_nop_();
  261. ack = sda; //接收设备的ack _n
  262. scl = 0;
  263. sda = 1;
  264. }

  265. unsigned char i2_js(bit _ack) //接收8位数据
  266. {
  267. unsigned char i = 0,Data = 0;
  268. for(;i<8;i++)
  269. {
  270.   Data <<= 1;
  271.   scl = 1;
  272.   _nop_();_nop_();
  273.   _nop_();_nop_();
  274.   Data |= sda; //接收数据
  275.   scl = 0;
  276.   _nop_();
  277. }
  278. //下面时主控器发送ACK或则NAK
  279. sda = _ack; //ack或者nak
  280. scl = 1; //拉高时钟产生第9个时钟
  281. _nop_();_nop_();
  282. _nop_();_nop_();
  283. scl = 0; //拉底时钟
  284. sda = 1; //释放总线
  285. _nop_();
  286. return Data;
  287. }
  288. /*i2c协议基本*/

  289. /*写入8位寄存器一个字节
  290.   参数 addr 寄存器地址
  291.   参数 Data 写入数据
  292.   返回值 (1=成功,0=失败)
  293. */
  294. unsigned char i2cwrite(unsigned char addr,unsigned char Data) //写入8位有效数据
  295. {
  296. i2_qs(); //起始信号
  297. i2_fs(SlaveAddress); //设备地址+写信号
  298. if(ack) return 0; //判断是否是ACK如果不是返回0
  299. i2_fs(addr); //设备内部地址
  300. if(ack) return 0;
  301. i2_fs(Data); //写入的数据
  302. if(ack) return 0;
  303. i2_tz(); //停止信号
  304. return 1;
  305. }
  306. /*读取8位寄存器一个字节
  307.   参数 addr 寄存器地址
  308.   参数 *Data 数据存储地址
  309.   返回值 (1=成功,0=失败)
  310. */
  311. unsigned char i2cread(unsigned char addr,unsigned char *Data)
  312. {
  313. /*unsigned char Data1;
  314. i2_qs(); //起始信号
  315. i2_fs(SlaveAddress); //设备地址+写信号
  316. SendByte(ack);
  317. i2_fs(addr); //设备内部地址
  318. i2_qs(); //起始信号
  319. i2_fs(SlaveAddress+1); //设备地址+读信号
  320. *Data = i2_js(1); //读取数据
  321. i2_tz(); //停止信号*/
  322. return i2creads(addr,1,Data);
  323. }
  324. /*读取8位寄存器多个字节
  325. * @参数 addr    I2C从器件内部地址
  326. * @参数 length  写入数据长度   
  327. * @参数 Data    保存数据的地址      
  328. * @返回值 返回状态 (1=成功)
  329. */
  330. unsigned char i2creads(unsigned char addr,unsigned char length,unsigned char *Data)
  331. {
  332.   unsigned char i;
  333.   length --;
  334.   i2_qs(); //起始信号
  335.   i2_fs(SlaveAddress); //设备地址+写信号
  336.   if(ack) return 0;
  337.   i2_fs(addr); //设备内部地址
  338.   if(ack) return 0;
  339.   i2_qs(); //起始信号
  340.   i2_fs(SlaveAddress+1); //设备地址+读信号
  341.   if(ack) return 0;
  342.   for(i=0;i<length;i++)
  343.   {
  344.    Data[i]= i2_js(0); //读取数据,发送ACK
  345.   }
  346.   Data[length] = i2_js(1);//读取数据,发送NAK
  347.   i2_tz(); //停止信号
  348.   return 1;
  349. }

  350. /**写入8位寄存器的一个位。
  351. * @参数 addr    I2C从器件内部地址
  352. * @参数 bitNum  写入的比特位(0-7)     
  353. * @参数 data    写入数据      
  354. * @返回值 返回状态 (1=成功)
  355. */
  356. unsigned char writeBit(unsigned char addr,unsigned char bitNum,unsigned char Data)
  357. {
  358. unsigned char b;
  359. if (i2cread(addr,&b))
  360.   {
  361.    b = (Data != 0) ? (b | (1 << bitNum)):(b & ~(1 << bitNum));
  362.    return i2cwrite(addr,b); //写入数据
  363.   }
  364. else
  365.   return 0;
  366. }
  367. /**写入8位寄存器的多个位。  
  368. * @参数 addr     I2C从器件内部地址
  369. * @参数 bitStart 第一位的写入位置(0-7)
  370. * @参数 length   写的比特数(不超过8)
  371. * @参数 Data     写入数据
  372. * @返回值 返回状态 (1=成功)
  373. */
  374. unsigned char writeBits(unsigned char addr,unsigned char bitStart,unsigned char length,unsigned char Data)
  375. {
  376.   //      010 要写入的值
  377.     // 76543210 比特位
  378.     //    xxx   args: bitStart=4, length=3
  379.     // 00011100 掩码字节
  380.     // 10101111 原始值(样本)
  381.     // 10100011 原始值 & ~掩码
  382.     // 10101011 掩码 | 原始值
  383. unsigned char b,mask=0;
  384. if (i2cread(addr,&b))
  385. {
  386.   mask = (((1<<length) - 1) << (bitStart-length + 1)); //掩码
  387.   Data <<=(bitStart - length + 1); //把写入的数据移动到位
  388.   Data &= mask;
  389.   b &= ~(mask);
  390.   b |= Data;
  391.   i2cwrite(addr,b); //写入数据
  392.   return 1;
  393. }
  394. else
  395.   return 0;
  396. }
  397. /**读取一个位从8位器件的寄存器。  
  398. * @参数 addr    I2C从器件内部地址
  399. * @参数 bitNum  位的位置来读取(0-7)
  400. * @参数 *data   数据存储地址  
  401. * @返回值(1=成功)
  402. */
  403. unsigned char readBit(unsigned char addr,unsigned char bitNum,unsigned char *Data)
  404. {
  405. unsigned char b;
  406. if(i2cread(addr,&b))
  407. {
  408.   *Data = b & (1 << bitNum);
  409.   return 1;
  410. }
  411. else
  412. {
  413.   return 0;
  414. }
  415. }
  416. /**读取8位寄存器的多个位。
  417. * @参数 addr    I2C从器件内部地址
  418. * @参数 bitStart第一位的位置读取(0-7)
  419. * @参数 length  位读取@参数长度数(不超过8)
  420. * @参数 *data   数据存储地址(即'101'任何bitStart位置读取将等于0X05)
  421. * @返回值(1=成功)
  422. */
  423. unsigned char readBits(unsigned char addr,unsigned char bitStart,unsigned char length,unsigned char *Data)
  424. {
  425.   // 01101001 读取字节
  426.     // 76543210 比特位
  427.     //    xxx   args: bitStart=4, length=3
  428.     //    010   masked
  429.     //   -> 010 shifted
  430. unsigned char b,mask=0;
  431. if(i2cread(addr,&b))
  432. {

  433.   mask = ((1 << length) - 1) << (bitStart - length + 1);
  434.   b &= mask;
  435.   b >>= (bitStart - length + 1);
  436.   *Data = b;
  437.   return 1;
  438. }
  439. else
  440.   return 0;
  441. }


  442. /*void init6050() //初始化 6050
  443. {
  444.   i2cwrite(0x6b,0x80);                 //电源管理(0x00 正常启用)                  

  445.   i2cwrite(0x6b ,0x01);                          //No sleep  , 3 PLL with X axis gyroscope reference电源管理
  446.   DelayMs(200);
  447.   i2cwrite(0x23 ,0x00);                          //FIFO 11111000 ,temp,gx,gy,gz,accel?
  448.   i2cwrite(0x19 ,0x05);                          //陀螺仪采样率
  449.   i2cwrite(0x1a ,0x03);                          //低通滤波
  450.   i2cwrite(0x1b ,0x18);                          //陀螺仪自检,量程范围 2000 /s
  451.   i2cwrite(0x1c ,0x00);                          //加速计自检,量程范围及 高通滤波频率 +-2g/s
  452. }
  453. */

  454. /*
  455.    加载 DMP代码到
  456.    返回值  (1=成功,0=失败)
  457. */
  458. unsigned char loadfirmware(void)
  459. {
  460.   unsigned int datanum=0; //DMP固件写入标志位
  461.   unsigned char ye,i,j;
  462.   unsigned char bank=0; //段(256个数据一段)
  463.   unsigned char addr=0;

  464. for(;bank<8;bank++)
  465. {
  466.   if(bank == 7) //这里的作用就是区分最后一段数据
  467.    i = 8;
  468.   else
  469.    i = 16;
  470.   for(ye=0;ye<i;ye++)
  471.   {
  472.    i2cwrite(0x6d,bank);
  473.    i2cwrite(0x6e,addr);
  474.    i2_qs(); //起始信号
  475.    i2_fs(SlaveAddress); //设备地址+写信号
  476.    i2_fs(0x6f); //设备内部地址
  477.    for(j=0;j<16;j++)
  478.    {
  479.     i2_fs(dmpmemorydata[datanum++]); //写入DMP的数据
  480.     if(ack) return 0;
  481.    }
  482.    addr += 16;
  483.    i2_tz(); //停止信号
  484.   }
  485. }
  486. i2cwrite(0x6d,7);
  487. i2cwrite(0x6e,addr);
  488. i2_qs(); //起始信号
  489. i2_fs(SlaveAddress); //设备地址+写信号
  490. i2_fs(0x6f); //设备内部地址
  491. for(i=0;i<9;i++)
  492. {
  493.   i2_fs(dmpmemorydata[datanum++]); //写入DMP的数据
  494.   if(ack) return 0;
  495. }
  496. i2_tz(); //停止信号
  497. return 1;
  498. }
  499. unsigned char loadcfgupd(void) //DMP设置
  500. {
  501.   unsigned char line; //一共需要写入30条设置数据
  502.   unsigned char bank; //页
  503.   unsigned char datacounts=0; //DMP设置数据标志位
  504.   unsigned char bytes2write; //数据长度。
  505.   unsigned char offset; //偏移地址
  506.   unsigned char writingcounts; //数据写入标志与bytes2write一同使用
  507.   unsigned char special;

  508.   for (line=0;line<30;line++)
  509.   {
  510.    bank=dmpcfgupddata[datacounts++];
  511.    offset=dmpcfgupddata[datacounts++];
  512.    bytes2write=dmpcfgupddata[datacounts++];
  513.    i2cwrite(0x6d,bank);
  514.    i2cwrite(0x6e,offset);
  515.    i2_qs(); //起始信号
  516.   i2_fs(SlaveAddress); //设备地址+写信号
  517.   i2_fs(0x6f); //设备内部地址
  518.    for(writingcounts=0;writingcounts<bytes2write;writingcounts++)
  519.    {
  520.     i2_fs(dmpcfgupddata[datacounts++]); //写入DMP配置数据
  521.    if(ack) return 0;
  522.    }
  523.    if(0 == bytes2write)
  524.    {
  525.     special=dmpcfgupddata[datacounts++];
  526.     if(0x01 == special)
  527.      {
  528.       //设置零运动中断启用(真);
  529.           //设置FIFO缓冲区溢出启用(真);
  530.           //设置DMP启用(真);
  531.       i2cwrite(0x38,0x32);
  532.      }
  533.     else
  534.      return 0;
  535.    }
  536.   }
  537.   i2_tz(); //停止信号
  538. return 1;
  539. }
  540. /*最后更新DMP*/
  541. unsigned char xdmpUpdates(unsigned char datacounts)
  542. {
  543. unsigned char writingcounts,bank,offset,bytes2write;
  544. bank=dmpUpdates[datacounts++];
  545.   offset=dmpUpdates[datacounts++];
  546.   bytes2write=dmpUpdates[datacounts++];
  547.   i2cwrite(0x6d,bank);
  548.   i2cwrite(0x6e,offset);
  549.   i2_qs(); //起始信号
  550. i2_fs(SlaveAddress); //设备地址+写信号
  551. i2_fs(0x6f); //设备内部地址
  552. for(writingcounts=0;writingcounts<bytes2write;writingcounts++)
  553.    {
  554.     i2_fs(dmpUpdates[datacounts++]); //写入DMP配置数据
  555.    if(ack) return 0;
  556.    }
  557.    i2_tz(); //停止信号
  558.    return 0;
  559. }
  560. /*读取 FIFO 计数*/
  561. unsigned int getFIFOCount()
  562. {
  563. unsigned char i[2];
  564. i2creads(0x72,2,i);
  565. return ((i[0]<<8)+i[1]);
  566. }
  567. /*FIFO数据读取
  568. 参数 *Data 存储数据的地址
  569. 返回值 (1=读取成功,0读取失败)
  570. */
  571. unsigned char readdmp(unsigned char *Data)
  572. {
  573.   return i2creads(0x74,42,Data);
  574. }

  575. //加载并配置 DMP 数字运动处理引擎
  576. unsigned char dmpInitialize(void)
  577. {
  578. unsigned char hwRevision,otpValid,mpuIntStatus/*fifoBuffer[128]*/;
  579. unsigned char xgOffsetTC,ygOffsetTC,zgOffsetTC;
  580. unsigned int fifoCount;
  581. writeBit(0x6B,7,1); //复位 MPU6050
  582. DelayMs(30);
  583. writeBit(0x6B,6,0); //禁止睡眠模式
  584. i2cwrite(0x6D,0x70); //写入一个字节数据到0x6d寄存器(选择用户 bank)
  585. i2cwrite(0x6E,0x06); //写入一个字节数据到0x6e寄存器(选择存储字节)
  586. i2cread(0x6F,&hwRevision); //读取
  587. i2cwrite(0x6D,0); //重置内存 bank 选择
  588. readBit(0x00,0,&otpValid); //读取 OTP bank 有效标志
  589. readBits(0x00,6,6,&xgOffsetTC); //读陀螺偏置TC值 X
  590. readBits(0x01,6,6,&ygOffsetTC); //读陀螺偏置TC值 Y)
  591. readBits(0x02,6,6,&zgOffsetTC); //读陀螺偏置TC值 Z
  592. i2cwrite(0x25,0x7f); //设置从0地址 0x7
  593. writeBit(0x6A,5,0); //禁用I2C主模式
  594. i2cwrite(0x25,0x68); //这里可能要改。还没有弄明白这里
  595. writeBit(0x6A,1,1); //I2C总线主控复位
  596. DelayMs(20);
  597. if((loadfirmware()) == 0 ) return 0; //加载 DMP代码到内存
  598. if((loadcfgupd()) == 0 ) return 0; //配制DMP
  599. writeBits(0x6B,2,3,0x03); //设置时钟脉冲源Z陀螺
  600. i2cwrite(0x38,0x12); //设置DMP和FIFO_OFLOW启用中断
  601. i2cwrite(0x19,4); //设置采样率为200 hz  (1khz / (1 + 4) = 200 Hz)
  602. writeBits(0x1A,5,3,0x1); //设置外部帧同步TEMP_OUT_L[0]
  603. writeBits(0x1A,2,3,0x03); //设置DLPF带宽42赫兹
  604. writeBits(0x1B,4,2,0x03); //陀螺灵敏度设置为+ / - 2000 deg/sec
  605. i2cwrite(0x70,0x03); //设置DMP配置字节(功能未知)
  606. i2cwrite(0x71,0x00); //设置DMP配置字节(功能未知)
  607. writeBit(0x00,0,0); //清除OTP Bank 标志
  608. writeBits(0x00,6,6,xgOffsetTC); //设置X 陀螺抵消TCs之前的值
  609. writeBits(0x01,6,6,ygOffsetTC); //设置Y 陀螺抵消TCs之前的值
  610. writeBits(0x02,6,6,zgOffsetTC); //设置Z 陀螺抵消TCs之前的值
  611. xdmpUpdates(0); //最后更新1/7(函数未知)dmpUpdates数组第一行
  612. xdmpUpdates(5); //最后更新2/7(函数未知)dmpUpdates数组第二行
  613. writeBit(0x6A,2,1); //复位 FIFO
  614. fifoCount = getFIFOCount(); //读取 FIFO 计数
  615. //readdmp(fifoCount,fifoBuffer); //读取FIFO里的数据
  616. writeBit(0x6A,2,1); //复位 FIFO

  617. i2cwrite(0x1F,2); //运动检测阈值设置为2
  618. i2cwrite(0x21,156); //零运动检测阈值为156
  619. i2cwrite(0x20,80); //设置运动检测持续时间至80
  620. i2cwrite(0x22,0); //设置零运动检测时间0
  621. writeBit(0x6A,2,1); //复位 FIFO
  622. writeBit(0x6A,6,1); //使能 FIFO
  623. writeBit(0x6A,7,1); //使能 DMP
  624. writeBit(0x6A,3,1); //复位 DMP
  625. xdmpUpdates(12); //最后更新3/7(函数未知)dmpUpdates数组第三行
  626. xdmpUpdates(17); //最后更新4/7(函数未知)dmpUpdates数组第四行
  627. xdmpUpdates(28); //最后更新5/7(函数未知)dmpUpdates数组第五行
  628. while((fifoCount = getFIFOCount()) < 3); //等待 FIFO 计数 > 2
  629. writeBit(0x6A,2,1); //复位 FIFO
  630. //readdmp(fifoCount,fifoBuffer); //读取FIFO里的数据
  631. i2cread(0x3A,&mpuIntStatus); //读取中断状态
  632. xdmpUpdates(35); //最后更新6/7(函数未知)dmpUpdates数组第六行
  633. while((fifoCount = getFIFOCount()) < 3); //等待 FIFO 计数 > 2
  634. writeBit(0x6A,2,1); //复位 FIFO
  635. //readdmp(fifoCount,fifoBuffer); //读取FIFO里的数据
  636. i2cread(0x3A,&mpuIntStatus); //读取中断状态
  637. xdmpUpdates(40); //最后更新7/7(函数未知)dmpUpdates数组第七行
  638. writeBit(0x6A,7,0); //禁用DMP(稍后您打开它)
  639. writeBit(0x6A,2,1); //复位 FIFO
  640. i2cread(0x3A,&mpuIntStatus);
  641. //星期六 (2014/06/28)
  642. return 1;
  643. }
  644. /*初始化MPU6050*/
  645. void initMPU6050(void)
  646. {
  647. writeBits (0x6B,2,3,0x01); //电源管理
  648. writeBits (0x1B,4,2,0x00); //设置陀螺仪量程 250/s
  649. writeBits (0x1C,4,2,0x00); //设置加速度量程 2G
  650. writeBit (0x6B,6,1); //电源管理MUP进入睡眠模式
  651. }
  652. /*验证MPU6050连接*/
  653. unsigned char getDeviceID(void)
  654. {
  655. unsigned char b=0; //临时变量
  656. readBits(0x75,6,6,&b); //读取i2c固定地址,去掉最高位和最低位这两位数据
  657. return b == 0x34; //判断B是否等于0x34,如果等于返回1,不等于返回0(库的是0x38)

  658. }
  659. /**************************************串口**********************************/
  660. void CSH  (void) //初始化串口
  661. {

  662.     SCON  = 0x50;          // SCON: 模式 1, 8-bit UART, 使能接收  
  663.     TMOD |= 0x20;               // TMOD: timer 1, mode 2, 8-bit 重装
  664.     TH1   = 0xFD;               // TH1:  重装值 9600 波特率 晶振 11.0592MHz  
  665.     TR1   = 1;                  // TR1:  timer 1 打开                        
  666.     EA    = 1;                  //打开总中断
  667.     //ES    = 1;                  //打开串口中断
  668. }
  669. void SendByte(unsigned char dat) //发送一个字符
  670. {
  671. SBUF = dat; //SBUF 串行数据缓冲器
  672. while(!TI);  //TI发送中断标志位 (当数据发送完毕后由硬件置 1 否则等待硬件置 1)
  673.       TI = 0;
  674. }
  675. /************************************************************************************/

  676. void main(void)
  677. {
  678. unsigned char zd,i;
  679. CSH(); //初始化串口
  680. initMPU6050(); //初始化
  681. if (getDeviceID()) //验证连接是否正常(读取MPU6050的I2C地址)
  682. {
  683.   if(!(dmpInitialize())) //加载并配置运动库
  684.    while(1);

  685. }
  686. writeBit(0x6A,2,1); //复位 FIFO
  687. writeBit(0x6A,7,1); //使能DMP
  688. while(1)
  689. {
  690.   i=getFIFOCount();//读取FIFO计数
  691.   i2cread(0x3A,&zd); //读取中断状态
  692.   if((zd & 0x10)||i==1024) //判断FIFO是否溢出
  693.   {
  694.      writeBit(0x6A,2,1); //复位 FIFO
  695. }
  696. else if (zd & 0x02)
  697. {
  698.      while(i<42) i=getFIFOCount();
  699.   readdmp(dmpdatas); //读取FIFO数据(四元数+其他的数据)
  700.   SendByte(dmpdatas[0]);
  701.   SendByte(dmpdatas[1]);
  702.          SendByte(dmpdatas[4]);
  703.   SendByte(dmpdatas[5]);
  704.   SendByte(dmpdatas[8]);
  705.   SendByte(dmpdatas[9]);
  706.   SendByte(dmpdatas[12]);
  707.   SendByte(dmpdatas[13]);
  708. }

  709. }
  710. }
复制代码

回复

使用道具 举报

ID:310519 发表于 2018-9-20 11:54 | 显示全部楼层
用官方的吧,直接输出四元数。
回复

使用道具 举报

ID:574341 发表于 2019-7-9 13:16 | 显示全部楼层
#include<reg52.h> #include<math.h> #include<stdio.h> #include<intrins.h>  typedef unsigned char  uchar; typedef unsigned short ushort; typedef unsigned int   uint;  sbit SCL = P1^5; sbit SDA = P1^4; #define Kp 100.0f #define Ki 0.002f #define halfT 0.001f  uint q0 = 1, q1 = 0, q2 = 0, q3 = 0; uint exInt = 0, eyInt = 0, ezInt = 0; uint Yaw;   #define SMPRT_DIV 0x19 #define CONFIG 0x1A #define GYRO_CONFIG 0x1B #define ACCEL_CONFIG 0x1C #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 #define WHO_AM_I 0x75 #define SlaveAddress 0xD0  uchar dis[6]; int dis_data;  void delay(uint k) {         uint i,j;         for(i=0;i<k;i++)         {                 for(j=0;j<121;j++);         } }  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_(); }  void I2C_Start()  {         SCL = 1;         SDA = 1;         Delay5us();         SDA = 0;         Delay5us();         SCL = 0; }  void I2C_Stop() {         SDA = 0;         SCL = 1;         Delay5us();         SDA = 1;         Delay5us();         SDA = 0; }  void I2C_SendACK(bit ack)//发送应答信号 {         SDA = ack;         SCL = 1;         Delay5us();         SCL = 0;         Delay5us(); }  bit I2C_RecvACk() {         SCL = 1;         Delay5us();         CY = SDA;         SCL = 0;         Delay5us();         return CY; }  void I2C_SendByte(uchar dat) {         uchar i;         for(i=0;i<8;i++)         {                 dat <<= 1;                 SDA = CY;                 SCL = 1;                 Delay5us();                 SCL = 0;                 Delay5us();         }         I2C_RecvACk(); }  bit I2C_RecvByte() {         uchar i;         uchar dat = 0;         SDA = 1;         for(i=0;i<8;i++)         {                 dat <<=1;                 SCL = 1;                 Delay5us();                 dat |= SDA;                 SCL = 0;                 Delay5us();         }         return dat; }  void Single_WriteI2C(uchar REG_address,uchar REG_data) {         I2C_Start();         I2C_SendByte(SlaveAddress);         I2C_SendByte(REG_address);         I2C_SendByte(REG_data);         I2C_Stop(); }  uchar Single_ReadI2C(uchar REG_Address) {         uchar REG_data;         I2C_Start();         I2C_SendByte(SlaveAddress);         I2C_SendByte(REG_Address);         I2C_Start();         I2C_SendByte(SlaveAddress+1);         REG_data = I2C_RecvByte();         I2C_SendACK(1);         I2C_Stop();         return REG_data; }  void init_uart() {         TMOD = 0x21;         TH1 = 0xfd;      //f3         TL1 = 0xfd;         SCON = 0x50;         PS = 1;         TR0 = 1;         TR1 = 1;         ET0 = 1;         ES = 1;         EA = 1; }  void InitMPU6050() {         Single_WriteI2C(PWR_MGMT_1, 0x00);         Single_WriteI2C(SMPRT_DIV, 0x07);         Single_WriteI2C(CONFIG, 0x06);         Single_WriteI2C(GYRO_CONFIG,0x18);         Single_WriteI2C(ACCEL_CONFIG, 0x01); }  void SeriPushSend(uchar send_data) {         SBUF = send_data;         while(!TI);TI = 0; }   int GetData(uchar REG_Address) {         uchar H,L;         H  = Single_ReadI2C(REG_Address);         L  = Single_ReadI2C(REG_Address+1);         return ((H<<8)+L); }  void lcd_printf(uchar *s, int temp_data) {         if(temp_data<0)         {                 temp_data = -temp_data;                 *s = '-';         }         else *s = ' ';                  *++s = temp_data/1000+0x30;         temp_data = temp_data%10000;          *++s = temp_data/1000+0x30;         temp_data = temp_data%10000;                  *++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 Display10BitData(int value) {         uchar i;         lcd_printf(dis,value);         for(i=0;i<6;i++)         {                 SeriPushSend(dis[i]);         } } //*********************   void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az) {         float norm;         float vx, vy, vz;         float ex, ey, ez;                  norm = sqrt(ax*ax + ay*ay + az*az);         ax = ax / norm;         ay = ay / norm;         az = az / norm;                  vx = 2*(q1*q3 - q0*q2);         vy = 2*(q0*q1 - q2*q3);         vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;                  ex = (ay*vz - az*vy);         ey = (az*vx - ax*vz);         ez = (ax*vy - ay*vx);          exInt = exInt + ex*Ki;         eyInt = eyInt + ey*Ki;         ezInt = ezInt + ez*Ki;                   gx = gx + Kp*ex + exInt;         gy = gy + Kp*ey + eyInt;         gz = gz + Kp*ez + ezInt;                   q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;         q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;         q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;         q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;                     norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);         q0 = q0 / norm;         q1 = q1 / norm;         q2 = q2 / norm;         q3 = q3 / norm;          Yaw = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3)* 57.3; } //**************************** void main() {          delay(500);                         init_uart();         InitMPU6050();                 delay(150);         while(1)         {                 SeriPushSend('A');                   SeriPushSend(0x20);SeriPushSend('X'); SeriPushSend(':');                  Display10BitData(GetData(ACCEL_XOUT_H));        //??X????                 SeriPushSend(0x20);SeriPushSend('Y'); SeriPushSend(':');                 Display10BitData(GetData(ACCEL_YOUT_H));        //??Y????                 SeriPushSend(0x20);SeriPushSend('Z'); SeriPushSend(':');                 Display10BitData(GetData(ACCEL_ZOUT_H));        //??Z????                 SeriPushSend(0x20);      SeriPushSend('G');                   SeriPushSend(0x20);SeriPushSend('X'); SeriPushSend(':');                 Display10BitData(GetData(GYRO_XOUT_H));                //??X????                 SeriPushSend(0x20);SeriPushSend('Y'); SeriPushSend(':');                 Display10BitData(GetData(GYRO_YOUT_H));                //??Y????                 SeriPushSend(0x20);SeriPushSend('Z'); SeriPushSend(':');                 Display10BitData(GetData(GYRO_ZOUT_H));                //??Z????                              SeriPushSend(0x0d);                 IMUupdate(GetData(GYRO_XOUT_H), GetData(GYRO_YOUT_H), GetData(GYRO_ZOUT_H), GetData(ACCEL_XOUT_H), GetData(ACCEL_YOUT_H), GetData(ACCEL_ZOUT_H));                 SeriPushSend(0x20);SeriPushSend(Yaw);     SeriPushSend(0x0a);//??,??                 delay(2000);         } }
回复

使用道具 举报

ID:574341 发表于 2019-7-9 13:17 | 显示全部楼层
这个是我的代码,可以实现。
#include<reg52.h>
#include<math.h>
#include<stdio.h>
#include<intrins.h>

typedef unsigned char  uchar;
typedef unsigned short ushort;
typedef unsigned int   uint;

sbit SCL = P1^5;
sbit SDA = P1^4;
#define Kp 100.0f
#define Ki 0.002f
#define halfT 0.001f

uint q0 = 1, q1 = 0, q2 = 0, q3 = 0;
uint exInt = 0, eyInt = 0, ezInt = 0;
uint Yaw;


#define SMPRT_DIV 0x19
#define CONFIG 0x1A
#define GYRO_CONFIG 0x1B
#define ACCEL_CONFIG 0x1C
#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
#define WHO_AM_I 0x75
#define SlaveAddress 0xD0

uchar dis[6];
int dis_data;

void delay(uint k)
{
        uint i,j;
        for(i=0;i<k;i++)
        {
                for(j=0;j<121;j++);
        }
}

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_();
}

void I2C_Start()
{
        SCL = 1;
        SDA = 1;
        Delay5us();
        SDA = 0;
        Delay5us();
        SCL = 0;
}

void I2C_Stop()
{
        SDA = 0;
        SCL = 1;
        Delay5us();
        SDA = 1;
        Delay5us();
        SDA = 0;
}

void I2C_SendACK(bit ack)//发送应答信号
{
        SDA = ack;
        SCL = 1;
        Delay5us();
        SCL = 0;
        Delay5us();
}

bit I2C_RecvACk()
{
        SCL = 1;
        Delay5us();
        CY = SDA;
        SCL = 0;
        Delay5us();
        return CY;
}

void I2C_SendByte(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)
        {
                dat <<= 1;
                SDA = CY;
                SCL = 1;
                Delay5us();
                SCL = 0;
                Delay5us();
        }
        I2C_RecvACk();
}

bit I2C_RecvByte()
{
        uchar i;
        uchar dat = 0;
        SDA = 1;
        for(i=0;i<8;i++)
        {
                dat <<=1;
                SCL = 1;
                Delay5us();
                dat |= SDA;
                SCL = 0;
                Delay5us();
        }
        return dat;
}

void Single_WriteI2C(uchar REG_address,uchar REG_data)
{
        I2C_Start();
        I2C_SendByte(SlaveAddress);
        I2C_SendByte(REG_address);
        I2C_SendByte(REG_data);
        I2C_Stop();
}

uchar Single_ReadI2C(uchar REG_Address)
{
        uchar REG_data;
        I2C_Start();
        I2C_SendByte(SlaveAddress);
        I2C_SendByte(REG_Address);
        I2C_Start();
        I2C_SendByte(SlaveAddress+1);
        REG_data = I2C_RecvByte();
        I2C_SendACK(1);
        I2C_Stop();
        return REG_data;
}

void init_uart()
{
        TMOD = 0x21;
        TH1 = 0xfd;      //f3
        TL1 = 0xfd;
        SCON = 0x50;
        PS = 1;
        TR0 = 1;
        TR1 = 1;
        ET0 = 1;
        ES = 1;
        EA = 1;
}

void InitMPU6050()
{
        Single_WriteI2C(PWR_MGMT_1, 0x00);
        Single_WriteI2C(SMPRT_DIV, 0x07);
        Single_WriteI2C(CONFIG, 0x06);
        Single_WriteI2C(GYRO_CONFIG,0x18);
        Single_WriteI2C(ACCEL_CONFIG, 0x01);
}

void SeriPushSend(uchar send_data)
{
        SBUF = send_data;
        while(!TI);TI = 0;
}


int GetData(uchar REG_Address)
{
        uchar H,L;
        H  = Single_ReadI2C(REG_Address);
        L  = Single_ReadI2C(REG_Address+1);
        return ((H<<8)+L);
}

void lcd_printf(uchar *s, int temp_data)
{
        if(temp_data<0)
        {
                temp_data = -temp_data;
                *s = '-';
        }
        else *s = ' ';
       
        *++s = temp_data/1000+0x30;
        temp_data = temp_data%10000;

        *++s = temp_data/1000+0x30;
        temp_data = temp_data%10000;
       
        *++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 Display10BitData(int value)
{
        uchar i;
        lcd_printf(dis,value);
        for(i=0;i<6;i++)
        {
                SeriPushSend(dis[i]);
        }
}
//*********************


void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az)
{
        float norm;
        float vx, vy, vz;
        float ex, ey, ez;
       
        norm = sqrt(ax*ax + ay*ay + az*az);
        ax = ax / norm;
        ay = ay / norm;
        az = az / norm;
       
        vx = 2*(q1*q3 - q0*q2);
        vy = 2*(q0*q1 - q2*q3);
        vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;
       
        ex = (ay*vz - az*vy);
        ey = (az*vx - ax*vz);
        ez = (ax*vy - ay*vx);

        exInt = exInt + ex*Ki;
        eyInt = eyInt + ey*Ki;
        ezInt = ezInt + ez*Ki;

       
        gx = gx + Kp*ex + exInt;
        gy = gy + Kp*ey + eyInt;
        gz = gz + Kp*ez + ezInt;

       
        q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;
        q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;
        q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;
        q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;  

       
        norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
        q0 = q0 / norm;
        q1 = q1 / norm;
        q2 = q2 / norm;
        q3 = q3 / norm;

        Yaw = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3)* 57.3;
}
//****************************
void main()
{
        delay(500);               
        init_uart();
        InitMPU6050();       
        delay(150);
        while(1)
        {
                SeriPushSend('A');  
                SeriPushSend(0x20);SeriPushSend('X'); SeriPushSend(':');
                Display10BitData(GetData(ACCEL_XOUT_H));        //??X????
                SeriPushSend(0x20);SeriPushSend('Y'); SeriPushSend(':');
                Display10BitData(GetData(ACCEL_YOUT_H));        //??Y????
                SeriPushSend(0x20);SeriPushSend('Z'); SeriPushSend(':');
                Display10BitData(GetData(ACCEL_ZOUT_H));        //??Z????
                SeriPushSend(0x20);
    SeriPushSend('G');  
                SeriPushSend(0x20);SeriPushSend('X'); SeriPushSend(':');
                Display10BitData(GetData(GYRO_XOUT_H));                //??X????
                SeriPushSend(0x20);SeriPushSend('Y'); SeriPushSend(':');
                Display10BitData(GetData(GYRO_YOUT_H));                //??Y????
                SeriPushSend(0x20);SeriPushSend('Z'); SeriPushSend(':');
                Display10BitData(GetData(GYRO_ZOUT_H));                //??Z????             
                SeriPushSend(0x0d);
                IMUupdate(GetData(GYRO_XOUT_H), GetData(GYRO_YOUT_H), GetData(GYRO_ZOUT_H), GetData(ACCEL_XOUT_H), GetData(ACCEL_YOUT_H), GetData(ACCEL_ZOUT_H));
                SeriPushSend(0x20);SeriPushSend(Yaw);
    SeriPushSend(0x0a);//??,??
                delay(2000);
        }
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表