ICM42605相比于ICM20602有更小的噪声,但它们的寄存器有一些差异,建议先查找ICM42605的数据手册熟悉熟悉。
本程序的一些底层实现函数是基于逐飞开源的RT1064库的,参考逐飞科技RT1064开源库: 逐飞科技针对参加各类竞赛以及使用RT1064进行产品开发,制作的恩智浦RT1064高性能MCU开源库。 (gitee.com)
1. icm42605.h,首先是头文件宏定义寄存器地址及必要的寄存器数值:
#ifndef _icm42605_h_
#define _icm42605_h_
#include "zf_common_typedef.h"
#define ICM42605_USE_SOFT_IIC (0) // 默认使用硬件 SPI 方式驱动
#if ICM42605_USE_SOFT_IIC // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 IIC 驱动====================================================
#define ICM42605_SOFT_IIC_DELAY (100) // 软件 IIC 的时钟延时周期 数值越小 IIC 通信速率越快
#define ICM42605_SCL_PIN (B23) // 软件 IIC SCL 引脚 连接 ICM42605 的 SCL 引脚
#define ICM42605_SDA_PIN (B22) // 软件 IIC SDA 引脚 连接 ICM42605 的 SDA 引脚
//====================================================软件 IIC 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define ICM42605_SPI_SPEED (24 * 1000 * 1000) // 硬件 SPI 速率
#define ICM42605_SPI (SPI_4) // 硬件 SPI 号
#define ICM42605_SPC_PIN (SPI4_SCK_C23) // 硬件 SPI SCK 引脚
#define ICM42605_SDI_PIN (SPI4_MOSI_C22) // 硬件 SPI MOSI 引脚
#define ICM42605_SDO_PIN (SPI4_MISO_C21) // 硬件 SPI MISO 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define ICM42605_CS_PIN (C20) // CS 片选引脚
#define ICM42605_CS(x) ((x) ? (gpio_high(ICM42605_CS_PIN)) : (gpio_low(ICM42605_CS_PIN)))
#define ICM42605_TIMEOUT_COUNT (0x00FF) // ICM42605 超时计数
//================================================定义 ICM42605 内部地址================================================
//#define ICM42605_DEV_ADDR (0x69) // SA0接地:0x68 SA0上拉:0x69 模块默认上拉
#define ICM42605_SPI_W (0x00)
#define ICM42605_SPI_R (0x80)
#define ICM42605_ID (0x42)//WHO AM I的值
/***********************************/
// Bank 0
#define ICM42605_DEVICE_CONFIG 0x11
#define ICM42605_DRIVE_CONFIG 0x13
#define ICM42605_INT_CONFIG 0x14
#define ICM42605_FIFO_CONFIG 0x16
#define ICM42605_TEMP_DATA1 0x1D
#define ICM42605_TEMP_DATA0 0x1E
#define ICM42605_ACCEL_DATA_X1 0x1F
#define ICM42605_ACCEL_DATA_X0 0x20
#define ICM42605_ACCEL_DATA_Y1 0x21
#define ICM42605_ACCEL_DATA_Y0 0x22
#define ICM42605_ACCEL_DATA_Z1 0x23
#define ICM42605_ACCEL_DATA_Z0 0x24
#define ICM42605_GYRO_DATA_X1 0x25
#define ICM42605_GYRO_DATA_X0 0x26
#define ICM42605_GYRO_DATA_Y1 0x27
#define ICM42605_GYRO_DATA_Y0 0x28
#define ICM42605_GYRO_DATA_Z1 0x29
#define ICM42605_GYRO_DATA_Z0 0x2A
#define ICM42605_TMST_FSYNCH 0x2B
#define ICM42605_TMST_FSYNCL 0x2C
#define ICM42605_INT_STATUS 0x2D
#define ICM42605_FIFO_COUNTH 0x2E
#define ICM42605_FIFO_COUNTL 0x2F
#define ICM42605_FIFO_DATA 0x30
#define ICM42605_APEX_DATA0 0x31
#define ICM42605_APEX_DATA1 0x32
#define ICM42605_APEX_DATA2 0x33
#define ICM42605_APEX_DATA3 0x34
#define ICM42605_APEX_DATA4 0x35
#define ICM42605_APEX_DATA5 0x36
#define ICM42605_INT_STATUS2 0x37
#define ICM42605_INT_STATUS3 0x38
#define ICM42605_SIGNAL_PATH_RESET 0x4B
#define ICM42605_INTF_CONFIG0 0x4C
#define ICM42605_INTF_CONFIG1 0x4D
#define ICM42605_PWR_MGMT0 0x4E
#define ICM42605_GYRO_CONFIG0 0x4F
#define ICM42605_ACCEL_CONFIG0 0x50
#define ICM42605_GYRO_CONFIG1 0x51
#define ICM42605_GYRO_ACCEL_CONFIG0 0x52
#define ICM42605_ACCEL_CONFIG1 0x53
#define ICM42605_TMST_CONFIG 0x54
#define ICM42605_APEX_CONFIG0 0x56
#define ICM42605_SMD_CONFIG 0x57
#define ICM42605_FIFO_CONFIG1 0x5F
#define ICM42605_FIFO_CONFIG2 0x60
#define ICM42605_FIFO_CONFIG3 0x61
#define ICM42605_FSYNC_CONFIG 0x62
#define ICM42605_INT_CONFIG0 0x63
#define ICM42605_INT_CONFIG1 0x64
#define ICM42605_INT_SOURCE0 0x65
#define ICM42605_INT_SOURCE1 0x66
#define ICM42605_INT_SOURCE3 0x68
#define ICM42605_INT_SOURCE4 0x69
#define ICM42605_FIFO_LOST_PKT0 0x6C
#define ICM42605_FIFO_LOST_PKT1 0x6D
#define ICM42605_SELF_TEST_CONFIG 0x70
#define ICM42605_WHO_AM_I 0x75
#define ICM42605_REG_BANK_SEL 0x76
// Bank 1
#define ICM42605_SENSOR_CONFIG0 0x03
#define ICM42605_GYRO_CONFIG_STATIC2 0x0B
#define ICM42605_GYRO_CONFIG_STATIC3 0x0C
#define ICM42605_GYRO_CONFIG_STATIC4 0x0D
#define ICM42605_GYRO_CONFIG_STATIC5 0x0E
#define ICM42605_GYRO_CONFIG_STATIC6 0x0F
#define ICM42605_GYRO_CONFIG_STATIC7 0x10
#define ICM42605_GYRO_CONFIG_STATIC8 0x11
#define ICM42605_GYRO_CONFIG_STATIC9 0x12
#define ICM42605_GYRO_CONFIG_STATIC10 0x13
#define ICM42605_XG_ST_DATA 0x5F
#define ICM42605_YG_ST_DATA 0x60
#define ICM42605_ZG_ST_DATA 0x61
#define ICM42605_TMSTVAL0 0x62
#define ICM42605_TMSTVAL1 0x63
#define ICM42605_TMSTVAL2 0x64
#define ICM42605_INTF_CONFIG4 0x7A
#define ICM42605_INTF_CONFIG5 0x7B
#define ICM42605_INTF_CONFIG6 0x7C
// Bank 2
#define ICM42605_ACCEL_CONFIG_STATIC2 0x03
#define ICM42605_ACCEL_CONFIG_STATIC3 0x04
#define ICM42605_ACCEL_CONFIG_STATIC4 0x05
#define ICM42605_XA_ST_DATA 0x3B
#define ICM42605_YA_ST_DATA 0x3C
#define ICM42605_ZA_ST_DATA 0x3D
// Bank 4
#define ICM42605_GYRO_ON_OFF_CONFIG 0x0E
#define ICM42605_APEX_CONFIG1 0x40
#define ICM42605_APEX_CONFIG2 0x41
#define ICM42605_APEX_CONFIG3 0x42
#define ICM42605_APEX_CONFIG4 0x43
#define ICM42605_APEX_CONFIG5 0x44
#define ICM42605_APEX_CONFIG6 0x45
#define ICM42605_APEX_CONFIG7 0x46
#define ICM42605_APEX_CONFIG8 0x47
#define ICM42605_APEX_CONFIG9 0x48
#define ICM42605_ACCEL_WOM_X_THR 0x4A
#define ICM42605_ACCEL_WOM_Y_THR 0x4B
#define ICM42605_ACCEL_WOM_Z_THR 0x4C
#define ICM42605_INT_SOURCE6 0x4D
#define ICM42605_INT_SOURCE7 0x4E
#define ICM42605_INT_SOURCE8 0x4F
#define ICM42605_INT_SOURCE9 0x50
#define ICM42605_INT_SOURCE10 0x51
#define ICM42605_OFFSET_USER0 0x77
#define ICM42605_OFFSET_USER1 0x78
#define ICM42605_OFFSET_USER2 0x79
#define ICM42605_OFFSET_USER3 0x7A
#define ICM42605_OFFSET_USER4 0x7B
#define ICM42605_OFFSET_USER5 0x7C
#define ICM42605_OFFSET_USER6 0x7D
#define ICM42605_OFFSET_USER7 0x7E
#define ICM42605_OFFSET_USER8 0x7F
/** 寄存器赋值宏定义 **/
#define ICM42605_SOFT_RESET_CONFIG (0x01)
#define ICM42605_Bank_0 (0x00)
#define ICM42605_Bank_1 (0x01)
#define ICM42605_Bank_2 (0x02)
#define ICM42605_Bank_3 (0x03)
#define ICM42605_Bank_4 (0x04)
#define FIFO_THS_INT1_EN (0x04)//FIFO threshold interrupt
#define ICM42605_ACCEL_FS_SEL (0x20) // 加速度计量程
// 设置为:0x00 加速度计量程为:±16g 获取到的加速度计数据 除以2048 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x20 加速度计量程为:±8g 获取到的加速度计数据 除以4096 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x40 加速度计量程为:±4g 获取到的加速度计数据 除以8192 可以转化为带物理单位的数据,单位:g(m/s^2)
// 设置为:0x60 加速度计量程为:±2g 获取到的加速度计数据 除以16384 可以转化为带物理单位的数据,单位:g(m/s^2)
#define ICM42605_ACCEL_ODR (0x06) // 加速度计输出数据速率
// 设置为:0x03 加速度计输出数据速率为:8kHz (LN mode)
// 设置为:0x04 加速度计输出数据速率为:4kHz (LN mode)
// 设置为:0x05 加速度计输出数据速率为:2kHz (LN mode)
// 设置为:0x06 加速度计输出数据速率为:1kHz (LN mode) (default)
// 设置为:0x07 加速度计输出数据速率为:200Hz (LP or LN mode)
// 设置为:0x08 加速度计输出数据速率为:100Hz (LP or LN mode)
// 设置为:0x09 加速度计输出数据速率为:50Hz (LP or LN mode)
// 设置为:0x0A 加速度计输出数据速率为:25Hz (LP or LN mode)
// 设置为:0x0B 加速度计输出数据速率为:12.5Hz (LP or LN mode)
// 设置为:0x0C 加速度计输出数据速率为:6.25Hz (LP mode)
// 设置为:0x0D 加速度计输出数据速率为:3.125Hz (LP mode)
// 设置为:0x0E 加速度计输出数据速率为:1.5625Hz (LP mode)
// 设置为:0x0F 加速度计输出数据速率为:500Hz (LP or LN mode)
#define ICM42605_ACCEL_MODE (0x03) //加速度计模式
// 设置为:0x00 加速度计模式为:Turns accelerometer off (default)
// 设置为:0x01 加速度计模式为:Turns accelerometer off
// 设置为:0x02 加速度计模式为:Places accelerometer in Low Power (LP) Mode
// 设置为:0x03 加速度计模式为:Places accelerometer in Low Noise (LN) Mode
#define ICM42605_GYRO_FS_SEL (0x00) // 陀螺仪量程
// 设置为:0x00 陀螺仪量程为:±2000 dps 获取到的陀螺仪数据除以16.4 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x20 陀螺仪量程为:±1000 dps 获取到的陀螺仪数据除以32.8 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x40 陀螺仪量程为:±500 dps 获取到的陀螺仪数据除以65.5 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x60 陀螺仪量程为:±250 dps 获取到的陀螺仪数据除以131 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0x80 陀螺仪量程为:±125 dps 获取到的陀螺仪数据除以262 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0xA0 陀螺仪量程为:±62.5 dps 获取到的陀螺仪数据除以524.3 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0xC0 陀螺仪量程为:±31.25 dps 获取到的陀螺仪数据除以1048.6 可以转化为带物理单位的数据,单位为:°/s
// 设置为:0xE0 陀螺仪量程为:±15.625dps 获取到的陀螺仪数据除以2097.2 可以转化为带物理单位的数据,单位为:°/s
#define ICM42605_GYRO_ODR (0x06) // 陀螺仪输出数据速率
// 设置为:0x03 加速度计输出数据速率为:8kHz
// 设置为:0x04 加速度计输出数据速率为:4kHz
// 设置为:0x05 加速度计输出数据速率为:2kHz
// 设置为:0x06 加速度计输出数据速率为:1kHz (default)
// 设置为:0x07 加速度计输出数据速率为:200Hz
// 设置为:0x08 加速度计输出数据速率为:100Hz
// 设置为:0x09 加速度计输出数据速率为:50Hz
// 设置为:0x0A 加速度计输出数据速率为:25Hz
// 设置为:0x0B 加速度计输出数据速率为:12.5Hz
// 设置为:0x0F 加速度计输出数据速率为:500Hz
#define ICM42605_GYRO_MODE (0x0C) //陀螺仪模式
// 设置为:0x00 陀螺仪模式为:Turns gyroscope off (default)
// 设置为:0x04 陀螺仪模式为:Places gyroscope in Standby Mode
// 设置为:0x0C 陀螺仪模式为:Places gyroscope in Low Noise (LN) Mode
//================================================定义 ICM42605 内部地址================================================
extern int16 icm42605_gyro_x, icm42605_gyro_y, icm42605_gyro_z; // 三轴陀螺仪数据
extern int16 icm42605_acc_x, icm42605_acc_y, icm42605_acc_z; // 三轴加速度计数据
extern int16 icm42605_temp;
void icm42605_get_temp (void);
void icm42605_get_acc (void);
void icm42605_get_gyro (void);
float icm42605_temp_transition (int16 acc_value); // 将 ICM42605 加速度计数据转换为实际物理数据
float icm42605_acc_transition (int16 acc_value); // 将 ICM42605 加速度计数据转换为实际物理数据
float icm42605_gyro_transition (int16 gyro_value); // 将 ICM42605 陀螺仪数据转换为实际物理数据
uint8 icm42605_init (void);
#endif
为了便于移植和理解,接下来直接给出初始化及读取数据的函数,其中调用了icm42605_read_registers()等对寄存器读写的函数,后面会说明。
2. 初始化函数
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 ICM42605 自检
// 参数说明 void
// 返回参数 uint8 1-自检失败 0-自检成功
// 使用示例 icm42605_self_check();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 icm42605_self_check (void)
{
uint8 dat = 0, return_state = 0;
uint16 timeout_count = 0;
while(ICM42605_ID != dat) // 判断 ID 是否正确
{
if(timeout_count ++ > ICM42605_TIMEOUT_COUNT)
{
return_state = 1;
break;
}
dat = icm42605_read_register(ICM42605_WHO_AM_I);
system_delay_ms(10);
}
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 ICM42605
// 参数说明 void
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 icm42605_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 icm42605_init (void)
{
uint8 val = 0x0, return_state = 0;
uint16 timeout_count = 0;
system_delay_ms(10); // 上电延时
#if ICM42605_USE_SOFT_IIC
soft_iic_init(&icm42605_iic_struct, ICM42605_DEV_ADDR, ICM42605_SOFT_IIC_DELAY, ICM42605_SCL_PIN, ICM42605_SDA_PIN);
#else
spi_init(ICM42605_SPI, SPI_MODE0, ICM42605_SPI_SPEED, ICM42605_SPC_PIN, ICM42605_SDI_PIN, ICM42605_SDO_PIN, SPI_CS_NULL);
gpio_init(ICM42605_CS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
#endif
do
{
if(icm42605_self_check())
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 ICM42605 自检出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "icm42605 self check error.");
return_state = 1;
break;
}
icm42605_write_register(ICM42605_REG_BANK_SEL,ICM42605_Bank_0); //设置bank 0区域寄存器
icm42605_write_register(ICM42605_DEVICE_CONFIG, ICM42605_SOFT_RESET_CONFIG); // 复位设备
system_delay_ms(2); //After writing 1 to this SOFT_RESET_CONFIG, wait 1ms for soft reset to be effective, before attempting any other register access
do
{ // 等待复位成功
val = icm42605_read_register(ICM42605_DEVICE_CONFIG);
if(timeout_count ++ > ICM42605_TIMEOUT_COUNT)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 ICM42605 自检出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "icm42605 reset error.");
return_state = 1;
break;
}
}while(0x00 != val);//DEVICE_CONFIG Reset value: 0x00
if(1 == return_state)
{
break;
}
icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_1); //设置bank 1区域寄存器
icm42605_write_register(ICM42605_INTF_CONFIG4, 0x02); //设置为4线SPI通信
// icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_0); //设置bank 0区域寄存器
// icm42605_write_register(ICM42605_INTF_CONFIG0, 0xB0);
// icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_0); //设置bank 0区域寄存器
// icm42605_write_register(ICM42605_FIFO_CONFIG, 0x40); //Stream-to-FIFO Mode(page61)
//开启加速度计、陀螺仪的FIFO
// val = icm42605_read_register(ICM42605_INT_SOURCE0);
// icm42605_write_register(ICM42605_INT_SOURCE0, ICM42605_Bank_0);
// icm42605_write_register(ICM42605_FIFO_CONFIG2, 0x00); // watermark
// icm42605_write_register(ICM42605_FIFO_CONFIG3, 0x02); // watermark
// icm42605_write_register(ICM42605_INT_SOURCE0, val);
// icm42605_write_register(ICM42605_FIFO_CONFIG1, 0x47); // Enable the accel and gyro to the FIFO
// icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_0); //设置bank 0区域寄存器
// icm42605_write_register(ICM42605_INT_CONFIG, 0x36);
// icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_0); //设置bank 0区域寄存器
// val = (icm42605_read_register(ICM42605_INT_SOURCE0)|FIFO_THS_INT1_EN);
// icm42605_write_register(ICM42605_INT_SOURCE0, val);
// 设置加速度计量程
icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_0); //设置bank 0区域寄存器
val = ((icm42605_read_register(ICM42605_ACCEL_CONFIG0)&0x1F)|(ICM42605_ACCEL_FS_SEL));//8g //page74
icm42605_write_register(ICM42605_ACCEL_CONFIG0, val);
// 设置加速度计输出数据速率
icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_0); //设置bank 0区域寄存器
val = ((icm42605_read_register(ICM42605_ACCEL_CONFIG0)&0xF0)|(ICM42605_ACCEL_ODR));//50Hz //page74
icm42605_write_register(ICM42605_ACCEL_CONFIG0, val);
// 设置陀螺仪量程
icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_0); //设置bank 0区域寄存器
val = ((icm42605_read_register(ICM42605_GYRO_CONFIG0)&0x1F)|(ICM42605_GYRO_FS_SEL));
icm42605_write_register(ICM42605_GYRO_CONFIG0,val);
// 设置陀螺仪输出数据速率
icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_0); //设置bank 0区域寄存器
val = ((icm42605_read_register(ICM42605_GYRO_CONFIG0)&0xF0)|ICM42605_GYRO_ODR);
icm42605_write_register(ICM42605_GYRO_CONFIG0, val);
// // 设置陀螺仪低通滤波器
// icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_0); //设置bank 0区域寄存器
// val = ((icm42605_read_register(ICM42605_GYRO_ACCEL_CONFIG0)&0xF0)|0x07);
// icm42605_write_register(ICM42605_GYRO_ACCEL_CONFIG0, val);
// // 设置陀螺仪陷波滤波器 滤除谐波,还要单独配置每个轴
// icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_1); //设置bank 0区域寄存器
// val = ((icm42605_read_register(ICM42605_GYRO_CONFIG_STATIC10)&0x8F)|0x00);
// icm42605_write_register(ICM42605_GYRO_CONFIG_STATIC10, val);
//
// val = ((icm42605_read_register(ICM42605_GYRO_CONFIG_STATIC9)&0x8F)|0x00);
// icm42605_write_register(ICM42605_GYRO_CONFIG_STATIC9, val);
// 设置加速度计模式
icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_0); //设置bank 0区域寄存器
val = icm42605_read_register(ICM42605_PWR_MGMT0)|(ICM42605_ACCEL_MODE); // Accel on in LNM //读取PWR—MGMT0当前寄存器的值(page72)
icm42605_write_register(ICM42605_PWR_MGMT0, val);
system_delay_ms(1);
// 设置陀螺仪模式
icm42605_write_register(ICM42605_REG_BANK_SEL, ICM42605_Bank_0); //设置bank 0区域寄存器
val = icm42605_read_register(ICM42605_PWR_MGMT0)|(ICM42605_GYRO_MODE); // Gyro on in LN
icm42605_write_register(ICM42605_PWR_MGMT0, val); //操作完PWR—MGMT0寄存器后 200us内不能有任何读写寄存器的操作
system_delay_ms(1);
printf("ok");
}while(0);
return return_state;
}
3. 读取加速度计数值及物理单位转化
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 ICM42605 加速度计数据
// 参数说明 void
// 返回参数 void
// 使用示例 icm42605_get_acc(); // 执行该函数后,直接查看对应的变量即可
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void icm42605_get_acc (void)
{
uint8 dat[6];
icm42605_read_registers(ICM42605_ACCEL_DATA_X1, dat, 6);
icm42605_acc_x = (int16)(((uint16)dat[0] << 8 | dat[1]));
icm42605_acc_y = (int16)(((uint16)dat[2] << 8 | dat[3]));
icm42605_acc_z = (int16)(((uint16)dat[4] << 8 | dat[5]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 ICM42605 加速度计数据转换为实际物理数据
// 参数说明 acc_value 任意轴的加速度计数据
// 返回参数 void
// 使用示例 float data = icm42605_acc_transition(icm42605_acc_x); // 单位为 g(m/s^2)
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
float icm42605_acc_transition (int16 acc_value)
{
float acc_data = 0;
switch(ICM42605_ACCEL_FS_SEL)
{
case 0x00: acc_data = (float)acc_value / 2048; break;// 设置为:0x00 加速度计量程为:±16g 获取到的加速度计数据 除以2048 可以转化为带物理单位的数据,单位:g(m/s^2)
case 0x20: acc_data = (float)acc_value / 4096; break;// 设置为:0x20 加速度计量程为:±8g 获取到的加速度计数据 除以4096 可以转化为带物理单位的数据,单位:g(m/s^2)
case 0x40: acc_data = (float)acc_value / 8192; break;// 设置为:0x40 加速度计量程为:±4g 获取到的加速度计数据 除以8192 可以转化为带物理单位的数据,单位:g(m/s^2)
case 0x60: acc_data = (float)acc_value / 16384; break;// 设置为:0x60 加速度计量程为:±2g 获取到的加速度计数据 除以16384 可以转化为带物理单位的数据,单位:g(m/s^2)
default: break;
}
return acc_data;
}
4. 读取陀螺仪计数值及物理单位转化
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取ICM42605陀螺仪数据
// 参数说明 void
// 返回参数 void
// 使用示例 icm42605_get_gyro(); // 执行该函数后,直接查看对应的变量即可
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void icm42605_get_gyro (void)
{
uint8 dat[6];
icm42605_read_registers(ICM42605_GYRO_DATA_X1, dat, 6);
icm42605_gyro_x = (int16)(((uint16)dat[0] << 8 | dat[1]));
icm42605_gyro_y = (int16)(((uint16)dat[2] << 8 | dat[3]));
icm42605_gyro_z = (int16)(((uint16)dat[4] << 8 | dat[5]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 ICM42605 陀螺仪数据转换为实际物理数据
// 参数说明 gyro_value 任意轴的陀螺仪数据
// 返回参数 void
// 使用示例 float data = icm42605_gyro_transition(icm42605_gyro_x); // 单位为°/s
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
float icm42605_gyro_transition (int16 gyro_value)
{
float gyro_data = 0;
switch(ICM42605_GYRO_FS_SEL)
{
case 0x00: gyro_data = (float)gyro_value / 16.4f; break;// 设置为:0x00 陀螺仪量程为:±2000 dps 获取到的陀螺仪数据除以16.4 可以转化为带物理单位的数据,单位为:°/s
case 0x20: gyro_data = (float)gyro_value / 32.8f; break;// 设置为:0x20 陀螺仪量程为:±1000 dps 获取到的陀螺仪数据除以32.8 可以转化为带物理单位的数据,单位为:°/s
case 0x40: gyro_data = (float)gyro_value / 65.5f; break;// 设置为:0x40 陀螺仪量程为:±500 dps 获取到的陀螺仪数据除以65.5 可以转化为带物理单位的数据,单位为:°/s
case 0x60: gyro_data = (float)gyro_value / 131.0f; break;// 设置为:0x60 陀螺仪量程为:±250 dps 获取到的陀螺仪数据除以131 可以转化为带物理单位的数据,单位为:°/s
case 0x80: gyro_data = (float)gyro_value / 262.0f; break;// 设置为:0x80 陀螺仪量程为:±125 dps 获取到的陀螺仪数据除以262 可以转化为带物理单位的数据,单位为:°/s
case 0xA0: gyro_data = (float)gyro_value / 524.3f; break;// 设置为:0xA0 陀螺仪量程为:±62.5 dps 获取到的陀螺仪数据除以524.3 可以转化为带物理单位的数据,单位为:°/s
case 0xC0: gyro_data = (float)gyro_value / 1048.6f; break;// 设置为:0xC0 陀螺仪量程为:±31.25 dps 获取到的陀螺仪数据除以1048.6 可以转化为带物理单位的数据,单位为:°/s
case 0xE0: gyro_data = (float)gyro_value / 2097.2f; break;// 设置为:0xE0 陀螺仪量程为:±15.625dps 获取到的陀螺仪数据除以2097.2 可以转化为带物理单位的数据,单位为:°/s
default: break;
}
return gyro_data;
}
5. 读取温度计数值及物理单位转化
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 ICM42605 加速度计数据
// 参数说明 void
// 返回参数 void
// 使用示例 icm42605_get_temp(); // 执行该函数后,直接查看对应的变量即可
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void icm42605_get_temp(void)
{
uint8 dat[6];
icm42605_read_registers(ICM42605_TEMP_DATA1, dat, 2);
icm42605_temp = (int16)(((uint16)dat[0] << 8 | dat[1]));
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 将 ICM42605 温度传感器数据转换为实际物理数据
// 参数说明 temp_value 任意轴的加速度计数据
// 返回参数 void
// 使用示例 temp_data = icm42605_temp_transition(icm42605_temp); // 单位为 g(m/s^2)
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
float icm42605_temp_transition (int16 temp_value)
{
float temp_data = 0;
temp_data = (float)temp_value / 132.48 + 25; // 除以132.48,再加25,单位为 °C
return temp_data;
}
5. icm42605_read_registers()读取寄存器的实现
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 ICM42605 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 icm42605_write_register(ICM42605_PWR_MGMT_1, 0x80);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void icm42605_write_register(uint8 reg, uint8 data)
{
ICM42605_CS(0);
spi_write_8bit_register(ICM42605_SPI, reg | ICM42605_SPI_W, data);
ICM42605_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 SPI 接口向传感器的寄存器写 8bit 数据
// 参数说明 spi_n SPI 模块号 参照 zf_driver_spi.h 内 spi_index_enum 枚举体定义
// 参数说明 register_name 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 spi_write_8bit_register(SPI_1, 0x11, 0x01);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void spi_write_8bit_register (spi_index_enum spi_n, const uint8 register_name, const uint8 data)
{
#ifdef SPI_SPEED_PRIORITY
spi_write(spi_n, ®ister_name, NULL, 1, 0);
spi_write(spi_n, &data, NULL, 1, 1);
#else
spi_8bit_data_handler(spi_n, register_name);
spi_8bit_data_handler(spi_n, data);
#endif
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 ICM42605 读数据
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 icm42605_read_registers(ICM42605_ACCEL_XOUT_H, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void icm42605_read_registers(uint8 reg, uint8 *data, uint32 len)
{
ICM42605_CS(0);
spi_read_8bit_registers(ICM42605_SPI, reg | ICM42605_SPI_R, data, len);
ICM42605_CS(1);
}
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 SPI 接口从传感器的寄存器读 8bit 数据
// 参数说明 spi_n SPI 模块号 参照 zf_driver_spi.h 内 spi_index_enum 枚举体定义
// 参数说明 register_name 寄存器地址
// 返回参数 uint8 数据
// 使用示例 spi_read_8bit_register(SPI_1, 0x11);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
uint8 spi_read_8bit_register (spi_index_enum spi_n, const uint8 register_name)
{
#ifdef SPI_SPEED_PRIORITY
uint8 data = 0;
spi_write(spi_n, (const uint8 *)®ister_name, NULL, 1, 1);
spi_write(spi_n, NULL, (uint8 *)&data, 1, 1);
return data;
#else
spi_8bit_data_handler(spi_n, register_name);
return spi_8bit_data_handler(spi_n, 0);
#endif
}
如需移植只要修改读写寄存器及GPIO初始化的相关函数即可