数字加速度计 (ADXL345)- 计算xyz轴重力值
1、i2c总线读取
1、接线
上一节的软件模式i2c的方式,选择PB10(SCL) PB11(SDA)。
GD32 ADXL345
PB10 --------------- SCL
PB11 --------------- SDA
3.3 --------------- 3.3
GND --------------- GND
3.3 --------------- CS
CS接高电平时,才会使能ADXL345 的i2c总线。
2、封装对寄存器读写函数。
可根据自己的平台换i2c读写函数,或者spi读写函数。
static void adxl345_write_reg(uint8_t reg,uint8_t data)
{
#if SW_IIC == 1
swi2c_device_write_data(ADXL345_ADDR,®,1,&data,1);
#endif
}
static void adxl345_read_reg(uint8_t reg,uint8_t *data)
{
#if SW_IIC == 1
swi2c_device_read_data(ADXL345_ADDR,®,1,data,1);
#endif
}
static void adxl345_get_x_y_z_data(uint8_t reg,uint8_t *data,uint16_t len)
{
#if SW_IIC == 1
swi2c_device_read_data(ADXL345_ADDR,®,1,data,len);
#endif
}
3、ADXL345的寄存器
上图看出,xyz轴的数据存在0x32-0x37寄存器中,所以我们通过设置其他寄存器去初始化ADXL345后,从这六个寄存器读取数据就好了。
4、ADXL345的初始化代码
每个寄存器的每个功能都有初始化,对着规格书很容易就能明白。
void adxl345_xyz_read_init()
{
uint8_t id = 0;
uint8_t reg;
uint8_t watermark;
uint8_t x_offset;
uint8_t y_offset;
uint8_t z_offset;
uint8_t tap_threshold;
uint8_t tap_duration;
uint8_t tap_window;
uint8_t latent;
uint8_t action_threshold;
uint8_t inaction_threshold;
uint8_t inaction_time;
uint8_t fall_threshold;
uint8_t free_fall_time;
adxl345_interrupt_active_level_t it_level;
adxl345_bool_t auto_sleep_enable;
adxl345_bool_t sleep_enable;
adxl345_sleep_frequency_t sleep_freq;
adxl345_mode_t fifo_mode;
adxl345_interrupt_pin_t interrupt_pin;
adxl345_get_device_id(&id);
if (id == 0xe5)
{
adxl345_set_interrupt_active_level(ADXL345_INTERRUPT_ACTIVE_LEVEL_LOW); // 设置中断为低电平
adxl345_get_interrupt_active_level(&it_level);
printf("adxl345_get_interrupt_active_level == 0x%02x\r\n",it_level);
adxl345_set_auto_sleep(ADXL345_BOOL_FALSE); // 设置自动休眠为关
adxl345_get_auto_sleep(&auto_sleep_enable);
printf("adxl345_get_auto_sleep == 0x%02x\r\n",auto_sleep_enable);
adxl345_set_sleep(ADXL345_BOOL_FALSE); // 置为0,普通工作模式,置为1 ,休眠模式
adxl345_get_sleep(&sleep_enable);
printf("adxl345_get_sleep == 0x%02x\r\n",sleep_enable);
adxl345_set_sleep_frequency(ADXL345_SLEEP_FREQUENCY_1HZ);
adxl345_get_sleep_frequency(&sleep_freq);
printf("adxl345_get_sleep_frequency == 0x%02x\r\n",sleep_freq);
adxl345_set_fifo_mode(ADXL345_MODE_BYPASS);
adxl345_get_fifo_mode(&fifo_mode);
printf("adxl345_get_fifo_mode == 0x%02x\r\n",fifo_mode);
adxl345_set_trigger_pin(ADXL345_INTERRUPT_PIN1);
adxl345_get_trigger_pin(&interrupt_pin);
printf("adxl345_get_trigger_pin == 0x%02x\r\n",interrupt_pin);
adxl345_set_watermark(0x1F);
adxl345_get_watermark(&watermark);
printf("adxl345_get_watermark == 0x%02x\r\n",watermark);
//set x y z offset
adxl345_offset_convert_to_register(0.0f,®);
adxl345_set_offset(reg,reg,reg);
adxl345_get_offset((uint8_t *)&x_offset,(uint8_t *)&y_offset,(uint8_t *)&z_offset);
printf("x_offset == 0x%02x y_offset == 0x%02x z_offset= 0x%02x\r\n",x_offset,y_offset,z_offset);
/* set threshold 3g */
adxl345_tap_threshold_convert_to_register(3.0f,®);
/* set tap threshold */
adxl345_set_tap_threshold(reg);
adxl345_get_tap_threshold(&tap_threshold);
printf("adxl345_get_tap_threshold == 0x%02x\r\n",tap_threshold);
/* set 10 ms */
adxl345_duration_convert_to_register(10 * 1000, (uint8_t *)®);
/* set duration */
adxl345_set_duration(reg);
adxl345_get_duration(&tap_duration);
printf("adxl345_get_duration == 0x%02x\r\n",tap_duration);
/* set 20 ms */
adxl345_latent_convert_to_register(20.0f, (uint8_t *)®);
/* set latent */
adxl345_set_latent(reg);
adxl345_get_latent(&latent);
printf("adxl345_get_latent == 0x%02x\r\n",latent);
/* set 80 ms */
adxl345_window_convert_to_register(80.0f, (uint8_t *)®);
/* set windows time */
adxl345_set_window(reg);
adxl345_get_window(&tap_window);
printf("adxl345_get_window == 0x%02x\r\n",tap_window);
/* set x axis */
adxl345_set_tap_axis(ADXL345_TAP_AXIS_X, ADXL345_BOOL_FALSE);
adxl345_get_tap_axis(ADXL345_TAP_AXIS_X,®);
printf("adxl345_get_tap_x_axis == 0x%02x\r\n",reg);
/* set y axis */
adxl345_set_tap_axis(ADXL345_TAP_AXIS_Y, ADXL345_BOOL_FALSE);
adxl345_get_tap_axis(ADXL345_TAP_AXIS_Y,®);
printf("adxl345_get_tap_y_axis == 0x%02x\r\n",reg);
/* set z axis */
adxl345_set_tap_axis(ADXL345_TAP_AXIS_Z, ADXL345_BOOL_FALSE);
adxl345_get_tap_axis(ADXL345_TAP_AXIS_Z,®);
printf("adxl345_get_tap_z_axis == 0x%02x\r\n",reg);
/* disable suppress */
adxl345_set_tap_suppress(ADXL345_BOOL_FALSE);
adxl345_get_tap_suppress(®);
printf("adxl345_get_tap_suppress == 0x%02x\r\n",reg);
/* map int 1 */
adxl345_set_interrupt_map(ADXL345_INTERRUPT_SINGLE_TAP, ADXL345_INTERRUPT_PIN1);
adxl345_get_interrupt_map(ADXL345_INTERRUPT_SINGLE_TAP, ®);
printf("adxl345_get_interrupt_map == 0x%02x\r\n",reg);
/* set single tap */
adxl345_set_interrupt(ADXL345_INTERRUPT_SINGLE_TAP, ADXL345_BOOL_FALSE);
adxl345_get_interrupt(ADXL345_INTERRUPT_SINGLE_TAP,®);
printf("adxl345_get_interrupt == 0x%02x\r\n",reg);
/* map int 1 */
adxl345_set_interrupt_map(ADXL345_INTERRUPT_DOUBLE_TAP, ADXL345_INTERRUPT_PIN1);
adxl345_get_interrupt_map(ADXL345_INTERRUPT_DOUBLE_TAP, ®);
printf("adxl345_get_interrupt_map == 0x%02x\r\n",reg);
/* set double tap */
adxl345_set_interrupt(ADXL345_INTERRUPT_DOUBLE_TAP, ADXL345_BOOL_FALSE);
adxl345_get_interrupt(ADXL345_INTERRUPT_DOUBLE_TAP,®);
printf("adxl345_get_interrupt == 0x%02x\r\n",reg);
/* link activity and inactivity */
adxl345_set_link_activity_inactivity(ADXL345_BOOL_FALSE);
adxl345_get_link_activity_inactivity(®);
printf("adxl345_get_link_activity_inactivity == 0x%02x\r\n",reg);
adxl345_action_threshold_convert_to_register(2.0f,(uint8_t *)®);
adxl345_set_action_threshold(reg);
adxl345_get_action_threshold(&action_threshold);
printf("adxl345_get_action_threshold == 0x%02x\r\n",action_threshold);
adxl345_inaction_threshold_convert_to_register(1.0f, (uint8_t *)®);
/* set inaction threshold */
adxl345_set_inaction_threshold( reg);
adxl345_get_inaction_threshold(&inaction_threshold);
printf("adxl345_get_inaction_threshold == 0x%02x\r\n",inaction_threshold);
/* set 3 s */
adxl345_inaction_time_convert_to_register(3, (uint8_t *)®);
/* set inaction time */
adxl345_set_inaction_time(reg);
adxl345_get_inaction_time(&inaction_time);
printf("adxl345_get_inaction_time == 0x%02x\r\n",inaction_time);
/* set action x */
adxl345_set_action_inaction(ADXL345_ACTION_X, ADXL345_BOOL_FALSE);
adxl345_get_action_inaction(ADXL345_ACTION_X,®);
printf("adxl345_get_action_inaction == 0x%02x\r\n",reg);
/* set action y */
adxl345_set_action_inaction(ADXL345_ACTION_Y, ADXL345_BOOL_FALSE);
adxl345_get_action_inaction(ADXL345_ACTION_Y,®);
printf("adxl345_get_action_inaction == 0x%02x\r\n",reg);
/* set action z */
adxl345_set_action_inaction(ADXL345_ACTION_Z, ADXL345_BOOL_FALSE);
adxl345_get_action_inaction(ADXL345_ACTION_Z,®);
printf("adxl345_get_action_inaction == 0x%02x\r\n",reg);
/* set inaction x */
adxl345_set_action_inaction(ADXL345_INACTION_X, ADXL345_BOOL_FALSE);
adxl345_get_action_inaction(ADXL345_INACTION_X,®);
printf("adxl345_get_action_inaction == 0x%02x\r\n",reg);
/* set inaction y */
adxl345_set_action_inaction(ADXL345_INACTION_Y, ADXL345_BOOL_FALSE);
adxl345_get_action_inaction(ADXL345_INACTION_Y,®);
printf("adxl345_get_action_inaction == 0x%02x\r\n",reg);
/* set inaction z */
adxl345_set_action_inaction(ADXL345_INACTION_Z, ADXL345_BOOL_FALSE);
adxl345_get_action_inaction(ADXL345_INACTION_Z,®);
printf("adxl345_get_action_inaction == 0x%02x\r\n",reg);
/* set action ac coupled */
adxl345_set_action_coupled(ADXL345_COUPLED_AC);
adxl345_get_action_coupled(®);
printf("adxl345_get_action_coupled == 0x%02x\r\n",reg);
/* set inaction dc coupled */
adxl345_set_inaction_coupled(ADXL345_COUPLED_DC);
adxl345_get_inaction_coupled(®);
printf("adxl345_get_inaction_coupled == 0x%02x\r\n",reg);
/* map int 1 */
adxl345_set_interrupt_map(ADXL345_INTERRUPT_ACTIVITY, ADXL345_INTERRUPT_PIN1);
/* set activity */
adxl345_set_interrupt(ADXL345_INTERRUPT_ACTIVITY, ADXL345_BOOL_FALSE);
/* map int 1 */
adxl345_set_interrupt_map(ADXL345_INTERRUPT_INACTIVITY, ADXL345_INTERRUPT_PIN1);
/* set inactivity */
adxl345_set_interrupt(ADXL345_INTERRUPT_INACTIVITY, ADXL345_BOOL_FALSE);
/* set free fall */
adxl345_free_fall_threshold_convert_to_register( 0.8f, (uint8_t *)®);
/* set free fall threshold */
adxl345_set_free_fall_threshold(reg);
adxl345_get_free_fall_threshold(&fall_threshold);
printf("adxl345_get_free_fall_threshold == 0x%02x\r\n",fall_threshold);
/* set 10 ms */
adxl345_free_fall_time_convert_to_register(10, (uint8_t *)®);
/* set free fall time */
adxl345_set_free_fall_time(reg);
adxl345_get_free_fall_time(&free_fall_time);
printf("adxl345_get_free_fall_time == 0x%02x\r\n",free_fall_time);
/* set interrupt 1 */
adxl345_set_interrupt_map(ADXL345_INTERRUPT_FREE_FALL, ADXL345_INTERRUPT_PIN1);
/* set fall */
adxl345_set_interrupt(ADXL345_INTERRUPT_FREE_FALL, ADXL345_BOOL_FALSE);
/* set interrupt 1 */
adxl345_set_interrupt_map(ADXL345_INTERRUPT_DATA_READY, ADXL345_INTERRUPT_PIN1);
/* set data ready */
adxl345_set_interrupt(ADXL345_INTERRUPT_DATA_READY, ADXL345_BOOL_FALSE);
/* set interrupt 1 */
adxl345_set_interrupt_map(ADXL345_INTERRUPT_WATERMARK, ADXL345_INTERRUPT_PIN1);
/* set water mark */
adxl345_set_interrupt(ADXL345_INTERRUPT_WATERMARK, ADXL345_BOOL_FALSE);
/* set interrupt 1 */
adxl345_set_interrupt_map(ADXL345_INTERRUPT_OVERRUN, ADXL345_INTERRUPT_PIN1);
/* set over run */
adxl345_set_interrupt(ADXL345_INTERRUPT_OVERRUN, ADXL345_BOOL_FALSE);
/* set justify right */
adxl345_set_justify(ADXL345_JUSTIFY_RIGHT);
adxl345_get_justify(®);
printf("adxl345_get_justify == 0x%02x\r\n",reg);
/* set 100 rate */
adxl345_set_rate(ADXL345_RATE_100);
adxl345_get_rate(®);
printf("adxl345_get_rate == 0x%02x\r\n",reg);
/* set full resolution */
adxl345_set_full_resolution(ADXL345_BOOL_TRUE);
adxl345_get_full_resolution(®);
printf("adxl345_get_full_resolution == 0x%02x\r\n",reg);
/* 2g */
adxl345_set_range(ADXL345_RANGE_4G);
adxl345_get_range(®);
printf("adxl345_get_range == 0x%02x\r\n",reg);
/* start measure */
adxl345_set_measure(ADXL345_BOOL_TRUE);
adxl345_get_measure(®);
printf("adxl345_get_measure == 0x%02x\r\n",reg);
uint8_t xyz_data[6] = {0};
uint16_t x_data;
uint16_t y_data;
uint16_t z_data;
while(1)
{
adxl345_get_x_y_z_data(ADXL345_REG_DATAX0,xyz_data,6);
x_data = (int16_t)(xyz_data[1] << 8) | xyz_data[0]; /* set raw z */
y_data = (int16_t)(xyz_data[3] << 8) | xyz_data[2]; /* set raw y */
z_data = (int16_t)(xyz_data[5] << 8) | xyz_data[4];
printf("adxl345_get_x_data == %0.2f g\r\n",(float)x_data * 0.0039f);
printf("adxl345_get_y_data == %0.2f g\r\n",(float)y_data * 0.0039f);
printf("adxl345_get_z_data == %0.2f g\r\n",(float)z_data * 0.0039f);
delay_1ms(1000);
}
}
5、各寄存器设置跟读取函数
/**
* 获取设备ID的函数
*/
static void adxl345_get_device_id(uint8_t *id)
{
adxl345_read_reg(ADXL345_REG_DEVID,id);
}
/**
* 设置中断是高电平还是低电平的函数
*/
static uint8_t adxl345_set_interrupt_active_level(adxl345_interrupt_active_level_t active_level)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_DATA_FORMAT,&value);
value &= ~(1 << 5); /* clear config */
value |= (active_level << 5);
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_DATA_FORMAT,value);
return 0;
}
static uint8_t adxl345_get_interrupt_active_level(adxl345_interrupt_active_level_t *active_level)
{
uint8_t value = 0;
adxl345_read_reg(ADXL345_REG_DATA_FORMAT,&value);
value &= (0x01<<5);
*active_level = (adxl345_interrupt_active_level_t )(value >> 5);
return 0;
}
static uint8_t adxl345_set_auto_sleep(adxl345_bool_t enable)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_POWER_CTL,&value);
value &= ~(1 << 4); /* clear config */
value |= enable << 4;
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_POWER_CTL,value);
return 0;
}
static uint8_t adxl345_get_auto_sleep(adxl345_bool_t *enable)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_POWER_CTL,&value);
value &= (0x01 << 4);
*enable = (adxl345_bool_t )(value >> 4);
return 0;
}
static uint8_t adxl345_set_sleep(adxl345_bool_t enable)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_POWER_CTL,&value);
value &= ~(1 << 2); /* clear config */
value |= enable << 2;
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_POWER_CTL,value);
return 0;
}
static uint8_t adxl345_get_sleep(adxl345_bool_t *enable)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_POWER_CTL,&value);
value &= (0x01 << 2); /* clear config */
*enable = (adxl345_bool_t) (value >>2);
return 0;
}
static uint8_t adxl345_set_sleep_frequency(adxl345_sleep_frequency_t sleep_frequency)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_POWER_CTL,&value);
value &= ~(0x03 << 0); /* clear config */
value |= (sleep_frequency << 0);
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_POWER_CTL,value);
return 0;
}
static uint8_t adxl345_get_sleep_frequency(adxl345_sleep_frequency_t *sleep_frequency)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_POWER_CTL,&value);
value &= (0x03 << 0); /* clear config */
*sleep_frequency = (adxl345_sleep_frequency_t) (value >> 0);
return 0;
}
static uint8_t adxl345_set_fifo_mode(adxl345_mode_t fifo_mode)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_FIFO_CTL,&value);
value &= ~(0x03 << 6); /* clear config */
value |= (fifo_mode << 6);
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_FIFO_CTL,value);
return 0;
}
static uint8_t adxl345_get_fifo_mode(adxl345_mode_t *fifo_mode)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_FIFO_CTL,&value);
value &= (0x03 << 6); /* clear config */
*fifo_mode = (adxl345_mode_t) value >> 6;
return 0;
}
static uint8_t adxl345_set_trigger_pin(adxl345_interrupt_pin_t pin)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_FIFO_CTL,&value);
value &= ~(0x01<< 5); /* clear config */
value |= (pin << 5);
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_FIFO_CTL,value);
return 0;
}
static uint8_t adxl345_get_trigger_pin(adxl345_interrupt_pin_t *pin)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_FIFO_CTL,&value);
value &= (0x01<< 5); /* clear config */
*pin = (adxl345_interrupt_pin_t) value >> 5;
return 0;
}
static uint8_t adxl345_set_watermark(uint8_t level)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_FIFO_CTL,&value);
value &= ~(0x1F<< 0); /* clear config */
value |= (level << 0);
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_FIFO_CTL,value);
return 0;
}
static uint8_t adxl345_get_watermark(uint8_t *level)
{
int value = 0;
adxl345_read_reg(ADXL345_REG_FIFO_CTL,&value);
value &= (0x1F<< 0); /* clear config */
*level = value >> 0;
return 0;
}
static uint8_t adxl345_offset_convert_to_register(float g, uint8_t *reg)
{
*reg = (int8_t)(g / 0.0156f);
return 0; // 比例因子为15.6 mg/LSB(即0x7F = 2 g)。
}
static uint8_t adxl345_offset_convert_to_data(uint8_t reg, float *g)
{
*g = (float)(reg) * 0.0156f;
return 0;
}
static uint8_t adxl345_set_offset(uint8_t x, uint8_t y, uint8_t z)
{
adxl345_write_reg(ADXL345_REG_OFSX,x);
adxl345_write_reg(ADXL345_REG_OFSY,y);
adxl345_write_reg(ADXL345_REG_OFSZ,z);
return 0;
}
static uint8_t adxl345_get_offset(uint8_t *x, uint8_t *y, uint8_t *z)
{
adxl345_read_reg(ADXL345_REG_OFSX,x);
adxl345_read_reg(ADXL345_REG_OFSY,y);
adxl345_read_reg(ADXL345_REG_OFSZ,z);
return 0;
}
static uint8_t adxl345_tap_threshold_convert_to_register(float g, uint8_t *reg)
{
*reg = (uint8_t)(g / 0.0625f); /* convert real data to register data */
return 0; /* success return 0 */
}
static uint8_t adxl345_tap_threshold_convert_to_data(uint8_t reg, float *g)
{
*g = (float)(reg) * 0.0625f; /* convert raw data to real data */
return 0; /* success return 0 */
}
static uint8_t adxl345_set_tap_threshold(uint8_t threshold)
{
adxl345_write_reg(ADXL345_REG_THRESH_TAP ,threshold); /* write config */
return 0;
}
static uint8_t adxl345_get_tap_threshold(uint8_t *threshold)
{
adxl345_read_reg(ADXL345_REG_THRESH_TAP ,threshold); /* write config */
return 0;
}
static uint8_t adxl345_duration_convert_to_register(uint32_t us, uint8_t *reg)
{
*reg = (uint8_t)(us / 625); /* convert real data to register data */
return 0; /* success return 0 */
}
static uint8_t adxl345_duration_convert_to_data(uint8_t reg, uint32_t *us)
{
*us = (uint32_t)((float)(reg) * 625.0f); /* convert raw data to real data */
return 0; /* success return 0 */
}
static uint8_t adxl345_set_duration(uint8_t t)
{
adxl345_write_reg(ADXL345_REG_DUR, t); /* write config */
return 0;
}
static uint8_t adxl345_get_duration(uint8_t *t)
{
adxl345_read_reg(ADXL345_REG_DUR, t); /* write config */
return 0;
}
static uint8_t adxl345_latent_convert_to_register(float ms, uint8_t *reg)
{
*reg = (uint8_t)(ms / 1.25f); /* convert real data to register data */
return 0; /* success return 0 */
}
static uint8_t adxl345_latent_convert_to_data(uint8_t reg, float *ms)
{
*ms = (float)(reg) * 1.25f; /* convert raw data to real data */
return 0; /* success return 0 */
}
static uint8_t adxl345_set_latent(uint8_t t)
{
adxl345_write_reg(ADXL345_REG_LATENT, t); /* write config */
return 0;
}
static uint8_t adxl345_get_latent(uint8_t *t)
{
adxl345_read_reg(ADXL345_REG_LATENT, t); /* write config */
return 0;
}
static uint8_t adxl345_window_convert_to_register(float ms, uint8_t *reg)
{
*reg = (uint8_t)(ms / 1.25f); /* convert real data to register data */
return 0; /* success return 0 */
}
static uint8_t adxl345_window_convert_to_data(uint8_t reg, float *ms)
{
*ms = (float)(reg) * 1.25f; /* convert raw data to real data */
return 0; /* success return 0 */
}
uint8_t adxl345_set_window(uint8_t t)
{
adxl345_write_reg(ADXL345_REG_WINDOW, t); /* write config */
return 0;
}
uint8_t adxl345_get_window(uint8_t *t)
{
adxl345_read_reg(ADXL345_REG_WINDOW, t); /* write config */
return 0;
}
static uint8_t adxl345_set_tap_axis(adxl345_tap_axis_t axis, adxl345_bool_t enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_TAP_AXES,(uint8_t *)&prev); /* read config */
prev &= ~(1 << axis); /* clear axis */
prev |= enable << axis; /* set axis */
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_TAP_AXES, prev); /* write config */
return 0;
}
static uint8_t adxl345_get_tap_axis(adxl345_tap_axis_t axis, adxl345_bool_t *enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_TAP_AXES,(uint8_t *)&prev); /* read config */
prev &= (1 << axis); /* clear axis */
*enable = (adxl345_bool_t)(prev >> axis); /* set axis */
return 0;
}
static uint8_t adxl345_set_tap_suppress(adxl345_bool_t enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_TAP_AXES,(uint8_t *)&prev); /* read config */
prev &= ~(1 << 3); /* clear suppress */
prev |= enable << 3; /* set axis */
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_TAP_AXES, prev); /* write config */
return 0;
}
static uint8_t adxl345_get_tap_suppress(adxl345_bool_t *enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_TAP_AXES,(uint8_t *)&prev); /* read config */
prev &= (1 << 3); /* clear config */
*enable = (adxl345_bool_t)(prev >> 3);
return 0;
}
static uint8_t adxl345_set_interrupt_map(adxl345_interrupt_t type, adxl345_interrupt_pin_t pin)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_INT_MAP, (uint8_t *)&prev); /* read config */
prev &= ~(1 << type); /* clear type */
prev |= pin << type;
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_INT_MAP, prev); /* write config */
return 0;
}
static uint8_t adxl345_get_interrupt_map(adxl345_interrupt_t type, adxl345_interrupt_pin_t *pin)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_INT_MAP, (uint8_t *)&prev); /* read config */
prev &= (1 << type); /* clear config */
*pin = (adxl345_interrupt_pin_t)(prev >> type);
return 0;
}
static uint8_t adxl345_set_interrupt(adxl345_interrupt_t type, adxl345_bool_t enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_INT_ENABLE, (uint8_t *)&prev); /* read config */
prev &= ~(1 << type); /* clear interrupt */
prev |= enable << type;
delay_1ms(1); /* set interrupt */
adxl345_write_reg(ADXL345_REG_INT_ENABLE, prev); /* write config */
return 0;
}
static uint8_t adxl345_get_interrupt(adxl345_interrupt_t type, adxl345_bool_t *enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_INT_ENABLE, (uint8_t *)&prev); /* read config */
prev &= (1 << type); /* clear config */
*enable = (adxl345_bool_t)(prev >> type);
return 0;
}
static uint8_t adxl345_set_link_activity_inactivity(adxl345_bool_t enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_POWER_CTL, (uint8_t *)&prev); /* read config */
prev &= ~(1 << 5); /* clear config */
prev |= enable << 5;
delay_1ms(1); /* set interrupt */
adxl345_write_reg(ADXL345_REG_POWER_CTL, prev); /* write config */
return 0;
}
static uint8_t adxl345_get_link_activity_inactivity(adxl345_bool_t *enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_POWER_CTL, (uint8_t *)&prev); /* read config */
prev &= 1 << 5; /* get config */
*enable = (adxl345_bool_t)(prev >> 5);
return 0;
}
static uint8_t adxl345_action_threshold_convert_to_register(float g, uint8_t *reg)
{
*reg = (uint8_t)(g / 0.0625f); /* convert real data to register data */
return 0; /* success return 0 */
}
static uint8_t adxl345_action_threshold_convert_to_data(uint8_t reg, float *g)
{
*g = (float)(reg) * 0.0625f; /* convert raw data to real data */
return 0; /* success return 0 */
}
static uint8_t adxl345_set_action_threshold(uint8_t threshold)
{
adxl345_write_reg(ADXL345_REG_THRESH_ACT, threshold); /* write config */
return 0;
}
static uint8_t adxl345_get_action_threshold(uint8_t *threshold)
{
adxl345_read_reg(ADXL345_REG_THRESH_ACT, threshold); /* write config */
return 0;
}
static uint8_t adxl345_inaction_threshold_convert_to_register(float g, uint8_t *reg)
{
*reg = (uint8_t)(g / 0.0625f); /* convert real data to register data */
return 0; /* success return 0 */
}
static uint8_t adxl345_inaction_threshold_convert_to_data(uint8_t reg, float *g)
{
*g = (float)(reg) * 0.0625f; /* convert raw data to real data */
return 0; /* success return 0 */
}
static uint8_t adxl345_set_inaction_threshold(uint8_t threshold)
{
adxl345_write_reg(ADXL345_REG_THRESH_INACT, threshold); /* write config */
return 0;
}
static uint8_t adxl345_get_inaction_threshold(uint8_t *threshold)
{
adxl345_read_reg(ADXL345_REG_THRESH_INACT, threshold); /* read config */
return 0;
}
static uint8_t adxl345_inaction_time_convert_to_register(uint8_t s, uint8_t *reg)
{
*reg = s; /* convert real data to register data */
return 0; /* success return 0 */
}
static uint8_t adxl345_inaction_time_convert_to_data(uint8_t reg, uint8_t *s)
{
*s = reg; /* convert raw data to real data */
return 0; /* success return 0 */
}
static void adxl345_set_inaction_time(uint8_t t)
{
adxl345_write_reg(ADXL345_REG_TIME_INACT, t); /* write config */
}
static void adxl345_get_inaction_time(uint8_t *t)
{
adxl345_read_reg(ADXL345_REG_TIME_INACT, t); /* write config */
}
static void adxl345_set_action_inaction(adxl345_action_inaction_t type, adxl345_bool_t enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_ACT_INACT_CTL, (uint8_t *)&prev); /* read config */
prev &= ~(1 << type); /* clear type */
prev |= (enable << type); /* set type */
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_ACT_INACT_CTL,prev); /* write config */
}
static void adxl345_get_action_inaction(adxl345_action_inaction_t type, adxl345_bool_t *enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_ACT_INACT_CTL, (uint8_t *)&prev); /* read config */
prev &= (1 << type); /* get type */
*enable = (adxl345_bool_t)(prev >> type); /* set type */ /* success return 0 */
}
static void adxl345_set_action_coupled(adxl345_coupled_t coupled)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_ACT_INACT_CTL, (uint8_t *)&prev); /* read config */
prev &= ~(1 << 7); /* clear coupled */
prev |= (coupled << 7); /* set coupled */
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_ACT_INACT_CTL,prev); /* write config */
}
static void adxl345_get_action_coupled(adxl345_coupled_t *coupled)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_ACT_INACT_CTL, (uint8_t *)&prev); /* read config */
prev &= (1 << 7); /* clear config */
*coupled = (adxl345_coupled_t)(prev >> 7); /* set config */ /* success return 0 */
}
static void adxl345_set_inaction_coupled(adxl345_coupled_t coupled)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_ACT_INACT_CTL, (uint8_t *)&prev); /* read config */
prev &= ~(1 << 3); /* clear config */
prev |= (coupled << 3); /* set inaction coupled */
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_ACT_INACT_CTL, prev); /* write config */
}
static void adxl345_get_inaction_coupled(adxl345_coupled_t *coupled)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_ACT_INACT_CTL, (uint8_t *)&prev); /* read config */
prev &= (1 << 3); /* clear config */
*coupled = (adxl345_coupled_t)(prev >> 3); /* set config */ /* success return 0 */
}
static void adxl345_free_fall_threshold_convert_to_register(float g, uint8_t *reg)
{
*reg = (uint8_t)(g / 0.0625f); /* convert real data to register data */
}
static void adxl345_free_fall_threshold_convert_to_data(uint8_t reg, float *g)
{
*g = (float)(reg) * 0.0625f; /* convert raw data to real data */
}
static void adxl345_set_free_fall_threshold(uint8_t threshold)
{
adxl345_write_reg(ADXL345_REG_THRESH_FF, threshold); /* write config */
}
static void adxl345_get_free_fall_threshold(uint8_t *threshold)
{
adxl345_read_reg(ADXL345_REG_THRESH_FF, threshold); /* write config */
}
static void adxl345_free_fall_time_convert_to_register(uint16_t ms, uint8_t *reg)
{
*reg = (uint8_t)(ms / 5); /* convert real data to register data */
}
static void adxl345_free_fall_time_convert_to_data(uint8_t reg, uint16_t *ms)
{
*ms = reg * 5; /* convert raw data to real data */
}
static void adxl345_set_free_fall_time(uint8_t t)
{
adxl345_write_reg(ADXL345_REG_TIME_FF, t); /* write config */
}
static void adxl345_get_free_fall_time(uint8_t *t)
{
adxl345_read_reg(ADXL345_REG_TIME_FF, t); /* write config */
}
static void adxl345_set_justify(adxl345_justify_t enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_DATA_FORMAT, (uint8_t *)&prev); /* read config */
prev &= ~(1 << 2); /* clear config */
prev |= (enable << 2); /* set justify */
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_DATA_FORMAT, prev); /* write config */
}
static void adxl345_get_justify(adxl345_justify_t *enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_DATA_FORMAT, (uint8_t *)&prev); /* read config */
prev &= (1 << 2); /* get config */
*enable = (adxl345_justify_t)(prev >> 2); /* get justify */
}
static void adxl345_set_rate(adxl345_rate_t rate)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_BW_RATE, (uint8_t *)&prev); /* read config */
prev &= ~(0x1F); /* clear rate */
prev |= rate; /* set rate */
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_BW_RATE, prev); /* write config */
}
static void adxl345_get_rate(adxl345_rate_t *rate)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_BW_RATE, (uint8_t *)&prev); /* read config */
prev &= 0x1F; /* clear config */
*rate = (adxl345_rate_t)(prev); /* get rate */ /* success return 0 */
}
static void adxl345_set_full_resolution(adxl345_bool_t enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_DATA_FORMAT, (uint8_t *)&prev); /* read config */
prev &= ~(1 << 3); /* clear resolution */
prev |= (enable << 3);
delay_1ms(1); /* set resolution */
adxl345_write_reg(ADXL345_REG_DATA_FORMAT, prev ); /* write config */
}
static void adxl345_get_full_resolution(adxl345_bool_t *enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_DATA_FORMAT, (uint8_t *)&prev); /* read config */
prev &= (1 << 3); /* clear config */
*enable = (adxl345_bool_t)(prev >> 3); /* set resolution */ /* success return 0 */
}
static void adxl345_set_range(adxl345_range_t range)
{
uint8_t res, prev;
adxl345_read_reg(ADXL345_REG_DATA_FORMAT, (uint8_t *)&prev); /* read config */
prev &= ~(3 << 0); /* clear config */
prev |= (range << 0); /* set range */
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_DATA_FORMAT, prev); /* write config */
}
static void adxl345_get_range(adxl345_range_t *range)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_DATA_FORMAT, (uint8_t *)&prev); /* read config */
prev &= (3 << 0); /* get config */
*range = (adxl345_range_t)(prev >> 0); /* set range */
}
static void adxl345_set_measure(adxl345_bool_t enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_POWER_CTL, (uint8_t *)&prev); /* read config */
prev &= ~(1 << 3); /* clear config */
prev |= enable << 3; /* set measure */
delay_1ms(1);
adxl345_write_reg(ADXL345_REG_POWER_CTL,prev); /* write config */
}
static void adxl345_get_measure(adxl345_bool_t *enable)
{
uint8_t prev;
adxl345_read_reg(ADXL345_REG_POWER_CTL, (uint8_t *)&prev); /* read config */
prev &= 1 << 3; /* get config */
*enable = (adxl345_bool_t)(prev >> 3); /* get measure */
}
6、头文件定义
#ifndef __ADXL345_H__
#define __ADXL345_H__
#include "gd32f30x.h"
#define ENABLE_ADXL345 1
#define ADXL345_ADDR 0xA6
#define ADXL345_REG_DEVID 0x00 /**< device id register */
#define ADXL345_REG_THRESH_TAP 0x1D /**< thresh tap register */
#define ADXL345_REG_OFSX 0x1E /**< x offset register */
#define ADXL345_REG_OFSY 0x1F /**< y offset register */
#define ADXL345_REG_OFSZ 0x20 /**< z offset register */
#define ADXL345_REG_DUR 0x21 /**< duration time register */
#define ADXL345_REG_LATENT 0x22 /**< latent register */
#define ADXL345_REG_WINDOW 0x23 /**< window register */
#define ADXL345_REG_THRESH_ACT 0x24 /**< act thresh register */
#define ADXL345_REG_THRESH_INACT 0x25 /**< inact thresh register */
#define ADXL345_REG_TIME_INACT 0x26 /**< inact time register */
#define ADXL345_REG_ACT_INACT_CTL 0x27 /**< act inact ctl register */
#define ADXL345_REG_THRESH_FF 0x28 /**< free fall thresh register */
#define ADXL345_REG_TIME_FF 0x29 /**< free fall time register */
#define ADXL345_REG_TAP_AXES 0x2A /**< tap axes register */
#define ADXL345_REG_ACT_TAP_STATUS 0x2B /**< act tap status register */
#define ADXL345_REG_BW_RATE 0x2C /**< bandwidth rate register */
#define ADXL345_REG_POWER_CTL 0x2D /**< power control register */
#define ADXL345_REG_INT_ENABLE 0x2E /**< interrupt enable register */
#define ADXL345_REG_INT_MAP 0x2F /**< interrupt map register */
#define ADXL345_REG_INT_SOURCE 0x30 /**< interrupt source register */
#define ADXL345_REG_DATA_FORMAT 0x31 /**< data format register */
#define ADXL345_REG_DATAX0 0x32 /**< data X0 register */
#define ADXL345_REG_DATAX1 0x33 /**< data X1 register */
#define ADXL345_REG_DATAY0 0x34 /**< data Y0 register */
#define ADXL345_REG_DATAY1 0x35 /**< data Y1 register */
#define ADXL345_REG_DATAZ0 0x36 /**< data Z0 register */
#define ADXL345_REG_DATAZ1 0x37 /**< data Z1 register */
#define ADXL345_REG_FIFO_CTL 0x38 /**< fifo control register */
#define ADXL345_REG_FIFO_STATUS 0x39 /**< fifo status register */
typedef enum
{
ADXL345_BOOL_FALSE = 0x00, /**< false */
ADXL345_BOOL_TRUE = 0x01, /**< true */
} adxl345_bool_t;
typedef enum
{
ADXL345_INTERRUPT_ACTIVE_LEVEL_HIGH = 0x00, /**< interrupt active level high */
ADXL345_INTERRUPT_ACTIVE_LEVEL_LOW = 0x01, /**< interrupt active level low */
} adxl345_interrupt_active_level_t;
/**
* @brief adxl345 sleep frequency enumeration definition
*/
typedef enum
{
ADXL345_SLEEP_FREQUENCY_8HZ = 0x00, /**< sleep 8Hz */
ADXL345_SLEEP_FREQUENCY_4HZ = 0x01, /**< sleep 4Hz */
ADXL345_SLEEP_FREQUENCY_2HZ = 0x02, /**< sleep 2Hz */
ADXL345_SLEEP_FREQUENCY_1HZ = 0x03, /**< sleep 1Hz*/
} adxl345_sleep_frequency_t;
/**
* @brief adxl345 mode enumeration definition
*/
typedef enum
{
ADXL345_MODE_BYPASS = 0x00, /**< bypass mode */
ADXL345_MODE_FIFO = 0x01, /**< fifo mode */
ADXL345_MODE_STREAM = 0x02, /**< stream mode */
ADXL345_MODE_TRIGGER = 0x03, /**< trigger mode */
} adxl345_mode_t;
/**
* @brief adxl345 interrupt pin enumeration definition
*/
typedef enum
{
ADXL345_INTERRUPT_PIN1 = 0x00, /**< interrupt pin 1 */
ADXL345_INTERRUPT_PIN2 = 0x01, /**< interrupt pin 2 */
} adxl345_interrupt_pin_t;
typedef enum
{
ADXL345_TAP_AXIS_X = 0x02, /**< x axis tap */
ADXL345_TAP_AXIS_Y = 0x01, /**< y axis tap */
ADXL345_TAP_AXIS_Z = 0x00, /**< z axis tap */
} adxl345_tap_axis_t;
typedef enum
{
ADXL345_INTERRUPT_DATA_READY = 0x07, /**< data ready */
ADXL345_INTERRUPT_SINGLE_TAP = 0x06, /**< single tap */
ADXL345_INTERRUPT_DOUBLE_TAP = 0x05, /**< double tap */
ADXL345_INTERRUPT_ACTIVITY = 0x04, /**< activity */
ADXL345_INTERRUPT_INACTIVITY = 0x03, /**< inactivity */
ADXL345_INTERRUPT_FREE_FALL = 0x02, /**< free fall */
ADXL345_INTERRUPT_WATERMARK = 0x01, /**< watermark */
ADXL345_INTERRUPT_OVERRUN = 0x00, /**< overrun */
} adxl345_interrupt_t;
typedef enum
{
ADXL345_ACTION_X = 0x06, /**< x axis action */
ADXL345_ACTION_Y = 0x05, /**< y axis action */
ADXL345_ACTION_Z = 0x04, /**< z axis action */
ADXL345_INACTION_X = 0x02, /**< x axis inaction */
ADXL345_INACTION_Y = 0x01, /**< y axis inaction */
ADXL345_INACTION_Z = 0x00, /**< z axis inaction */
} adxl345_action_inaction_t;
typedef enum
{
ADXL345_COUPLED_DC = 0x00, /**< DC coupled */
ADXL345_COUPLED_AC = 0x01, /**< AC coupled */
} adxl345_coupled_t;
typedef enum
{
ADXL345_JUSTIFY_RIGHT = 0x00, /**< right justify */
ADXL345_JUSTIFY_LEFT = 0x01, /**< left justify */
} adxl345_justify_t;
typedef enum
{
ADXL345_RATE_0P1 = 0x00, /**< 0.1Hz */
ADXL345_RATE_0P2 = 0x01, /**< 0.2Hz */
ADXL345_RATE_0P39 = 0x02, /**< 0.39Hz */
ADXL345_RATE_0P78 = 0x03, /**< 0.78Hz */
ADXL345_RATE_1P56 = 0x04, /**< 1.56Hz */
ADXL345_RATE_3P13 = 0x05, /**< 3.13Hz */
ADXL345_RATE_6P25 = 0x06, /**< 6.25Hz */
ADXL345_RATE_12P5 = 0x07, /**< 12.5Hz */
ADXL345_RATE_25 = 0x08, /**< 25Hz */
ADXL345_RATE_50 = 0x09, /**< 50Hz */
ADXL345_RATE_100 = 0x0A, /**< 100Hz */
ADXL345_RATE_200 = 0x0B, /**< 200Hz */
ADXL345_RATE_400 = 0x0C, /**< 400Hz */
ADXL345_RATE_800 = 0x0D, /**< 800Hz */
ADXL345_RATE_1600 = 0x0E, /**< 1600Hz */
ADXL345_RATE_3200 = 0x0F, /**< 3200Hz */
ADXL345_LOW_POWER_RATE_12P5 = 0x17, /**< low power 12.5Hz */
ADXL345_LOW_POWER_RATE_25 = 0x18, /**< low power 25Hz */
ADXL345_LOW_POWER_RATE_50 = 0x19, /**< low power 50Hz */
ADXL345_LOW_POWER_RATE_100 = 0x1A, /**< low power 100Hz */
ADXL345_LOW_POWER_RATE_200 = 0x1B, /**< low power 200Hz */
ADXL345_LOW_POWER_RATE_400 = 0x1C, /**< low power 400Hz */
} adxl345_rate_t;
typedef enum
{
ADXL345_RANGE_2G = 0x00, /**< ±2G */
ADXL345_RANGE_4G = 0x01, /**< ±4G */
ADXL345_RANGE_8G = 0x02, /**< ±8G */
ADXL345_RANGE_16G = 0x03, /**< ±16G */
} adxl345_range_t;
void adxl345_xyz_read_init();
#endif
7、实验现象
main函数直接调用void adxl345_xyz_read_init()即可。
打印结果如下:
8、代码
代码路径:https://gitee.com/xiaoguo-tec_0/gd32-iap-code.git
9、注意
代码里要打印float数据,修改APPlication Makefile文件如下:
如果编译后文件太大,超出我们定义的50K,那么修改GD32F303RCTx_FLASH.ld文件,