MMA8451Q的读值问题

[复制链接]
 楼主| y1204246322 发表于 2017-4-11 12:16 | 显示全部楼层 |阅读模式

最近在用MMA8451Q;发现把芯片正面朝上,水平静置时X=0,Y=0,而Z轴读出来的值为40H(正面朝下,水平静置时为C0H,十进制即为-64),按照datasheet上,满刻度2g情况下,每个数值对应为1g/4096(0.25mg) 那么计算下来(40H)64*0.25mg=16mg;        与datasheet中说的 当芯片正面水平朝上放置时,X读出的加速度值为0,Y读出的加速度值为0,Z读出的加速度值为1g(重力加速度)不是不一致吗?
我想问一下  一:从芯片中之间读出的X,Y,Z到底是什么值,又怎么处理呢?
                 二:我这样计算有问题吗,怎么就能出现datasheet上说的正面水平放置为1g呢?
   
  ps: MMA8451Q的datasheet 见附录 , 灵敏度见图片   ,程式设置的是快速读取模式,X,Y,Z轴只读1个字节


程式如下:
                  #include <msp430.h>
#include "MMA8451Q_register.h"
unsigned char reg[2];
int temp1, temp2, temp3, temp4, temp5, temp6;
void delay(int value)
{
      volatile unsigned int i;
      i = value;                  // SW Delay
      do
          i--;
      while (i != 0);
}
int readiic(unsigned char address)
{
    //   unsigned char temp;
    UCB0CTL1 |= UCTR + UCTXSTT;    // I2C TX, start condition: 启动并 写slave adress
      while (!(IFG2 & UCB0TXIFG))
          ;    //  等待写地址完毕
    //  IFG2 &= ~UCB0TXIFG;
    UCB0TXBUF = address;
    while (!(IFG2 & UCB0TXIFG))
          ;  //  等待写地址完毕
    //   IFG2 &= ~UCB0TXIFG;
    UCB0CTL1 &= ~UCTR; // 设置为读模式
    UCB0CTL1 |= UCTXSTT; // restart + r + SLAVE ADRESS
    while (!(IFG2 & UCB0RXIFG))
          ; //  等待读地址完毕      此处如果写成    while (!(IFG2 & UCB0TXIFG)),由于UCB0TXIFG已经为0,所以程式会一直过不去
    //   IFG2 &= ~UCB0RXIFG;
    /*   reg[0] = UCB0RXBUF;
     while (!(IFG2 & UCB0RXIFG))
       ; //  等待接受数据完毕
     //  IFG2 &= ~UCB0RXIFG;
     reg[1] = UCB0RXBUF;
     while (!(IFG2 & UCB0RXIFG))  */
      temp1 = UCB0RXBUF;
      while (!(IFG2 & UCB0RXIFG))
          ;
    temp2 = UCB0RXBUF;
      while (!(IFG2 & UCB0RXIFG))
          ;
    UCB0CTL1 |= UCTXSTP;  // Nack + stop 通讯
    return temp2;
}
void write(unsigned char regAddr, unsigned char value)
{
      UCB0CTL1 |= UCTR + UCTXSTT;               // I2C TX, start condition
      while (!(IFG2 & UCB0TXIFG))
          ;                               //  WAIT 发送完毕
    // IFG2 &= ~UCB0TXIFG;
    UCB0TXBUF = regAddr;           // 写寄存器地址
    while (!(IFG2 & UCB0TXIFG))
          ;                         //  WAIT 发送完毕
    IFG2 &= ~UCB0TXIFG;
    UCB0TXBUF = value;
      while (!(IFG2 & UCB0TXIFG))
          ;
      IFG2 &= ~UCB0TXIFG;
    UCB0CTL1 |= UCTXSTP;  //  Transmit STOP
    delay(100);
}
void main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
    P6DIR |= BIT4;
