3轴加速度传感器QMA6100P 的初始化程序

QMA6100P 姿态传感器的初始化程序


前言

国产3轴加速度传感器QMA6100P 的初始化程序,HK32的MCU,整个工程,可以顺利读取3个轴的数据。

一、简述

使用HK32F030MF4U6作为测试单片机
使用模拟IIC通讯
QMA6100P 的ID地址是0x12或者0x13(取决AD0脚是否接地)
寄存器地址0x00是存储ID的地址,读取到的数据是0x90

二、使用步骤

1.IIC基本配置(iic.c文件)

代码如下():


#define IIC_SCL_Pin 	GPIO_Pin_6
#define IIC_SCL_Port 	GPIOC
#define IIC_SDA_Pin 	GPIO_Pin_5
#define IIC_SDA_Port 	GPIOC	

#define SCL_H()   		GPIO_SetBits(IIC_SCL_Port, IIC_SCL_Pin)
#define SCL_L()   		GPIO_ResetBits(IIC_SCL_Port, IIC_SCL_Pin)
#define SDA_H()   		GPIO_SetBits(IIC_SDA_Port, IIC_SDA_Pin)
#define SDA_L()   		GPIO_ResetBits(IIC_SDA_Port, IIC_SDA_Pin)
#define READ_SDA 		GPIO_ReadInputDataBit(IIC_SDA_Port, IIC_SDA_Pin)
#define ACCE_READ_ID 	(0x12<<1)+1
#define ACCE_WRITE_ID 	(0x12<<1)+0



void I2cInit(void)
{
	/* sEE_I2C_SCL_GPIO_CLK and sEE_I2C_SDA_GPIO_CLK Periph clock enable */
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
	/* sEE_I2C Periph clock enable */

	GPIO_InitTypeDef  GPIO_InitStructure;

	/* GPIO configuration */  
	/* Configure sEE_I2C pins: SCL */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	/* Configure sEE_I2C pins: SDA */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
}


void SDA_IN(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	/* GPIO configuration */  
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
}


