QMA6100P 姿态传感器使用
项目用途:分析和记录设备位置信息变化(设备安装在车辆内部)
通讯接口:I2C,地址0x13,标准I2C通讯采用IO模拟
功能需求:读取三轴加速度
芯片初始化设置
参考手册说明和参考代码做如下初始化:
Acce_Write_Byte(QMA6100P_REG_RESET,0xB6);
DDL_DelayMS(5);
Acce_Write_Byte(QMA6100P_REG_RESET,0x00);
DDL_DelayMS(10);
Acce_Write_Byte(0x11,0x80);
Acce_Write_Byte(0x11,0x84);
Acce_Write_Byte(0x4a,0x20);
Acce_Write_Byte(0x56,0x01);
Acce_Write_Byte(0x5f,0x80);
DDL_DelayMS(2);
Acce_Write_Byte(0x5f,0x00);
DDL_DelayMS(10);
//设置满量程刻度
Acce_Write_Byte(QMA6100P_REG_RANGE, QMA6100P_RANGE_8G);
//带宽设置
Acce_Write_Byte(QMA6100P_REG_BW_ODR, QMA6100P_BW_100);
//设置时钟和模式
Acce_Write_Byte(QMA6100P_REG_POWER_MANAGE, QMA6100P_MCLK_6_4K|0x80);
//中断配置
Acce_Write_Byte(0x21,0x03);
获取设备ID
用于验证通讯是否正常
uint8_t AcceDrvReadID(void)
{
return Acce_Read_Byte(0x00);
}
读取加速度
short AcceDrvReadX(void)
{
short u16Temp;
float X;
u16Temp = Acce_Read_Byte(QMA6100P_REG_XOUTL) + \
(Acce_Read_Byte(QMA6100P_REG_XOUTH)<<8);
X = (u16Temp>>2)*QMA6100P_SENSITITY_8G/1000.0;
return (short)X;
}
short AcceDrvReadY(void)
{
short u16Temp;
float X;
u16Temp = Acce_Read_Byte(QMA6100P_REG_YOUTL) + \
(Acce_Read_Byte(QMA6100P_REG_YOUTH)<<8);
X = (u16Temp>>2)*QMA6100P_SENSITITY_8G/1000.0;
return X;
}
short AcceDrvReadZ(void)
{
short u16Temp;
float X;
u16Temp = Acce_Read_Byte(QMA6100P_REG_ZOUTL) + \
(Acce_Read_Byte(QMA6100P_REG_ZOUTH)<<8);
X = (u16Temp>>2)*QMA6100P_SENSITITY_8G/1000.0;
return X;
}
I2C通讯接口
#define IIC_SCL_Pin GPIO_PIN_05
#define IIC_SCL_Port GPIO_PORT_C
#define IIC_SDA_Pin GPIO_PIN_04
#define IIC_SDA_Port GPIO_PORT_C
#define SCL_H() GPIO_SetPins(IIC_SCL_Port, IIC_SCL_Pin)
#define SCL_L() GPIO_ResetPins(IIC_SCL_Port, IIC_SCL_Pin)
#define SDA_H() GPIO_SetPins(IIC_SDA_Port, IIC_SDA_Pin)
#define SDA_L() GPIO_ResetPins(IIC_SDA_Port, IIC_SDA_Pin)
#define READ_SDA GPIO_ReadInputPins(IIC_SDA_Port, IIC_SDA_Pin)
static void SDA_IN(void){}
static void SDA_OUT(void){}
static void delay_us(int X)
{
DDL_DelayUS(X);
}
static void IIC_Start(void)
{
SDA_OUT();
SDA_H();
SCL_H();
delay_us(4);
SDA_L();
delay_us(4);
SCL_L();
}
static void IIC_Stop(void)
{
SDA_OUT();
SCL_L();
SDA_L();
delay_us(4);
SCL_H();
SDA_H();
delay_us(4);
}
static uint8_t IIC_Wait_Ack(void)
{
uint8_t ucErrTime=0;
SDA_OUT();
SDA_H();delay_us(1);
SCL_H();delay_us(1);
SDA_IN();
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
SCL_L();
return 0;
}
static void IIC_Ack(void)
{
SCL_L();
SDA_OUT();
SDA_L();
delay_us(2);
SCL_H();
delay_us(2);
SCL_L();
}
static void IIC_NAck(void)
{
SCL_L();
SDA_OUT();
SDA_H();
delay_us(2);
SCL_H();
delay_us(2);
SCL_L();
}
static void IIC_Send_Byte(uint8_t Data)
{
uint8_t t;
SDA_OUT();
SCL_L();
for(t=0;t<8;t++)
{
if((Data&0x80)>>7)
SDA_H();
else
SDA_L();
Data<<=1;
delay_us(2);
SCL_H();
delay_us(2);
SCL_L();
delay_us(2);
}
}
static uint8_t IIC_Read_Byte(uint8_t ack)
{
uint8_t i,receive=0;
SDA_IN();
for(i=0;i<8;i++ )
{
SCL_L();
delay_us(2);
SCL_H();
receive<<=1;
if(READ_SDA)
receive++;
delay_us(1);
}
if (!ack)
IIC_NAck();
else
IIC_Ack();
return receive;
}
void Acce_Write_Byte(uint8_t addr, uint8_t data)
{
IIC_Start();
IIC_Send_Byte(ACCE_WRITE_ID);
IIC_Wait_Ack();
IIC_Send_Byte(addr);
IIC_Wait_Ack();
IIC_Send_Byte(data);
IIC_Wait_Ack();
IIC_Stop();
DDL_DelayMS(2);
}
uint8_t Acce_Read_Byte(uint8_t addr)
{
uint8_t Read_Data;
IIC_Start();
IIC_Send_Byte(ACCE_WRITE_ID);
IIC_Wait_Ack();
IIC_Send_Byte(addr);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(ACCE_READ_ID);
IIC_Wait_Ack();
Read_Data = IIC_Read_Byte(0);
IIC_Stop();
return Read_Data;
}