// 0000 0110
      P3SEL |= 0x06;                     // Assign I2C pins to USCI_B0   P3_1,P3_2
      UCB0CTL1 |= UCSWRST;                      // Enable SW reset
      UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
      UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
      UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
      UCB0BR1 = 0;
      UCB0I2CSA = 0x1C;                         // SA0=0 , Slave Address is 1CH
      UCB0CTL1 &= ~UCSWRST;                    // Clear SW reset, resume operation
    P2DIR |= BIT3;   // 设置P2_3端口为输出
    P2OUT |= BIT3;  // P2_3 ,  使能蓝牙VCC,拉高复位 pin,使其处正常状态
    P3SEL |= BIT4 + BIT5;  // 设置P3_4 ,P3_5 为特殊功能;
    DCOCTL = 0;                          // Select lowest DCOx and MODx settings
      BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
      DCOCTL = CALDCO_1MHZ;
      UCA0CTL1 |= UCSWRST;
      UCA0CTL1 |= UCSSEL_2;   // SMCLK
      UCA0BR0 = 8;    //时钟信号1MHZ情况下,波特率设置为115200  refer to datasheet
      UCA0BR1 = 0;
      UCA0MCTL |= UCBRS2 + UCBRS0;   // 5
      UCA0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation  
      IE2 |= UCA0RXIE;
      __enable_interrupt();
    while (1)
      {
          int k;
          P6OUT ^= BIT4;
          delay(20000);
          MMA8451Q_INIT();
          UCA0TXBUF = temp3;
          while (UCA0STAT & UCBUSY)
              ;
          for(k=0;k<=30;k++)
          delay(6000);
        UCA0TXBUF = temp4;
          while (UCA0STAT & UCBUSY)
              ;
          for(k=0;k<=30;k++)
          delay(6000);
          UCA0TXBUF = temp5;
          while (UCA0STAT & UCBUSY)
              ;
          for(k=0;k<=30;k++)
          delay(6000);
          UCA0TXBUF = temp6;
          while (UCA0STAT & UCBUSY)
              ;
          for(k=0;k<=30;k++)
          delay(6000);
      }
}
void MMA8451Q_INIT(void)
{
    write(CTRL_REG1, 0X03);    // 加速度传感器 激活模式 + Fast Read Mode(Single Byte Data)
      temp3 = readiic(WHO_AM_I);         // 读出数据应该是0X1A(DEVICE ID)
      delay(20);
      temp4 = readiic(OUT_X_MSB);       // 读取 X加速度数据
    delay(20);
      temp5 = readiic(OUT_Y_MSB);       // 读取 Y加速度数据
    delay(20);
      temp6 = readiic(OUT_Z_MSB);       // 读取 Z加速度数据
    delay(20);
}
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USC(void)
{
      while (UCA0STAT & UCBUSY)
          ;
      UCA0TXBUF = UCA0RXBUF;C:\Users\Administrator\Desktop
}
datasheet
                                                                                               诚挚的感谢;


 楼主| y1204246322 发表于 2017-4-11 12:22 | 显示全部楼层
