加速度传感器QMA6100P的使用

本文聊聊上海矽睿产的加速度传感器qma6100p的使用。1、特性高集成,小尺寸封装:2 x 2 x 0.95 mm lga
14位数模转化,低噪声 ·
具有标准模式和快速模式,支持i2c和spi接口
内置self-test
大范围操作电压1.7v-3.6v,与低功耗2~50μa
集成64位fifo存贮器,符合rohs标准,无卤素添加
内置运动算法 ,尤其是硬件计步算法
可在-40°c~85°c的温度中工作
2、引脚说明
可以看出提供了两个外部中断引脚,支持spi或i2c通信。
3、i2c读写地址
4、部分寄存器4.1、设备id寄存器
可以通过读这个寄存器判断设备是否存在,默认是0x90。
4.2、软复位寄存器4.3、数据寄存器通过这6个寄存器可以读出三轴数据。
4.4、量程寄存器
通过这个寄存器设置测量范围。
4.5、带宽寄存器
4.6、电源管理寄存器
5、原理图设计
6、代码本文使用软硬件i2c与qma6100p通讯,通过宏切换。
void i2cinit(void)
{
gpio_inittypedef gpio_initstructure;
i2c_inittypedef i2c_initstructure;
rcc_i2cclkconfig(rcc_i2c1clk_sysclk);
rcc_apb1periphclockcmd(rcc_apb1periph_i2c2, enable);
rcc_ahbperiphclockcmd(rcc_ahbperiph_gpiof , enable);
/* connect pxx to i2c_scl*/
gpio_pinafconfig(gpiof, gpio_pinsource6, gpio_af_1);
/* connect pxx to i2c_sda*/
gpio_pinafconfig(gpiof, gpio_pinsource7, gpio_af_1);
/* gpio configuration */ 
/* configure see_i2c pins: scl */
gpio_initstructure.gpio_pin = gpio_pin_6;
gpio_initstructure.gpio_mode = gpio_mode_af;
gpio_initstructure.gpio_speed = gpio_speed_2mhz;
gpio_initstructure.gpio_otype = gpio_otype_od;
gpio_initstructure.gpio_pupd = gpio_pupd_up;
gpio_init(gpiof, &gpio_initstructure);
/* configure see_i2c pins: sda */
gpio_initstructure.gpio_pin = gpio_pin_7;
gpio_init(gpiof, &gpio_initstructure);
i2c_initstructure.i2c_mode = i2c_mode_i2c;
i2c_initstructure.i2c_analogfilter = i2c_analogfilter_enable;
i2c_initstructure.i2c_digitalfilter = 0x00;
i2c_initstructure.i2c_ownaddress1 = 0x00;
i2c_initstructure.i2c_ack = i2c_ack_enable;
i2c_initstructure.i2c_acknowledgedaddress = i2c_acknowledgedaddress_7bit;
i2c_initstructure.i2c_timing = 0x40b22536;//0x20d22e37;// 0x02105070; //0x40b22536//100k, 0x10950c27; //400khz
i2c_init(i2c2, &i2c_initstructure);
/* apply see_i2c configuration after enabling it */
i2c_init(i2c2, &i2c_initstructure);
/* see_i2c peripheral enable */
i2c_cmd(i2c2, enable);
}
void i2cwrite(uint8_t reg,uint8_t var)