void SDA_OUT(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	/* GPIO configuration */  
	/* Configure sEE_I2C pins: SCL */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void delay_us(unsigned short us);

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();
	delay_us(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;
}

2.QMA6110P的寄存器地址(qma6100p.h文件)

代码如下(示例):


void funQMA6100PInit(void);
void funQMA6100PCheck(void);
short funAcceDrvReadX(void);
short funAcceDrvReadY(void);
short funAcceDrvReadZ(void);

#define SLAVE_ADDR  QMA6100P_ADDRESS

#define QMA6100P_ADDRESS   				0x12

#define QMA6100P_DEVICE_ID				0x90

#define QMA6100P_REG_CHIP_ID		    0x00

#define QMA6100P_REG_XOUTL				0x01
#define QMA6100P_REG_XOUTH				0x02
#define QMA6100P_REG_YOUTL				0x03
#define QMA6100P_REG_YOUTH				0x04
#define QMA6100P_REG_ZOUTL				0x05
#define QMA6100P_REG_ZOUTH				0x06

#define QMA6100P_REG_STEP_CNT_L			0x07
#define QMA6100P_REG_STEP_CNT_M			0x08
#define QMA6100P_REG_STEP_CNT_H			0x0d

#define QMA6100P_REG_INT_STATUS_0		0x09
#define QMA6100P_REG_INT_STATUS_1		0x0a
#define QMA6100P_REG_INT_STATUS_2		0x0b
#define QMA6100P_REG_INT_STATUS_3		0x0c

#define QMA6100P_REG_FIFO_STATE			0x0e

#define QMA6100P_REG_RANGE				0x0f

#define QMA6100P_REG_BW_ODR				0x10

#define QMA6100P_REG_POWER_MANAGE		0x11

#define QMA6100P_REG_STEP_SAMPLE_CNT	0x12
#define QMA6100P_REG_STEP_PRECISION		0x13
#define QMA6100P_REG_STEP_TIME_LOW		0x14
#define QMA6100P_REG_STEP_TIME_UP		0x15

#define QMA6100P_REG_INT_EN_0			0x16
#define QMA6100P_REG_INT_EN_1			0x17
#define QMA6100P_REG_INT_EN_2			0x18

#define QMA6100P_REG_INT1_MAP_0			0x19
#define QMA6100P_REG_INT1_MAP_1			0x1a
#define QMA6100P_REG_INT2_MAP_0			0x1b
#define QMA6100P_REG_INT2_MAP_1			0x1c

#define QMA6100P_REG_INTPIN_CFG			0x20

#define QMA6100P_REG_INT_CFG			0x21

#define QMA6100P_REG_OS_CUST_X		    0x27
#define QMA6100P_REG_OS_CUST_Y			0x28
#define QMA6100P_REG_OS_CUST_Z			0x29

#define QMA6100P_REG_NVM				0x33
#define QMA6100P_REG_RESET				0x36


#define QMA6100P_REG_DRDY_BIT			0x10	// enable 1

#define QMA6100P_REG_AMD_X_BIT			0x01
#define QMA6100P_REG_AMD_Y_BIT			0x02
#define QMA6100P_REG_AMD_Z_BIT			0x04

typedef enum
{
	QMA6100P_MAP_INT1,
	QMA6100P_MAP_INT2,
	QMA6100P_MAP_INT_NONE
}qma6100p_int_map;

typedef enum
{
	QMA6100P_BW_100 = 0,
	QMA6100P_BW_200 = 1,
	QMA6100P_BW_400 = 2,
	QMA6100P_BW_800 = 3,
	QMA6100P_BW_1600 = 4,
	QMA6100P_BW_50 = 5,
	QMA6100P_BW_25 = 6,
	QMA6100P_BW_12_5 = 7,
	QMA6100P_BW_OTHER = 8
}qma6100p_bw;

typedef enum
{
	QMA6100P_RANGE_2G = 0x01,
	QMA6100P_RANGE_4G = 0x02,
	QMA6100P_RANGE_8G = 0x04,
	QMA6100P_RANGE_16G = 0x08,
	QMA6100P_RANGE_32G = 0x0f
}qma6100p_range;

typedef enum
{
	QMA6100P_LPF_OFF = (0x00<<5),
	QMA6100P_LPF_1 = (0x04<<5),
	QMA6100P_LPF_2 = (0x01<<5),
	QMA6100P_LPF_4 = (0x02<<5),
	QMA6100P_LPF_8 = (0x03<<5),
	QMA6100P_LPF_RESERVED = 0xff
}qma6100p_nlpf;

typedef enum
{
	QMA6100P_HPF_DIV_OFF = (0x00<<5),
	QMA6100P_HPF_DIV_10 = (0x01<<5),
	QMA6100P_HPF_DIV_25 = (0x02<<5),
	QMA6100P_HPF_DIV_50 = (0x03<<5),
	QMA6100P_HPF_DIV_100 = (0x04<<5),
	QMA6100P_HPF_DIV_200 = (0x05<<5),
	QMA6100P_HPF_DIV_400 = (0x06<<5),
	QMA6100P_HPF_DIV_800 = (0x07<<5),
	QMA6100P_HPF_RESERVED = 0xff
}qma6100p_nhpf;

typedef enum
{
	QMA6100P_MODE_STANDBY = 0,
	QMA6100P_MODE_ACTIVE = 1,
	QMA6100P_MODE_MAX
}qma6100p_mode;

typedef enum
{
	QMA6100P_MCLK_102_4K = 0x03,
	QMA6100P_MCLK_51_2K = 0x04,
	QMA6100P_MCLK_25_6K = 0x05,
	QMA6100P_MCLK_12_8K = 0x06,
	QMA6100P_MCLK_6_4K = 0x07,
	QMA6100P_MCLK_RESERVED = 0xff
}qma6100p_mclk;

typedef enum
{
	QMA6100P_STEP_LPF_0 = (0x00<<6),
	QMA6100P_STEP_LPF_2 = (0x01<<6),
	QMA6100P_STEP_LPF_4 = (0x02<<6),
	QMA6100P_STEP_LPF_8 = (0x03<<6),
	QMA6100P_STEP_LPF_RESERVED = 0xff
}qma6100p_step_lpf;

typedef enum
{
	QMA6100P_STEP_AXIS_ALL = 0x00,
	QMA6100P_STEP_AXIS_YZ = 0x01,
	QMA6100P_STEP_AXIS_XZ = 0x02,
	QMA6100P_STEP_AXIS_XY = 0x03,
	QMA6100P_STEP_AXIS_RESERVED = 0xff
}qma6100p_step_axis;

typedef enum
{
	QMA6100P_STEP_START_0 = 0x00,
	QMA6100P_STEP_START_4 = 0x20,
	QMA6100P_STEP_START_8 = 0x40,
	QMA6100P_STEP_START_12 = 0x60,
	QMA6100P_STEP_START_16 = 0x80,
	QMA6100P_STEP_START_24 = 0xa0,
	QMA6100P_STEP_START_32 = 0xc0,
	QMA6100P_STEP_START_40 = 0xe0,
	QMA6100P_STEP_START_RESERVED = 0xff
}qma6100p_step_start_cnt;

typedef enum
{
	QMA6100P_FIFO_MODE_NONE,
	QMA6100P_FIFO_MODE_FIFO,
	QMA6100P_FIFO_MODE_STREAM,
	QMA6100P_FIFO_MODE_BYPASS,
	QMA6100P_FIFO_MODE_MAX
}qma6100p_fifo_mode;

typedef enum
{
	QMA6100P_TAP_SINGLE = 0x80,
	QMA6100P_TAP_DOUBLE = 0x20,
	QMA6100P_TAP_TRIPLE = 0x10,
	QMA6100P_TAP_QUARTER = 0x01,
	QMA6100P_TAP_MAX = 0xff
}qma6100p_tap;

typedef enum
{
	QMA6100P_SENSITITY_2G = 244,
	QMA6100P_SENSITITY_4G = 488,
	QMA6100P_SENSITITY_8G = 977,
	QMA6100P_SENSITITY_16G = 1950,
	QMA6100P_SENSITITY_32G = 3910
}qma6100p_sensitity;

typedef struct {
	int temp;
	
	int acc_x;
	int acc_y;
	int acc_z;
}QMA6100PRawData_t;



QMA6100P ID和数据的读取函数(qma6100p.c文件)


uint8_t  chip_id=0;
void funQMA6100PCheck(void)
{

	chip_id=Acce_Read_Byte(QMA6100P_REG_CHIP_ID);

}
void funQMA6100PInit(void)
{
	Acce_Write_Byte(QMA6100P_REG_RESET,0xB6);
	delay_us(5);
	Acce_Write_Byte(QMA6100P_REG_RESET,0x00);
	delay_us(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);
	delay_us(2);
	Acce_Write_Byte(0x5f,0x00);
	delay_us(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);
}
short funAcceDrvReadX(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;
	return (short)u16Temp;
}

short funAcceDrvReadY(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;
	return (short)u16Temp;
}
short funAcceDrvReadZ(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;
	return (short)u16Temp;
}


主程序

配置好IIC端口初始化,然后就可以先读取传感器的ID地址0x00了,如果返回0x90说明IIC配置没有问题,然后再进行QMA6100P的参数设置,然后进行数据采集。


int main(void)
{
	SysTick_Config(SystemCoreClock/200);
	I2cInit();
	funTime1config();
	delay_us(2000);
	funQMA6100PCheck();
	funQMA6100PInit();

	while(1)
	{
		if(Flag10ms)
		{
			Flag10ms=0;
			Cnt10ms++;
			if(Cnt10ms>200)
			{
				Cnt10ms=0;						
				GPIO_Toggle(GPIOC,GPIO_Pin_4);
				QMA6110Pxyz[0] = funAcceDrvReadX();
				QMA6110Pxyz[1] = funAcceDrvReadY();
				QMA6110Pxyz[2] = funAcceDrvReadZ();
			}
		}	
	}
}

工程有整体打包上传,请自取https://download.csdn.net/download/b801007/88529553。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值