|
最近在用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
#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 //错了,应该是UCA0CTL1 &= ~UCSWRST;
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); // 读取 X加速度数据
delay(20);
temp6 = readiic(OUT_Z_MSB); // 读取 X加速度数据
delay(20);
}
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USC(void)
{
while (UCA0STAT & UCBUSY)
;
UCA0TXBUF = UCA0RXBUF;
}
诚挚的感谢;
|
|