/* while the bus is busy */
while(i2c_getflagstatus(i2c2, i2c_flag_busy) != reset){};
/* send touch address for write */
i2c_transferhandling(i2c2, (slave_addr<<1), 1, i2c_reload_mode, i2c_generate_start_write);
while(i2c_getflagstatus(i2c2, i2c_flag_txis )==reset){}; // i2c_flag_txe
i2c_senddata(i2c2, reg);
while(i2c_getflagstatus(i2c2, i2c_flag_tcr) == reset){};
i2c_transferhandling(i2c2, (slave_addr<<1), 1, i2c_autoend_mode, i2c_no_startstop);
/* test on ev8 and clear it */
while (i2c_getflagstatus(i2c2, i2c_flag_txis) == reset){}; //i2c_flag_txis
/* send the current byte */
i2c_senddata(i2c2, var);
/* send stop condition */
while(i2c_getflagstatus(i2c2, i2c_flag_stopf) == reset){};
}
uint8_t i2cread(uint8_t reg)
{
uint8_t ret=0;
/* while the bus is busy */
while(i2c_getflagstatus(i2c2, i2c_flag_busy) != reset){};
/* generate start & wait event detection */
i2c_transferhandling(i2c2, (slave_addr<<1), 1, i2c_softend_mode, i2c_generate_start_write);
while(i2c_getflagstatus(i2c2, i2c_flag_txis ) == reset){}; //i2c_flag_txis
i2c_senddata(i2c2, reg);
while (i2c_getflagstatus(i2c2, i2c_flag_tc) == reset){};
/* send strat condition a second time */ 
i2c_transferhandling(i2c2, (slave_addr<250)
{
_i2c_stop();
return 1;
}
}
gpio_resetbits(_scl_port,_scl_pin); //scl=0
delayus(5);
return 0;
}
uint8_t _i2c_read_byte(uint8_t ack)
{
uint8_t i,rxdata=0;
#if 0
_sda_in();
gpio_setbits(_sda_port,_sda_pin); //释放总线
#else
gpio_setbits(_sda_port,_sda_pin); //释放总线
_sda_in();
#endif
for(i=0;i<8;i++ )
{
gpio_resetbits(_scl_port,_scl_pin); //scl=0
delayus(5);
gpio_setbits(_scl_port,_scl_pin); //scl=1
delayus(5);
rxdata<<=1;
if(gpio_readinputdatabit(_sda_port,_sda_pin))
{
rxdata|=0x01;
}
delayus(5);
}
if (!ack)
_i2c_nack();//nack
else
_i2c_ack(); //ack
return rxdata;
}
void _i2c_send_byte(uint8_t txd)
{
uint8_t i;
_sda_out();
gpio_resetbits(_scl_port,_scl_pin); //scl=0
for(i=0;i<8;i++)
{
if((txd&0x80)==0x80)
gpio_setbits(_sda_port,_sda_pin);
else
gpio_resetbits(_sda_port,_sda_pin);
txd<<=1;
delayus(5);
gpio_setbits(_scl_port,_scl_pin); //scl=1
delayus(5);
gpio_resetbits(_scl_port,_scl_pin); //scl=0
delayus(5);
}
}
void _writebytereg(uint8_t addr,uint8_t reg,uint8_t data)
{
_i2c_start();
_i2c_send_byte(addr); //write addr
_i2c_wait_ack();
_i2c_send_byte(reg);
_i2c_wait_ack();
_i2c_send_byte(data);
_i2c_wait_ack();
_i2c_stop();
}
uint8_t _readbytereg(uint8_t addr,uint8_t reg)
{
uint8_t data;
_i2c_start();
_i2c_send_byte(addr); //write addr
_i2c_wait_ack();
_i2c_send_byte(reg);
_i2c_wait_ack();
_i2c_start();
_i2c_send_byte(addr+1); //read addr
_i2c_wait_ack();
data=_i2c_read_byte(0); //no ack
_i2c_stop();
return data;
}
void _writeregu8(uint8_t reg,uint8_t data)
{
_i2c_start();
_i2c_send_byte(slave_addr<<1|0x00); //write addr
_i2c_wait_ack();
_i2c_send_byte(reg);
_i2c_wait_ack();
_i2c_send_byte(data);
_i2c_wait_ack();
_i2c_stop();
}
uint8_t _readregu8(uint8_t reg)
{
uint8_t data;
_i2c_start();
_i2c_send_byte(slave_addr<<1|0x00); //write addr
_i2c_wait_ack();
_i2c_send_byte(reg);
_i2c_wait_ack();
_i2c_start();
_i2c_send_byte(slave_addr<<1|0x01); //read addr
_i2c_wait_ack();
data=_i2c_read_byte(0); //no ack
_i2c_stop();
return data;
}
#if 1
#define gsensorread i2cread
#define gsensorwrite i2cwrite
#define gsensorioinit i2cinit
#else
#define gsensorread _readregu8
#define gsensorwrite _writeregu8
#define gsensorioinit _i2cinit
#endif
void qma6100pcheck(void)
{
uint8_t chip_id=0;
chip_id=gsensorread(qma6100p_reg_chip_id);
log_debug (chip id=%d\r\n,chip_id);
if(chip_id==0x90)
{
log_debug(device exist\r\n);
}
else
{
log_debug(device not exist\r\n);
}
}
void qma6100pinit(void)
{
gsensorioinit();
qma6100pcheck();
gsensorwrite(qma6100p_reg_reset, 0xb6);
delayms(5);
gsensorwrite(qma6100p_reg_reset, 0x00);
delayms(10);
gsensorwrite(0x11, 0x80);
gsensorwrite(0x11, 0x84);
gsensorwrite(0x4a, 0x20);
gsensorwrite(0x56, 0x01);
gsensorwrite(0x5f, 0x80);
delayms(2);
gsensorwrite(0x5f, 0x00);
delayms(10);
gsensorwrite(qma6100p_reg_range,qma6100p_range_8g);
gsensorwrite(qma6100p_reg_bw_odr,qma6100p_bw_100);
gsensorwrite(qma6100p_reg_power_manage,qma6100p_mclk_51_2k|0x80);
qma6100p_hand_raise_down(3, qma6100p_map_int1, 1);
gsensorwrite(0x21, 0x03);// default 0x1c, step latch mode
}
void qma6100preadrawdata(qma6100prawdata_t *rawdata)
{
int16_t temp=0;
temp=gsensorread(qma6100p_reg_xoutl)+(gsensorread(qma6100p_reg_xouth)>2;
temp=gsensorread(qma6100p_reg_youtl)+(gsensorread(qma6100p_reg_youth)>2;
temp=gsensorread(qma6100p_reg_zoutl)+(gsensorread(qma6100p_reg_zouth)>2;
}
void qma6100ppolling(void)
{
static uint32_t curtick=0;
float angle_x,angle_y,angle_z;
if(systemgettick()-curtick>=200)
{
qma6100prawdata_t rawdata;
float x ,y,z,g;
qma6100preadrawdata(&rawdata);
x=rawdata.acc_x*qma6100p_sensitity_8g/1000.0;
y=rawdata.acc_y*qma6100p_sensitity_8g/1000.0;
z=rawdata.acc_z*qma6100p_sensitity_8g/1000.0;
g=sqrt(x*x+y*y+z*z);
log_debug(%f, %f, %f, %f\r\n,x,y,z,g);
curtick=systemgettick();
}
}
#define slave_addr qma6100p_address
#define qma6100p_address 0x12
#define qma6100p_device_id0x90
#define qma6100p_reg_chip_id 0x00
#define qma6100p_reg_xoutl0x01
#define qma6100p_reg_xouth0x02
#define qma6100p_reg_youtl0x03
#define qma6100p_reg_youth0x04
#define qma6100p_reg_zoutl0x05
#define qma6100p_reg_zouth0x06
#define qma6100p_reg_step_cnt_l0x07
#define qma6100p_reg_step_cnt_m0x08
#define qma6100p_reg_step_cnt_h0x0d
#define qma6100p_reg_int_status_00x09
#define qma6100p_reg_int_status_10x0a
#define qma6100p_reg_int_status_20x0b
#define qma6100p_reg_int_status_30x0c
#define qma6100p_reg_fifo_state0x0e
#define qma6100p_reg_range0x0f
#define qma6100p_reg_bw_odr0x10
#define qma6100p_reg_power_manage0x11
#define qma6100p_reg_step_sample_cnt0x12
#define qma6100p_reg_step_precision0x13
#define qma6100p_reg_step_time_low0x14
#define qma6100p_reg_step_time_up0x15
#define qma6100p_reg_int_en_00x16
#define qma6100p_reg_int_en_10x17
#define qma6100p_reg_int_en_20x18
#define qma6100p_reg_int1_map_00x19
#define qma6100p_reg_int1_map_10x1a
#define qma6100p_reg_int2_map_00x1b
#define qma6100p_reg_int2_map_10x1c
#define qma6100p_reg_intpin_cfg0x20
#define qma6100p_reg_int_cfg0x21
#define qma6100p_reg_os_cust_x 0x27
#define qma6100p_reg_os_cust_y0x28
#define qma6100p_reg_os_cust_z0x29
#define qma6100p_reg_nvm0x33
#define qma6100p_reg_reset0x36
#define qma6100p_reg_drdy_bit0x10// enable 1
#define qma6100p_reg_amd_x_bit0x01
#define qma6100p_reg_amd_y_bit0x02
#define qma6100p_reg_amd_z_bit0x04
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 {
int16_t temp;
int16_t acc_x;
int16_t acc_y;
int16_t acc_z;
}qma6100prawdata_t;
7、读取数据
本测试中读取了x,y,z三轴的值,并计算出了g的值。

华为麒麟9000s是几纳米工艺
全面大更改!华为手机将搭载高通芯片+鸿蒙系统,你期待吗?
各地关于共享汽车的政策,你知道多少?
中国电信:第一款千元级云手机“天翼1号”正式发售
Spartan EFEM系统可每小时加工450张晶圆
加速度传感器QMA6100P的使用
采用AI语音识别引擎支持各种任务的类机器人
HMD宣布5月16日诺基亚X入网工信部
英飞凌科技推出首款Qi2磁功率曲线(MPP)充电发射器解决方案
特斯拉国产Model 3续航里程不及进口版,460km降为445km
微控制器控制的电流环路AFE保护
2021年全球芯片企业汇总!
fireflyAIO-3399C主板红外遥控器简介
废旧荧光节能灯改造高亮LED灯
成都虹威MSO/DS4000数字示波器140M标配存储深度
金菱通达导热硅胶片替代富士高分子GR25A
京东X无人超市开张 线下零售步入“看脸时代”
如何调整调出输入法的顺序
卡普空EMEA高层自信表示:《生化危机7》首日能卖400万套
BOE(京东方)强势亮相ICDT 2021 新一代玻璃基Mini LED全面量产