datasheet  & 图片

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
火山LF 发表于 2017-4-11 17:12 | 显示全部楼层
规格书上说的是正确的,应该是你的问题,我读出来的值也是 0 0 4096 这样的值
给你个参考程序,用的是51单片机,软件I2C,利用加速度转换角度,原理什么的 要详细的可以留个邮箱,我发给你
  1. //***************************************
  2. //  MMA8452 IIC测试程序
  3. // 使用单片机STC89C51
  4. // 晶振:11.0592M
  5. // 显示:电脑串口  波特率 9600
  6. // 编译环境 Keil uVision4
  7. //****************************************
  8. #include  <REG51.H>       
  9. #include  <math.h>    //Keil library  
  10. #include  <stdio.h>   //Keil library       
  11. #include  <INTRINS.H>
  12. #define   uchar unsigned char //一个字节,8bit
  13. #define   uint unsigned int       
  14. #define PI 3.1415926f
  15. #define Scount  4096

  16. sbit          SCL=P2^1;      //IIC时钟引脚定义
  17. sbit           SDA=P2^0;      //IIC数据引脚定义

  18. #define        SlaveAddress   0x38        //定义器件在IIC总线中的从地址,根据SA0地址引脚不同修改

  19. typedef unsigned char  BYTE;
  20. typedef unsigned short WORD;

  21. BYTE BUF[8];                         //接收数据缓存区8个字节             
  22. uchar ge,shi,bai,qian,wan,swan;           //显示变量
  23. int  dis_data,calx,caly,calz;                       //变量
  24. int x,y,z;
  25. float X1,Y1,Z1,Xangle,Yangle,Zangle;

  26. void delay(unsigned int k);
  27. void Init_MMA8452(void);             //初始化MMA8452
  28. void conversion(uint temp_data);

  29. void  Single_Write_MMA8452(uchar REG_Address,uchar REG_data);   //单个写入数据
  30. uchar Single_Read_MMA8452(uchar REG_Address);                   //单个读取内部寄存器数据
  31. void  Multiple_Read_MMA8452();                                  //连续的读取内部寄存器数据
  32. //------------------------------------
  33. void Delay5us();
  34. void Delay5ms();
  35. void MMA8452_Start();
  36. void MMA8452_Stop();
  37. void MMA8452_SendACK(bit ack);
  38. bit  MMA8452_RecvACK();
  39. void MMA8452_SendByte(BYTE dat);
  40. BYTE MMA8452_RecvByte();
  41. void MMA8452_ReadPage();
  42. void MMA8452_WritePage();
  43. void calculateAngle();
  44. void display_cal();
  45. void diaplay_base();

  46. uchar  RX_DATA;
  47. //-----------------------------------

  48. void serial_serve(void) interrupt 4       
  49. {         
  50.         RI=0;
  51.         RX_DATA=SBUF;
  52. }
  53. //*********************************************
  54. //串口初始化
  55. //9600 bps [url=home.php?mod=space&uid=72445]@[/url] 11.059 MHz
  56. void init_uart()
  57. {
  58.         TMOD=0x21;                               
  59.         TH1=0xfd;                               
  60.         TL1=0xfd;                               
  61.         SCON=0x50;
  62.         PS=1;      //串口中断设为高优先级别
  63.         TR0=1;           //启动定时器                       
  64.         TR1=1;
  65.         ET0=1;     //打开定时器0中断                       
  66.         ES=1;       
  67.         EA=1;
  68. }

  69. //*********串口数据发送******************
  70. void  SeriPushSend(uchar send_data)
  71. {
  72.     SBUF=send_data;  
  73.         while(!TI);TI=0;          
  74. }
  75. //*********************************************************
  76. void conversion(uint temp_data)  
  77. {  
  78.         swan = temp_data/100000+0x30 ;
  79.         temp_data=temp_data%100000;         //取余运算
  80.     wan=temp_data/10000+0x30 ;
  81.     temp_data=temp_data%10000;   //取余运算
  82.         qian=temp_data/1000+0x30 ;
  83.     temp_data=temp_data%1000;    //取余运算
  84.     bai=temp_data/100+0x30   ;
  85.     temp_data=temp_data%100;     //取余运算
  86.     shi=temp_data/10+0x30    ;
  87.     temp_data=temp_data%10;      //取余运算
  88.     ge=temp_data+0x30;        
  89. }


  90. /*******************************/
  91. void delay(unsigned int k)       
  92. {                                               
  93. unsigned int i,j;                               
  94. for(i=0;i<k;i++)
  95. {                       
  96. for(j=0;j<121;j++)                       
  97. {;}}                                               
  98. }


  99. /**************************************
  100. 延时5微秒(STC90C52RC@12M)
  101. 不同的工作环境,需要调整此函数,注意时钟过快时需要修改
  102. 当改用1T的MCU时,请调整此延时函数
  103. **************************************/
  104. void Delay5us()
  105. {
  106.     _nop_();_nop_();_nop_();_nop_();
  107.     _nop_();_nop_();_nop_();_nop_();
  108.         _nop_();_nop_();_nop_();_nop_();
  109. }

  110. /**************************************
  111. 延时5毫秒(STC90C52RC@12M)
  112. 不同的工作环境,需要调整此函数
  113. 当改用1T的MCU时,请调整此延时函数
  114. **************************************/
  115. void Delay5ms()
  116. {
  117.     WORD n = 560;

  118.     while (n--);
  119. }

  120. /**************************************
  121. 起始信号
  122. **************************************/
  123. void MMA8452_Start()
  124. {
  125.     SDA = 1;                    //拉高数据线
  126.     SCL = 1;                    //拉高时钟线
  127.     Delay5us();                 //延时
  128.     SDA = 0;                    //产生下降沿
  129.     Delay5us();                 //延时
  130.     SCL = 0;                    //拉低时钟线
  131. }

  132. /**************************************
  133. 停止信号
  134. **************************************/
  135. void MMA8452_Stop()
  136. {
  137.     SDA = 0;                    //拉低数据线
  138.     SCL = 1;                    //拉高时钟线
  139.     Delay5us();                 //延时
  140.     SDA = 1;                    //产生上升沿
  141.     Delay5us();                 //延时
  142. }

  143. /**************************************
  144. 发送应答信号
  145. 入口参数:ack (0:ACK 1:NAK)
  146. **************************************/
  147. void MMA8452_SendACK(bit ack)
  148. {
  149.     SDA = ack;                  //写应答信号
  150.     SCL = 1;                    //拉高时钟线
  151.     Delay5us();                 //延时
  152.     SCL = 0;                    //拉低时钟线
  153.     Delay5us();                 //延时
  154. }

  155. /**************************************
  156. 接收应答信号
  157. **************************************/
  158. bit MMA8452_RecvACK()
  159. {
  160.     SCL = 1;                    //拉高时钟线
  161.     Delay5us();                 //延时
  162.     CY = SDA;                   //读应答信号
  163.     SCL = 0;                    //拉低时钟线
  164.     Delay5us();                 //延时

  165.     return CY;
  166. }

  167. /**************************************
  168. 向IIC总线发送一个字节数据
  169. **************************************/
  170. void MMA8452_SendByte(BYTE dat)
  171. {
  172.     BYTE i;

  173.     for (i=0; i<8; i++)         //8位计数器
  174.     {
  175.         dat <<= 1;              //移出数据的最高位
  176.         SDA = CY;               //送数据口
  177.         SCL = 1;                //拉高时钟线
  178.         Delay5us();             //延时
  179.         SCL = 0;                //拉低时钟线
  180.         Delay5us();             //延时
  181.     }
  182.     MMA8452_RecvACK();
  183. }

  184. /**************************************
  185. 从IIC总线接收一个字节数据
  186. **************************************/
  187. BYTE MMA8452_RecvByte()
  188. {
  189.     BYTE i;
  190.     BYTE dat = 0;

  191.     SDA = 1;                    //使能内部上拉,准备读取数据,
  192.     for (i=0; i<8; i++)         //8位计数器
  193.     {
  194.         dat <<= 1;
  195.         SCL = 1;                //拉高时钟线
  196.         Delay5us();             //延时
  197.         dat |= SDA;             //读数据               
  198.         SCL = 0;                //拉低时钟线
  199.         Delay5us();             //延时
  200.     }
  201.     return dat;
  202. }

  203. //******单字节写入*******************************************

  204. void Single_Write_MMA8452(uchar REG_Address,uchar REG_data)
  205. {
  206.     MMA8452_Start();                  //起始信号
  207.     MMA8452_SendByte(SlaveAddress);   //发送设备地址+写信号
  208.     MMA8452_SendByte(REG_Address);    //内部寄存器地址
  209.     MMA8452_SendByte(REG_data);       //内部寄存器数据
  210.     MMA8452_Stop();                   //发送停止信号
  211. }

  212. //********单字节读取*****************************************
  213. /*
  214. uchar Single_Read_MMA8452(uchar REG_Address)
  215. {  uchar REG_data;
  216.     MMA8452_Start();                          //起始信号
  217.     MMA8452_SendByte(SlaveAddress);           //发送设备地址+写信号
  218.     MMA8452_SendByte(REG_Address);                   //发送存储单元地址,从0开始       
  219.     MMA8452_Start();                          //起始信号
  220.     MMA8452_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  221.     REG_data=MMA8452_RecvByte();              //读出寄存器数据
  222.         MMA8452_SendACK(1);   
  223.         MMA8452_Stop();                           //停止信号
  224.     return REG_data;
  225. }
  226. */
  227. //*********************************************************
  228. //
  229. //连续读出MMA8452内部加速度数据,地址范围0x01~0x06
  230. //
  231. //*********************************************************
  232. void Multiple_read_MMA8452(void)
  233. {   uchar i;
  234.     MMA8452_Start();                          //起始信号
  235.     MMA8452_SendByte(SlaveAddress);           //发送设备地址+写信号
  236.     MMA8452_SendByte(0x01);                   //发送存储单元地址,从0x01开始       
  237.     MMA8452_Start();                          //起始信号
  238.     MMA8452_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  239.          for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF
  240.     {
  241.         BUF[i] = MMA8452_RecvByte();          //BUF[0]存储0x32地址中的数据
  242.         if (i == 5)
  243.         {
  244.            MMA8452_SendACK(1);                //最后一个数据需要回NOACK
  245.         }
  246.         else
  247.         {
  248.           MMA8452_SendACK(0);                //回应ACK
  249.        }
  250.    }
  251.     MMA8452_Stop();                          //停止信号
  252.     Delay5ms();
  253. }


  254. //*****************************************************************

  255. //初始化MMA8452,根据需要请参考pdf进行修改************************
  256. void Init_MMA8452()
  257. {
  258.    Single_Write_MMA8452(0x2A,0x01);   //
  259.    Single_Write_MMA8452(0x2B,0x02);   //

  260. }
  261. //***********************************************************************
  262. //显示x轴
  263. void display_x()
  264. {   float temp;
  265.     SeriPushSend('X');
  266.     dis_data=(BUF[0]<<8)|BUF[1];  //合成数据   
  267.         dis_data>>=2;

  268.         if(calx == 0)                                                                                // 偏移校准
  269.         {
  270.                 calx = dis_data*(-1);
  271.         }

  272.         x=(dis_data+calx);

  273.         if(dis_data<0){
  274.                dis_data=-dis_data;
  275.              SeriPushSend('-');
  276.         }
  277.         else SeriPushSend('+');

  278.     temp=(float)(dis_data+calx);      //计算数据和显示


  279.     conversion(temp);          //转换出显示需要的数据

  280.     SeriPushSend(':');
  281.         SeriPushSend(swan);
  282.         SeriPushSend(wan);
  283.     SeriPushSend(qian);
  284. //        SeriPushSend('.');
  285.         SeriPushSend(bai);
  286.         SeriPushSend(shi);

  287. }

  288. //***********************************************************************
  289. //显示y轴
  290. void display_y()
  291. {   float temp;
  292.     SeriPushSend('Y');

  293.     dis_data=(BUF[2]<<8)|BUF[3];  //合成数据   
  294.         dis_data>>=2;
  295.         if(caly == 0)                                                                                // 偏移校准
  296.         {
  297.                 caly = dis_data*(-1);
  298.         }

  299.         y=(dis_data+caly);

  300.         if(dis_data<0){
  301.         dis_data=-dis_data;
  302.     SeriPushSend('-');
  303.         }
  304.         else SeriPushSend('+');

  305.     temp=(float)(dis_data+caly);      //计算数据和显示

  306.     conversion(temp);          //转换出显示需要的数据

  307.         SeriPushSend(':');
  308.         SeriPushSend(swan);
  309.         SeriPushSend(wan);
  310.         SeriPushSend(qian);
  311. //        SeriPushSend('.');
  312.         SeriPushSend(bai);
  313.         SeriPushSend(shi);
  314. }

  315. //***********************************************************************
  316. //显示z轴
  317. void display_z()
  318. {   float temp;
  319.     SeriPushSend('Z');
  320.     dis_data=(BUF[4]<<8)|BUF[5];    //合成数据  
  321.     dis_data>>=2;
  322.         if(calz == 0)                                                                                  // 偏移校准
  323.         {
  324.                 calz = Scount-dis_data;
  325.         }

  326.         z=(dis_data+calz);

  327.         if(dis_data<0){
  328.         dis_data=-dis_data;
  329.     SeriPushSend('-');
  330.         }
  331.         else SeriPushSend('+');

  332.     temp=(float)(dis_data+calz);      //计算数据和显示

  333.     conversion(temp);          //转换出显示需要的数据

  334.         SeriPushSend(':');
  335.         SeriPushSend(swan);
  336.         SeriPushSend(wan);
  337.         SeriPushSend(qian);
  338. //        SeriPushSend('.');
  339.         SeriPushSend(bai);
  340.         SeriPushSend(shi);

  341. }


  342. void display_cal()
  343. {
  344.         conversion(calx);
  345.         SeriPushSend('X');
  346.         SeriPushSend(wan);
  347.         SeriPushSend(qian);
  348.         SeriPushSend(bai);
  349.         SeriPushSend(shi);

  350.         conversion(caly);
  351.         SeriPushSend('Y');
  352.         SeriPushSend(wan);
  353.         SeriPushSend(qian);
  354.         SeriPushSend(bai);
  355.         SeriPushSend(shi);

  356.         conversion(calz);
  357.         SeriPushSend('Z');
  358.         SeriPushSend(wan);
  359.         SeriPushSend(qian);
  360.         SeriPushSend(bai);
  361.         SeriPushSend(shi);

  362. }

  363. void calculateAngle()
  364. {
  365.         float temp,x2,y2,z2;

  366.         x2 = (float)x; // 强制类型转换
  367.         y2 = (float)y;
  368.         z2 = (float)z;

  369.         X1 = sqrt(y2*y2+z2*z2);
  370.         Y1 = sqrt(x2*x2+z2*z2);
  371.         Z1 = sqrt(y2*y2+x2*x2);

  372.         Xangle = (atan(x/X1)*180.0/PI);
  373.         Yangle = (atan(y/Y1)*180.0/PI);
  374.         Zangle = (atan(Z1/z)*180.0/PI);

  375.         temp = Zangle; // 获得角度
  376.         conversion(temp);

  377.         SeriPushSend('=');
  378.         if(y<0)
  379.         {
  380.                 SeriPushSend('+');
  381.         }else{
  382.                 SeriPushSend('-');
  383.         }
  384.         SeriPushSend(':');
  385.         SeriPushSend(wan);
  386.         SeriPushSend(qian);
  387.         SeriPushSend(shi);
  388.         SeriPushSend(ge);

  389. }


  390. //*********************************************************
  391. //******主程序********
  392. //*********************************************************
  393. void main()
  394. {
  395.         calx = 0;
  396.         caly = 0;
  397.         calz = 0;
  398. //  uchar devid;
  399.   delay(2);                           //上电延时               

  400.   init_uart();
  401.   Init_MMA8452();                 //初始化MMA8452

  402.   RX_DATA=0;
  403.   while(1)                         //循环
  404.   {
  405. // if( RX_DATA==0x31){
  406.     Init_MMA8452();                //初始化MMA8452

  407.     Multiple_Read_MMA8452();       //连续读出数据,存储在BUF中

  408.     SeriPushSend(0x0d);
  409.         SeriPushSend(0x0a);

  410.     display_x();                   //---------显示X轴
  411.     display_y();                   //---------显示Y轴
  412.     display_z();                   //---------显示Z轴

  413.         calculateAngle();              // 加速度转换成角度
  414.         SeriPushSend('=');

  415.         display_cal();

  416.         RX_DATA=0;
  417.     delay(50);                    //延时50ms      
  418. //   }
  419.   }
  420. }

