Initialization program of 3-axis acceleration sensor QMA6100P

QMA6100P attitude sensor initialization program

Article directory

  • Preface
  • 1. Brief description
  • 2. Usage steps
    • 1.IIC basic configuration (iic.c file)
    • 2. Register address of QMA6110P (qma6100p.h file)
  • QMA6100P ID and data reading function (qma6100p.c file)
  • main program

Foreword

The initialization program of the domestic 3-axis acceleration sensor QMA6100P, the HK32 MCU, and the entire project can smoothly read the data of the 3 axes.

1. Brief description

Use HK32F030MF4U6 as the test microcontroller
Use analog IIC communication
The ID address of QMA6100P is 0x12 or 0x13 (depending on whether the AD0 pin is grounded)
Register address 0x00 is the address where the ID is stored, and the read data is 0x90

2. Usage steps

1.IIC basic configuration (iic.c file)

code show as below():

#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, & amp;GPIO_InitStructure);

/* Configure sEE_I2C pins: SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_Init(GPIOC, & amp;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, & amp;GPIO_InitStructure);
\t
}


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, & amp;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 & amp;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;
\t
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();
\t
return Read_Data;
}

2. Register address of QMA6110P (qma6100p.h file)

The code is as follows (example):

void funQMA6100PInit(void);
void funQMA6100PCcheck(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_sensitivity;

typedef struct {<!-- -->
int temp;
\t
int acc_x;
int acc_y;
int acc_z;
}QMA6100PRawData_t;


QMA6100P ID and data reading function (qma6100p.c file)

uint8_t chip_id=0;
void funQMA6100PCcheck(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);

//Set full scale scale
Acce_Write_Byte(QMA6100P_REG_RANGE, QMA6100P_RANGE_8G);

//Set bandwidth
Acce_Write_Byte(QMA6100P_REG_BW_ODR, QMA6100P_BW_100);

//Set clock and mode
Acce_Write_Byte(QMA6100P_REG_POWER_MANAGE, QMA6100P_MCLK_6_4K|0x80);

//Set interrupt
Acce_Write_Byte(0x21,0x03);
}
short funAcceDrvReadX(void)
{<!-- -->
short u16Temp;
float X;
\t
u16Temp = Acce_Read_Byte(QMA6100P_REG_XOUTL) + \
(Acce_Read_Byte(QMA6100P_REG_XOUTH)<<8);
\t
X = (u16Temp>>2)*QMA6100P_SENSITITY_8G/1000.0;
\t
//return (short)X;
return (short)u16Temp;
}

short funAcceDrvReadY(void)
{<!-- -->
short u16Temp;
float X;
\t
u16Temp = Acce_Read_Byte(QMA6100P_REG_YOUTL) + \
(Acce_Read_Byte(QMA6100P_REG_YOUTH)<<8);
\t
X = (u16Temp>>2)*QMA6100P_SENSITITY_8G/1000.0;
\t
//return X;
return (short)u16Temp;
}
short funAcceDrvReadZ(void)
{<!-- -->
short u16Temp;
float X;
\t
u16Temp = Acce_Read_Byte(QMA6100P_REG_ZOUTL) + \
(Acce_Read_Byte(QMA6100P_REG_ZOUTH)<<8);
\t
X = (u16Temp>>2)*QMA6100P_SENSITITY_8G/1000.0;
\t
//return X;
return (short)u16Temp;
}

Main program

After configuring the IIC port initialization, you can first read the sensor’s ID address 0x00. If 0x90 is returned, it means there is no problem with the IIC configuration, and then set the parameters of QMA6100P, and then collect data.

int main(void)
{<!-- -->
SysTick_Config(SystemCoreClock/200);
I2cInit();
funTime1config();
delay_us(2000);
funQMA6100PCcheck();
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();
}
}
}
}

The project is packaged and uploaded as a whole, please get it from https://download.csdn.net/download/b801007/88529553.