打印

基于STM8读取MPU6050的dwp中的数据问题

[复制链接]
5970|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
激情的拼了|  楼主 | 2014-3-5 13:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
想要获得MPU6050的姿态角数据,从mpu的数据手册上看到有dwp功能可以快速获得四元数及欧拉角。
但是从mpu6050的fifo中读出的数据不对。
我是参考

void i2cinit(void)  

{

  // 16 M晶振,400K TWI 速率

  TWBR=0x0a;

  TWAR=0x00;

  TWCR=0x94;

  TWSR=0x00;

}

void showfloat(unsigned char x,unsigned char y,float f_2show)

{

  unsigned char str2show[10];

  lcd_gotoxy(x,y);

  ftoa( f_2show,10,str2show);

  lcd_puts(str2show);

}

void showlong(unsigned char x,unsigned char y,long l_2show)

{

  unsigned char str2show[15];

  lcd_gotoxy(x,y);

  ltoa( l_2show,str2show);

  lcd_puts(str2show);

}

//以下TWI的基本操作函数是从马潮老师的书中复制而来,在此表示谢意

unsigned char i2cstart(void)

{

  TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

  while(!(TWCR&(1<<TWINT))){};

  return 1;

}

void i2cstop(void)

{

  TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);

}

unsigned char i2cwbyte(unsigned char c)

{

  unsigned char ack=1;

  TWDR=c;

  TWCR=(1<<TWINT)|(1<<TWEN);

  while(!(TWCR&(1<<TWINT))){};

  if((TWSR&0xF8)!=TW_MT_SLA_ACK)

    ack=0;

  return ack;

}

unsigned char i2crbyte(unsigned char ack)

{

  if(ack)

    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);

  else

    TWCR=(1<<TWINT)|(1<<TWEN);

  while(!(TWCR&(1<<TWINT))){};

  return(TWDR);

}

unsigned char i2cread(unsigned char address)

{

  unsigned char data;

  i2cstart();

  i2cwbyte(i2cw);

  i2cwbyte(address);

  i2cstart();

  i2cwbyte(i2cr);

  data=i2crbyte(0);

  i2cstop();

  return data;

}

void i2cwrite(unsigned char address,unsigned char data)

{

  i2cstart();

  i2cwbyte(i2cw);

  i2cwbyte(address);

  i2cwbyte(data);

  i2cstop();

}

void readdmp(void)

{

  unsigned char dmpnum;

  i2cstart();

  i2cwbyte(i2cw);

  i2cwbyte(0x74);

  i2cstart();

  i2cwbyte(i2cr);     

  for (dmpnum=0;dmpnum<41;dmpnum++)

   {

    dmpdatas[dmpnum]=i2crbyte(1);  

   };

  dmpdatas[41]=i2crbyte(0);

  i2cstop();

}

long getdmplong(unsigned char address)

{

  long dmptempl;

  dmptempl = dmpdatas[address];

  dmptempl <<= 8;

  dmptempl |= dmpdatas[address+1];

  dmptempl <<= 8;

  dmptempl |= dmpdatas[address+2];

  dmptempl <<= 8;

  dmptempl |= dmpdatas[address+3];

  return dmptempl;

}

void getquaternion(void)

{   

  quartf[0] = getdmplong(0)/1073741824.0;  

  quartf[1] = getdmplong(4)/1073741824.0;

  quartf[2] = getdmplong(8)/1073741824.0;

  quartf[3] = getdmplong(12)/1073741824.0;

}

void getgyro(void)

{

  gyrof[0]=getdmplong(16)/16.384;

  gyrof[1]=getdmplong(20)/16.384;

  gyrof[2]=getdmplong(24)/16.384;

}

void getaccel(void)

{

  accelf[0]=getdmplong(28)/32768.0;

  accelf[1]=getdmplong(32)/32768.0;

  accelf[2]=getdmplong(36)/32768.0;

}

void init6050(void)

{

  i2cwrite(0x6b , 0b10000000);                          

  delay_ms(200);

  i2cwrite(0x6b , 0b00000001);                          //No sleep  , 3 PLL with X axis gyroscope reference

  i2cwrite(0x23 , 0b00000000);                          //FIFO 11111000 ,temp,gx,gy,gz,accel

  i2cwrite(0x19 , 0b00000101);                          //SMPLRT_DIV,+1 ,要能被 FIFO rate 整除

  i2cwrite(0x1a , 0b00000011);                          //00 111,8k ,other  1K  DLPF

  i2cwrite(0x1b , 0b00011000);                          //00011000  GYRO-CFG +-2000d/s

  i2cwrite(0x1c , 0b00000000);                          //ACCEL  +-2g/s

}