dirtwillfly 发表于 2017-4-11 19:51 | 显示全部楼层
火山LF 发表于 2017-4-11 17:12
规格书上说的是正确的,应该是你的问题,我读出来的值也是 0 0 4096 这样的值
给你个参考程序,用的是51单 ...

你也用这个ic?这个ic有什么优势?
火山LF 发表于 2017-4-12 08:55 | 显示全部楼层
dirtwillfly 发表于 2017-4-11 19:51
你也用这个ic?这个ic有什么优势?

就是一个三轴加速度传感器,优势嘛,当时选型的时候是同事选的,我也不是很清楚,成本应该不会很高,但是因为这个芯片交期长,时间跟不上我们的项目,就这把这个芯片给换了
 楼主| y1204246322 发表于 2017-4-12 11:40 | 显示全部楼层
本帖最后由 y1204246322 于 2017-4-12 11:49 编辑
火山LF 发表于 2017-4-11 17:12
规格书上说的是正确的,应该是你的问题,我读出来的值也是 0 0 4096 这样的值
给你个参考程序,用的是51单 ...

我详细看了下datasheet,发现我设置的是8-bit data输出数据,这样的话对应分辨率是0.0156mg (不是0.25mg,所以之前以为读出值错了); 则64*0.0156=0.9984g; 从这样的结果来看(水平静置朝上放置)Z轴是约等于1g的,说明结果正确的
但是我倾斜芯片后,利用读出值计算加速度传感器值与角速度值(弧度)时发现算出的角度值又不对劲;
你的void calculateAngle()中算法和我一样,算法参考见下个评论
可是按照这个算出的X轴的角度值怎么近2000度(当读出值X=27H (十进制为39,加速度为39*0.0156=0.6084g),  Y=00H , Z=31H(十进制为49,加速度为49*0.0156=0.7644g)时 ,Xangle按照这个带进去算出来的值是2000多;  Xangle = (artan(0.6084/0.7644)*180.0/3.14)=38*180/3.14=2178;  靠X轴的角度值2000多。。。哥们,请问下你有没有带过读出的数据进去算算,我这样算的话出了什么问题呢? 十分感谢
我这个程式只是简单读取三轴传感器加速度值然后通过蓝牙发送到软件上观察数据的,其它数据处理就是手算的
我的邮箱1226398898@qq.com
 楼主| y1204246322 发表于 2017-4-12 11:46 | 显示全部楼层
不给我发网址衔接,我截个图吧,算的是一样的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| y1204246322 发表于 2017-4-12 11:50 | 显示全部楼层
火山LF 发表于 2017-4-12 08:55
就是一个三轴加速度传感器,优势嘛,当时选型的时候是同事选的,我也不是很清楚,成本应该不会很高,但是 ...

5块钱一个这样
火山LF 发表于 2017-4-12 14:37 | 显示全部楼层
y1204246322 发表于 2017-4-12 11:40
我详细看了下datasheet,发现我设置的是8-bit data输出数据,这样的话对应分辨率是0.0156mg (不是0.25mg ...

必须有直接读出三轴的数据,然后带进公式去算,得出最后的角度。读出数据和计算都分别在51单片机和430的板子上实现了,是正确的。我们要的数据也是角度。
如果公式对的话,那就是你数据类型没有处理好,看看你计算时的数据类型,强转的有没有问题,不同编译器之间也会有区别的
 楼主| y1204246322 发表于 2017-4-12 15:18 | 显示全部楼层
火山LF 发表于 2017-4-12 14:37
必须有直接读出三轴的数据,然后带进公式去算,得出最后的角度。读出数据和计算都分别在51单片机和430的 ...

我程序中没有处理数据,只是读出来自己手算的,读出来值按道理对的(测试水平静置朝上放置Z轴是约等于1g的),带进去手动算值就不对劲
 楼主| y1204246322 发表于 2017-4-12 16:16 | 显示全部楼层
本帖最后由 y1204246322 于 2017-4-12 16:42 编辑
火山LF 发表于 2017-4-12 14:37
必须有直接读出三轴的数据,然后带进公式去算,得出最后的角度。读出数据和计算都分别在51单片机和430的 ...

火山,我发现问题出现在哪了,数据对的,你验证的读出的也是对的,
问题是出现在电脑上计算反函数坑死我了
实际应该0.7这样; 它帮我算成38 (我点了的度数,所以是最终转换值,如果你点弧度的话结果也是0.67是对的)    唉, 还是怪自己

38*180/3.14=2178度(爆炸),  我又简单调用了下数学函数测出正确值 arctan(0.6084/0.7644)*180/3.14=0.67*180/3.14=38.51度(和实际差不多);  见附件的图片

最后谢谢你,火山
诚挚的感谢



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评分

参与人数 1威望 +6 收起 理由
dirtwillfly + 6 很给力!

查看全部评分

火山LF 发表于 2017-4-12 18:40 | 显示全部楼层
y1204246322 发表于 2017-4-12 16:16
火山,我发现问题出现在哪了,数据对的,你验证的读出的也是对的,
问题是出现在电脑上计算反函数坑死我了 ...

 楼主| y1204246322 发表于 2017-4-13 18:05 | 显示全部楼层

慢慢来吧,这个解决了,中断那块又有问题。。。
myiclife 发表于 2017-4-15 22:14 | 显示全部楼层
这个有什么问题?转换有问题吗
iyoum 发表于 2017-4-15 22:15 | 显示全部楼层
读取的数据有问题?
wwppd 发表于 2017-4-15 22:15 | 显示全部楼层
推荐mpu6050芯片
myiclife 发表于 2017-4-15 22:16 | 显示全部楼层
怎么不使用alx345
iyoum 发表于 2017-4-15 22:16 | 显示全部楼层
这个加速度计没有怎么用过,不知道怎么样
wwppd 发表于 2017-4-15 22:16 | 显示全部楼层
mpu6050做姿态计算比较好。
 楼主| y1204246322 发表于 2017-4-18 09:42 | 显示全部楼层
myiclife 发表于 2017-4-15 22:14
这个有什么问题?转换有问题吗

不是,搞定了,自己计算失误
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

20

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部