1.1 概述
The ICM-20608-G is a 6-axis MotionTracking device that combines a 3-axis gyroscope, and a 3-axis accelerometer in a small 3x3x0.75mm (16-pin LGA) package. The gyroscope has a programmable full-scale range of ±250, ±500, ±1000, and ±2000 degrees/sec. The accelerometer has a user programmable accelerometer full-scale range of ±2g, ±4g, ±8g, and ±16g. Other industry-leading features include on-chip 16-bit ADCs, programmable digital filters, an embedded temperature sensor, and programmable interrupts. The device features I2 C and SPI serial interfaces, a VDD operating range of 1.71 to 3.45V, and a separate digital IO supply, VDDIO from 1.71V to 3.45V. Communication with all registers of the device is performed using either I2 C at 400kHz or SPI at 8MHz. 1.包含3轴陀螺仪数据和3轴加速度数据。 2.陀螺仪和加速度量程可设定,陀螺仪量程可设定位+-250,+-500,+-1000, +-2000角度每秒。加速度同理也可设定量程。 3.精度为16bit ADC转换。 4.使用I2C/SPI接口通信,I2C速率高达400KHz, SPI高达8MHz。
1.2 应用场景
1.3 陀螺仪和加速度特性
1.4 电器特性
可以看到FS_SEL,AFS_SEL用来选择陀螺仪和加速度计的量程。举个例子,当角速度量程为+-250时,那么ADC的数据为多少表示为1度呢?已知ADC精度16bit, 数据范围[0,65535], 假如ADC的数据为x, 那么x/65636 = 1/500,算出x= 131.272x,对应表格数据中的131。加速度的换算公式也是同理, 当AFS_SEL=0时,x/65536 = 1/4, x=16384。
1.5 交流电器特性
当用i2c通信,AD0引脚决定i2c从地址是0x68还是0x69。可以看到power-on reset上电时序,需要Valid power-on RESET时间最少0.01ms, 从启动到寄存器读写等11ms。
1.6 工作模式
1.7 SPI方式寄存器访问
数据上升沿锁存,下降沿数据发生改变。最大高达8MHz时钟,一次读写需要16个或者更多时钟周期,第一个字节传输寄存器地址,第二个字节传输数据。首字节的首位表示是读还是写。
#define ICM20608_CSN(n) (n ? gpio_pinwrite(GPIO1, 20, 1) : gpio_pinwrite(GPIO1, 20, 0)) /* SPI片选信号 */
/*
* @description : 写ICM20608指定寄存器
* @param - reg : 要读取的寄存器地址
* @param - value: 要写入的值
* @return : 无
*/
void icm20608_write_reg(unsigned char reg, unsigned char value)
{
/* ICM20608在使用SPI接口的时候寄存器地址
* 只有低7位有效,寄存器地址最高位是读/写标志位
* 读的时候要为1,写的时候要为0。
*/
reg &= ~0X80;
ICM20608_CSN(0); /* 使能SPI传输 */
spich0_readwrite_byte(ECSPI3, reg); /* 发送寄存器地址 */
spich0_readwrite_byte(ECSPI3, value); /* 发送要写入的值 */
ICM20608_CSN(1); /* 禁止SPI传输 */
}
/*
* @description : 读取ICM20608寄存器值
* @param - reg : 要读取的寄存器地址
* @return : 读取到的寄存器值
*/
unsigned char icm20608_read_reg(unsigned char reg)
{
unsigned char reg_val;
/* ICM20608在使用SPI接口的时候寄存器地址
* 只有低7位有效,寄存器地址最高位是读/写标志位
* 读的时候要为1,写的时候要为0。
*/
reg |= 0x80;
ICM20608_CSN(0); /* 使能SPI传输 */
spich0_readwrite_byte(ECSPI3, reg); /* 发送寄存器地址 */
reg_val = spich0_readwrite_byte(ECSPI3, 0XFF); /* 读取寄存器的值 */
ICM20608_CSN(1); /* 禁止SPI传输 */
return(reg_val); /* 返回读取到的寄存器值 */
}
2 ICM-20608-G寄存器描述
ICM-20608-G寄存器的地址和数据都是单字节。
2.1 控制寄存器
控制配置寄存器0x1a,0x1b,0x1c,0x1d,设置量程等配置。
0x19设置分频,不分频,配成0
0x1a设置陀螺仪低通滤波带宽BW=20Hz,配成0x4.
0x1b设置gyro量程,配成最大0x18.
0x1c设置加速度计的量程,也配成最大0x18.
0x1d设置加速度计低通滤波BW=21.2Hz
0x1e设置low power,配成0,关闭低功耗.
0x23设置fifo功能,这里配置0x0,禁用fifo.
设定量程,配置相关参数:
#define ICM20_SMPLRT_DIV 0x19
#define ICM20_CONFIG 0x1A
#define ICM20_GYRO_CONFIG 0x1B
#define ICM20_ACCEL_CONFIG 0x1C
#define ICM20_ACCEL_CONFIG2 0x1D
#define ICM20_LP_MODE_CFG 0x1E
#define ICM20_FIFO_EN 0x23
icm20608_write_reg(ICM20_SMPLRT_DIV, 0x00); /* 输出速率是内部采样率 */
icm20608_write_reg(ICM20_GYRO_CONFIG, 0x18); /* 陀螺仪±2000dps量程 */
icm20608_write_reg(ICM20_ACCEL_CONFIG, 0x18); /* 加速度计±16G量程 */
icm20608_write_reg(ICM20_CONFIG, 0x04); /* 陀螺仪低通滤波BW=20Hz */
icm20608_write_reg(ICM20_ACCEL_CONFIG2, 0x04); /* 加速度计低通滤波BW=21.2Hz */
icm20608_write_reg(ICM20_PWR_MGMT_2, 0x00); /* 打开加速度计和陀螺仪所有轴 */
icm20608_write_reg(ICM20_LP_MODE_CFG, 0x00); /* 关闭低功耗 */
icm20608_write_reg(ICM20_FIFO_EN, 0x00); /* 关闭FIFO */
2.2 数据寄存器
数据寄存器0x3b~0x48表示加速度和陀螺仪数据,可以看到该传感器的寄存器地址都是单字节,ADC精度16bit,因此需要2个寄存器来表示一个轴的坐标数据。
0x3b-0x40表示加速度计3轴数据。
0x42 温度数据
0x43~0x48陀螺仪3轴数据。
2.3 WHO_AM_I
寄存器表示设备ID,默认0xAF.
2.4 PWR_MGMT_1/PWR_MGMT_2
电源管理模式寄存器
可以看到bit6默认是一个sleep mode, bit7是复位信号,复位后,默认bit6会变成1,进入睡眠模式。Bit4 陀螺仪待机,bit3关闭温度传感器等等都不要开启,设置成0,bit[2:0]时钟选择自动。
可以看到设置成0,6轴数据全使能
复位初始化:
#define ICM20_PWR_MGMT_1 0x6B
#define ICM20_WHO_AM_I 0x75
icm20608_write_reg(ICM20_PWR_MGMT_1, 0x80); /* 复位,复位后为0x40,睡眠模式 */
delayms(50);
icm20608_write_reg(ICM20_PWR_MGMT_1, 0x01); /* 关闭睡眠,自动选择时钟 */
delayms(50);
regvalue = icm20608_read_reg(ICM20_WHO_AM_I);
printf("icm20608 id = %#Xrn", regvalue);
3 代码解析
icm20608.h
/* ICM20608寄存器
*复位后所有寄存器地址都为0,除了
*Register 107(0X6B) Power Management 1 = 0x40
*Register 117(0X75) WHO_AM_I = 0xAF或0xAE
*/
/* 陀螺仪和加速度自测(出产时设置,用于与用户的自检输出值比较) */
#define ICM20_SELF_TEST_X_GYRO 0x00
#define ICM20_SELF_TEST_Y_GYRO 0x01
#define ICM20_SELF_TEST_Z_GYRO 0x02
#define ICM20_SELF_TEST_X_ACCEL 0x0D
#define ICM20_SELF_TEST_Y_ACCEL 0x0E
#define ICM20_SELF_TEST_Z_ACCEL 0x0F
/* 陀螺仪静态偏移 */
#define ICM20_XG_OFFS_USRH 0x13
#define ICM20_XG_OFFS_USRL 0x14
#define ICM20_YG_OFFS_USRH 0x15
#define ICM20_YG_OFFS_USRL 0x16
#define ICM20_ZG_OFFS_USRH 0x17
#define ICM20_ZG_OFFS_USRL 0x18
#define ICM20_SMPLRT_DIV 0x19
#define ICM20_CONFIG 0x1A
#define ICM20_GYRO_CONFIG 0x1B
#define ICM20_ACCEL_CONFIG 0x1C
#define ICM20_ACCEL_CONFIG2 0x1D
#define ICM20_LP_MODE_CFG 0x1E
#define ICM20_ACCEL_WOM_THR 0x1F
#define ICM20_FIFO_EN 0x23
#define ICM20_FSYNC_INT 0x36
#define ICM20_INT_PIN_CFG 0x37
#define ICM20_INT_ENABLE 0x38
#define ICM20_INT_STATUS 0x3A
/* 加速度输出 */
#define ICM20_ACCEL_XOUT_H 0x3B
#define ICM20_ACCEL_XOUT_L 0x3C
#define ICM20_ACCEL_YOUT_H 0x3D
#define ICM20_ACCEL_YOUT_L 0x3E
#define ICM20_ACCEL_ZOUT_H 0x3F
#define ICM20_ACCEL_ZOUT_L 0x40
/* 温度输出 */
#define ICM20_TEMP_OUT_H 0x41
#define ICM20_TEMP_OUT_L 0x42
/* 陀螺仪输出 */
#define ICM20_GYRO_XOUT_H 0x43
#define ICM20_GYRO_XOUT_L 0x44
#define ICM20_GYRO_YOUT_H 0x45
#define ICM20_GYRO_YOUT_L 0x46
#define ICM20_GYRO_ZOUT_H 0x47
#define ICM20_GYRO_ZOUT_L 0x48
#define ICM20_SIGNAL_PATH_RESET 0x68
#define ICM20_ACCEL_INTEL_CTRL 0x69
#define ICM20_USER_CTRL 0x6A
#define ICM20_PWR_MGMT_1 0x6B
#define ICM20_PWR_MGMT_2 0x6C
#define ICM20_FIFO_COUNTH 0x72
#define ICM20_FIFO_COUNTL 0x73
#define ICM20_FIFO_R_W 0x74
#define ICM20_WHO_AM_I 0x75
/* 加速度静态偏移 */
#define ICM20_XA_OFFSET_H 0x77
#define ICM20_XA_OFFSET_L 0x78