void loadfirmware(void)

{

  unsigned int datanum=0;

  unsigned char bank;

  unsigned lastbank=1;

  for (datanum=0;datanum<1929;datanum++)

   {

     bank=datanum/256;

     if(lastbank!=bank){

       i2cwrite(0x6d,bank);

       i2cwrite(0x6e,0);

     }

     i2cwrite(0x6f,dmpmemorydata[datanum]);

     lastbank=bank;

    };

}

void loadcfgupd(void)

{

  unsigned char line;

  unsigned char bank;

  unsigned char datacounts=0;

  unsigned char bytes2write;

  unsigned char offset;

  unsigned char writingcounts;

     

  for (line=0;line<37;line++)

  {

    bank=dmpcfgupddata[datacounts];

    datacounts++;

    offset=dmpcfgupddata[datacounts];

    datacounts++;

    bytes2write=dmpcfgupddata[datacounts];

    i2cwrite(0x6d,bank);  

    i2cwrite(0x6e,offset);

   

    for (writingcounts=0;writingcounts<bytes2write;writingcounts++)

{

     datacounts++;

        i2cwrite(0x6f,dmpcfgupddata[datacounts]);  

    };

    datacounts++;

  };

}

void getyawpitchroll(void)

{

  // Roll = Atan2(2 *(Y * Z + W * X) , W * W -X * X -Y * Y + Z * Z)

yprf[0] = atan2(2 *(quartf[2] * quartf[3] + quartf[0] * quartf[1]) , quartf[0] * quartf[0] -quartf[1] * quartf[1] -quartf[2] * quartf[2] + quartf[3] * quartf[3])*57.3;

  // Pitch = asin(-2 * (X * Z - W * Y))  

yprf[1]=asin(-2*(quartf[1]*quartf[3]-quartf[0]*quartf[2]))*57.3;

  // Yaw   = atan2(2 * (X * Y + W * Z) ,W * W + X * X - Y * Y - Z * Z)

yprf[2]=atan2(2*(quartf[1] * quartf[2] + quartf[0] * quartf[3]) , quartf[0] * quartf[0] +quartf[1] * quartf[1] -quartf[2] * quartf[2] - quartf[3] * quartf[3])*57.3;

}



void main(void)

{

unsigned int fifocounts;

// Bit Rate: 400.000 kHz

TWBR=0x0a;

TWAR=0x00;

TWCR=0x94;

TWSR=0x00;

// Alphanumeric LCD initialization

// Connections specified in the

// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:

// RS - PORTA Bit 2

// RD - PORTA Bit 1

// EN - PORTA Bit 3

// D4 - PORTA Bit 4

// D5 - PORTA Bit 5

// D6 - PORTA Bit 6

// D7 - PORTA Bit 7

// Characters/line: 16

lcd_init(16);   

i2cinit();   

lcd_clear();

init6050();

loadfirmware();

loadcfgupd();



i2cwrite(0x70 , 0b00000011);                        

i2cwrite(0x71 , 0b00000000);                        

i2cwrite(0x6a , 0b11001100);  

while(1)

{   

   do

    {

       do {  

         fifocounts=i2cread(0x72);

         fifocounts=fifocounts<<8;

         fifocounts=fifocounts+i2cread(0x73);    //读出FIFO里有多少数据

         //showlong(12,3,fifocounts);

     }

       while (fifocounts<42);

       readdmp();  

    fifocounts=i2cread(0x72);

       fifocounts=fifocounts<<8;

       fifocounts=fifocounts+i2cread(0x73);

   }while(fifocounts>=42);

         

   getquaternion();

   //getgyro();

   //getaccel();

   getyawpitchroll();

   showlong(12,0,dmpdatas[0]);      //显示一下原始数据,看有没有规律

   showlong(12,1,dmpdatas[1]);

   showfloat(0,0,yprf[0]);   //显示 ROLL PITCH YAW 值

   showfloat(0,1,yprf[1]);

   showfloat(0,2,yprf[2]);

   delay_ms(200);      

   lcd_clear();

}

}


写的代码(不是用的库函数)。
有没有大虾能都指导一下不用dwp的库函数如何正确读出fifo中的内容。

相关帖子

沙发
激情的拼了|  楼主 | 2014-3-6 08:34 | 只看该作者
错了,是使用mpu6050的dmp不是dwp。。。

使用特权

评论回复
板凳
lijianfeng-11| | 2015-10-14 17:54 | 只看该作者
一直没有找到STM8的代码,太冷门了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

0

粉丝