最近接触到一款加速度传感器(MMA8451Q),自己在此之前也接触过其他的(MPU605,7455)等,其实关于其的读值问题,还是难为了我一阵子,因为上次接触到最近,间隔的时间太久了,而且这之间还有很多其他的事情,所以就在此和大家分享一下我的一下心得
首先,自己现在官网上下载一系列的资料
步骤1:编写IIC时序
步骤2:MMA8451Q初始化
步骤3:读取X,Y,Z相应的寄存器
步骤4:对读出的值进行处理
步骤5:串口打印
步骤1:编写IIC时序
IIC读写MMA8451Q设备时序图
上述要写的程序分别为:
void IIC_start(void); //开始信号
void IIC_stop(void); //停止
void IIC_Ack(void); //应答
unsigned char IIC_read_byte(void); //读一个字节
void IIC_write_byte(unsigned char date); //写一个字节
unsigned char IIC_Wait_Ack(void); //等待应答
void IIC_NAck(void); //不应答
下面的就是写传感器的读写函数:
- 1 、 读(单字节读)
//函数名: MMA8451_single_Read
//函数功能: 从传感器设备读一个字节
//参数: REG_Address -- 寄存器地址
//返回值: 读回的数据
unsigned char MMA8451_single_Read(unsigned char REG_Address)
{
unsigned char dat;
IIC_start();
IIC_write_byte(eSlaveAddress); //设备地址
IIC_Wait_Ack();
IIC_write_byte(REG_Address); //寄存器地址
IIC_Wait_Ack();
IIC_start(); //SR
IIC_write_byte(eSlaveAddress+1); //设备地址 + read 方向
IIC_Wait_Ack();
dat = IIC_read_byte();
IIC_NAck();
IIC_stop();
return dat;
}
2、 读多个字节
//函数名: MMA8451_Multiple_Read
//函数功能: 从传感器设备读多个字节
//参数: REG_Address -- 寄存器地址
// num -- 要读的字节数
// *data_buf -- 存放读回数据的缓冲区
//返回值: 无
void MMA8451_Multiple_Read(unsigned char REG_Address, unsigned char num, unsigned char *data_buf)
{
unsigned char i;
num += 1;
IIC_start();
IIC_write_byte(eSlaveAddress); //设备地址
IIC_Wait_Ack();
IIC_write_byte(REG_Address); //寄存器地址
IIC_Wait_Ack();
IIC_start(); //SR
IIC_write_byte(eSlaveAddress+1); //设备地址 + read 方向
IIC_Wait_Ack();
for(i=0;i<num-1;i++)
{
*(data_buf+i) = IIC_read_byte();
if(i == num-1)
IIC_NAck();
else
IIC_Ack();
}
IIC_stop();
}
3、 写一个字节
//函数名: MMA8451_single_Write
//函数功能: 向传感器设备写一个字节的数据
//参数: REG_Address -- 寄存器地址 REG_data -- 要写的数据
//返回值: 无
void MMA8451_single_Write(unsigned char REG_Address,unsigned char REG_data)
{
IIC_start();
IIC_write_byte(eSlaveAddress); //设备地址 + write 方向
IIC_Wait_Ack(); //等待应答
IIC_write_byte(REG_Address); //寄存器地址
IIC_Wait_Ack();
IIC_write_byte(REG_data); //数据
IIC_Wait_Ack();
IIC_stop();
}
步骤2:MMA8451Q初始化
MMA8451_single_Write(CTRL_REG1,0x01); //唤醒传感器
步骤3:读取X,Y,Z三轴的加速度值
即读下面六个寄存器的值在读之前,需要判断一下数据是否已准备好
Bit 3 = 1:XYZ新数据已准备好
Bit 3 = 0:XYZ新数据未准备好
默认为0.
MMA8451_Multiple_Read(OUT_X_MSB,6,uc_mmA8451q_buf);
步骤4:对读出的值进行处理
根据需要修改
RegisterFlag_ZYXDR = (MMA8451_single_Read(STATUS_F_STATUS) & 0x08); //查询数据是否ok
if(RegisterFlag_ZYXDR == 0x08)
{
MMA8451_Multiple_Read(OUT_X_MSB,6,uc_mmA8451q_buf);
}
X=uc_mmA8451q_buf[0];
X=(X<<8) | uc_mmA8451q_buf[1];
Y=uc_mmA8451q_buf[2];
Y=(Y<<8) | uc_mmA8451q_buf[3];
Z=uc_mmA8451q_buf[4];
Z=( Z<<8) | uc_mmA8451q_buf[5];
//*************************************************************************
//*****************************X轴
//*************************************************************************
if(uc_mmA8451q_buf[0] > 0x7f)
{
BUF[0]='-';
X= ~X + 1;
}
else
{
BUF[0]='+';
}
a=(unsigned char)((X>>2) / 1000);
r=(X>>2) % 1000;
b=(unsigned char)(r / 100);
r %= 100;
c=(unsigned char)(r / 10);
d=(unsigned char)(r % 10);
//a b c d
num=(int)((a*1000) + (b*100) + (c*10) + (d*1));
//num = num + Offset_X; //数据初始校准
if(num<0)
{
num = (-1)*num;
}
uc_read_x = num; //X轴的值
步骤5:通过串口发送 uc_read_x , uc_read_y , uc_read_z