RT1064读取ICM42605加速度计、陀螺仪、温度值

本文档展示了ICM42605传感器的驱动代码,包括头文件中的寄存器定义,初始化函数,以及读取加速度计和陀螺仪数据的函数。代码支持硬件SPI和软件IIC两种通信方式,并提供了物理单位转换的辅助函数。初始化过程中设置了传感器的工作模式、量程和数据速率。
摘要由CSDN通过智能技术生成

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, &register_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 *)&register_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初始化的相关函数即可

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烦恼分解菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值