ICM20602六轴传感器

  • ICM20602 通过IIC协议与MCU通信
  • ICM20602 初始化配置
  • ICM20602 相关配置函数
  • ICM20602 内部寄存器
  • 注意事项
    • (一)ICM20602 从地址
    • (二)ICM20602 器件id(0x12)

ICM20602 通过IIC协议与MCU通信

ICM-20602 是 日本TDKTDK公司生产的六轴传感器。
ICM-20602的DataSheet可在其官网下载: ICM20602 或者参考链接: 芯片翻译之ICM20602.

IIC软件模拟时序,请参考链接: IIC软件模拟时序-stm32F系列平台通用
下面为MCU通过IIC与ICM20602通信的读写函数

/*-------------- 读写从机的内部寄存器reg,读写1个字节数据 ----------------*/
/*** @brief  IIC写一个字节* @param  reg  要写的寄存器地址*         buf  写入到的数据存储区* @retval 1:失败*         0:成功*/
u8 ICM_Write_Byte(u8 reg, u8 data)
{IIC_Start();IIC_Send_Byte((ICM20602_ADDR << 1) | 0); //发送器件地址+写命令if (IIC_Wait_Ack()) //等待应答{IIC_Stop();return 1;}IIC_Send_Byte(reg); //写寄存器地址IIC_Wait_Ack(); //等待应答IIC_Send_Byte(data); //发送数据if (IIC_Wait_Ack()) //等待ACK{IIC_Stop();return 1;}IIC_Stop();return 0;
}/*** @brief  IIC读一个字节* @param  reg  要写的寄存器地址* @retval 读到的数据*/
u8 ICM_Read_Byte(u8 reg)
{u8 res;IIC_Start();IIC_Send_Byte((ICM20602_ADDR << 1) | 0); //发送器件地址+写命令IIC_Wait_Ack(); //等待应答IIC_Send_Byte(reg); //写寄存器地址IIC_Wait_Ack(); //等待应答IIC_Start();IIC_Send_Byte((ICM20602_ADDR << 1) | 1); //发送器件地址+读命令IIC_Wait_Ack(); //等待应答res = IIC_Read_Byte(0); //读取数据,发送nACKIIC_Stop(); //产生一个停止条件return res;
}/*----------------------- ICM20602 连续读写数据 ----------------------*/
/*** @brief  IIC发送数据* @param  * @retval 返回从机有无应答*         1:有应答*         0:无应答*/
u8 ICM_Write_Len(u8 addr, u8 reg, u8* buf, u8 len)
{u8 i;IIC_Start();IIC_Send_Byte((addr << 1) | 0); //发送器件地址+写命令if (IIC_Wait_Ack()) //等待应答{IIC_Stop();return 1;}IIC_Send_Byte(reg); //写寄存器地址IIC_Wait_Ack(); //等待应答for (i = 0; i < len; i++) {IIC_Send_Byte(buf[i]); //发送数据if (IIC_Wait_Ack()) //等待ACK{IIC_Stop();return 1;}}IIC_Stop();return 0;
}/*** @brief  IIC读取数据* @param  addr 器件地址*         reg  要读取的寄存器地址*         len  要读取的长度*         buf  读取到的数据存储区* @retval 1:失败*         0:成功*/
u8 ICM_Read_Len(u8 addr, u8 reg, u8* buf, u8 len)
{IIC_Start();IIC_Send_Byte((addr << 1) | 0); //发送器件地址+写命令if (IIC_Wait_Ack()) //等待应答{IIC_Stop();return 1;}IIC_Send_Byte(reg); //写寄存器地址IIC_Wait_Ack(); //等待应答IIC_Start();IIC_Send_Byte((addr << 1) | 1); //发送器件地址+读命令IIC_Wait_Ack(); //等待应答while (len) {if (len == 1)*buf = IIC_Read_Byte(0); //读数据,发送nACKelse*buf = IIC_Read_Byte(1); //读数据,发送ACKlen--;buf++;}IIC_Stop(); //产生一个停止条件return 0;
}

ICM20602 初始化配置

在初始化配置IMU传感器时,一定要先配置成功能正常读取IMU传感器的内部标识 id

/* ------------- ICM20602 六轴传感器初始化 ---------------- */
u8 ICM20602_sensor_init(void)
{u8 ICM_id;/* (1)IIC初始化 */IIC_Dev_Init();#if 1  // 此部分为ICM20602的INT引脚产生中断的相关配置
/*- ICM20602引脚INT产生中断时,MCU引脚PE0配置外部中断和NVIC优先级 -*/GPIO_InitTypeDef GPIO_InitStructure;/* 使能GPIOE、AFIO 端口时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);/* 配置ICM20602-PE0中断线 */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_Init(GPIOE, &GPIO_InitStructure);/* 配置中断线和 GPIO-PE0 映射关系 */GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0);/* 配置外部中断EXTI */myEXTI_Config(EXTI_Line0, EXTI_Mode_Interrupt, EXTI_Trigger_Falling);/* 配置NVIC中断优先级并使能中断 */myNVIC_Config(EXTI0_IRQn, 0, 0); // 外部中断线0#endif/* (2)复位ICM20602 */ICM_Write_Byte(ICM20602_PWR_MGMT1_REG, 0x80);timer_delay(100); // 利用定时器配置延迟100msICM_Write_Byte(ICM20602_PWR_MGMT1_REG, 0x00); //唤醒ICM20602/* 复位重置传感器各个通道的寄存器 */ICM_Write_Byte(ICM20602_USER_CTRL, 0x01); timer_delay(100);ICM_Write_Byte(ICM20602_USER_CTRL, 0x00);/* (3)配置陀螺仪满量程范围:-2g ~ +2g;加速度计满量程范围:-2000dps ~ +2000dps */ICM_Set_Gyro_Fsr(0x3);ICM_Set_Accel_Fsr(0);/* (4)设置采样频率50HZ */ICM_Set_Rate(50);/* (5)禁止中断,关闭硬件 */ICM_Write_Byte(ICM20602_INT_ENABLE_REG, 0x00);  // 关闭所有中断ICM_Write_Byte(ICM20602_FIFO_EN, 0x00);         // 关闭陀螺仪和加速度计的FIFO数据缓冲区ICM_Write_Byte(ICM20602_INT_PIN_CFG, 0x80);     // 设置INT引脚为低电平有效,开漏输出/* (6)判断器件ID = 0x12 */ICM_id = ICM_Read_Byte(ICM20602_WHO_AM_I);printf("ICM20602_ID = 0x%x .......\r\n", ICM_id);if (ICM_id == 0x12) {/* 设置时钟源 */ICM_Write_Byte(ICM20602_PWR_MGMT1_REG, 0x01);/* 设置accelerate阈值 */ICM_Write_Byte(ICM20602_LACCEL_WOM_X_THR, 0x7F);ICM_Write_Byte(ICM20602_LACCEL_WOM_Y_THR, 0x7F);ICM_Write_Byte(ICM20602_LACCEL_WOM_Z_THR, 0x7F);/* 开启加速度计的阈值中断 */ICM_Write_Byte(ICM20602_ACCEL_INTEL_CTRL, 0x80);timer_delay(1);/* 使能中断 */ICM_Write_Byte(ICM20602_INT_ENABLE_REG, 0xE0);timer_delay(1);/* 开启加速度与陀螺仪都工作 */ICM_Write_Byte(ICM20602_PWR_MGMT2_REG, 0x00);timer_delay(1);printf("ICM20602 IMU initalize success ............\r\n");} else {printf("ICM20602 initalize fail ...........\r\n");return 1;}return 0;
}/*---------- 设置运动检测(WAKE-ON MOTION) accelerate阈值 ----------*/
int Set_Accl_Thresh(u8 threshold)
{u8 accl_val;/* Threshold按十六进制传参不能超过值:(十进制0D)100 = 0x64 */if(threshold > 100){return 1;}u16 val_1= threshold * 0xFF;u16 val_2 = (u8)(val_1 / 100);accl_val = (u8)val_2;_debug(SYS_INFO, "threshold = %d%%, val_1 = 0x%x, val_2 = 0x%x, set accl_val = 0x%x ...\n", \threshold, val_1, val_2, accl_val);ICM_Write_Byte(ICM20602_LACCEL_WOM_X_THR, accl_val);ICM_Write_Byte(ICM20602_LACCEL_WOM_Y_THR, accl_val);ICM_Write_Byte(ICM20602_LACCEL_WOM_Z_THR, accl_val);  return 0;
}/* 外部中断配置EXTI寄存器 */
void myEXTI_Config(u32 myEXTI_Line, EXTIMode_TypeDef myEXTI_Mode, EXTITrigger_TypeDef myEXTI_Trigger)
{EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = myEXTI_Line;EXTI_InitStructure.EXTI_Mode = myEXTI_Mode;EXTI_InitStructure.EXTI_Trigger = myEXTI_Trigger;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);
}/* NVIC中断配置函数 */
void myNVIC_Config(u8 myNVIC_IRQChannel, u8 PreEmptionPriority, u8 SubPriority)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = myNVIC_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreEmptionPriority;NVIC_InitStructure.NVIC_IRQChannelSubPriority = SubPriority;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}/* EXTI0 中断处理函数 */
void EXTI0_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line0)) {/* ICM20602六轴传感器INT引脚 接MCU的PE0引脚 */if (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_0) == Bit_RESET) {ICM20602_Get_Data();}EXTI_ClearITPendingBit(EXTI_Line0);}
}

ICM20602 相关配置函数

此部分参考ICM20602的数据手册,

/*-------------------------- 设置满量程范围 ---------------------*/
/* 设置GYRO陀螺仪的满量程范围 */
u8 ICM_Set_Gyro_Fsr(u8 fsr)
{return ICM_Write_Byte(ICM20602_GYRO_CONFIG_REG, fsr << 3);
}/* 设置ACCEL加速度计的满量程范围 */
u8 ICM_Set_Accel_Fsr(u8 fsr)
{return ICM_Write_Byte(ICM20602_ACCEL_CONFIG1_REG, fsr << 3);
}/*------------------------- 设置采样频率 -------------------------*/
/*** 设置ICM20602的采样频率(假定Fs=1KHz)* INTERNAL_SAMPLE_RATE = 1 kHz* SAMPLE_RATE = INTERNAL_SAMPLE_RATE / (1 + SMPLRT_DIV);* rate:4 ~ 1000(Hz)* 返回值:0,设置成功;其他,设置失败*/
u8 ICM_Set_Rate(u16 rate)
{u8 div;if (rate > 1000) {rate = 1000;} else if (rate < 4) {rate = 4;}/* 设置预分频值DIV */div = 1000 / rate - 1;ICM_Write_Byte(ICM20602_SMPLRT_DIV, div);/* 配置低通滤波器为采样率的1/2 */return ICM_Set_DLPF(rate / 2);
}/*** 设置ICM20602的数字低通滤波器(假定Fs=1KHz)* 返回值:0,设置成功;其他,设置失败*/
u8 ICM_Set_DLPF(u16 dlpf)
{u8 data;if (dlpf >= 250) {data = 0;} else if (dlpf >= 176) {data = 1;} else if (dlpf >= 92) {data = 2;} else if (dlpf >= 41) {data = 3;} else if (dlpf >= 20) {data = 4;} else if (dlpf >= 10) {data = 5;} else {data = 6;}return ICM_Write_Byte(ICM20602_CONFIG_REG, data);
}/* ---------------------- 读取传感器采集到的数据 -------------------------- */
/*** 读取陀螺仪值(原始值)* gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)* 返回值:0,成功; 其他,错误代码*/
u8 ICM_Get_Gyroscope(short* gx, short* gy, short* gz)
{u8 buf[6], res;res = ICM_Read_Len(ICM20602_ADDR, ICM20602_GYRO_XOUT_H, buf, 6);if (res == 0) {*gx = ((u16)buf[0] << 8) | buf[1];*gy = ((u16)buf[2] << 8) | buf[3];*gz = ((u16)buf[4] << 8) | buf[5];}return res;
}/*** 读取加速度计值(原始值)* ax,ay,az:加速度计x,y,z轴的原始读数(带符号)* 返回值:0,成功; 其他,错误代码*/
u8 ICM_Get_Accelerometer(short* ax, short* ay, short* az)
{u8 buf[6], res;res = ICM_Read_Len(ICM20602_ADDR, ICM20602_ACCEL_XOUT_H, buf, 6);if (res == 0) {*ax = ((u16)buf[0] << 8) | buf[1];*ay = ((u16)buf[2] << 8) | buf[3];*az = ((u16)buf[4] << 8) | buf[5];}return res;
}/*** 读取温度值(原始值)* 返回值:温度值(扩大了100倍)*/
short ICM_Get_Temperature(void)
{u8 buf[2];short raw;float temp;ICM_Read_Len(ICM20602_ADDR, ICM20602_TEMP_OUT_H, buf, 2);raw = ((u16)buf[0] << 8) | buf[1];temp = 36.53 + ((double)raw) / 340;return temp * 100;
}

ICM20602 内部寄存器

icm20602_iic.h 头文件

/* ------------------ Register map for ICM20602 ---------------------- */#define ICM20602_SELF_TEST_X_ACCEL 0x0D     // X轴加速度计自检寄存器
#define ICM20602_SELF_TEST_Y_ACCEL 0x0E     // Y轴加速度计自检寄存器
#define ICM20602_SELF_TEST_Z_ACCEL 0x0F     // Z轴加速度计自检寄存器
#define ICM20602_SMPLRT_DIV 0x19            // 采样频率分频器
#define ICM20602_CONFIG_REG 0x1A            // 配置:fifo MODE, Enables the FSYNC and DLPF低通滤波器
#define ICM20602_GYRO_CONFIG_REG 0x1B       // (4:3 bit)gyroscope configuration
#define ICM20602_ACCEL_CONFIG1_REG 0x1C     // accelerometer configuration
#define ICM20602_ACCEL_CONFIG2_REG 0x1D     // accelerometer configuration
#define ICM20602_LP_MODE_CFG 0x1E           // gyroscope low-power mode or 6-axis low-power mode
#define ICM20602_LACCEL_WOM_X_THR 0x20      // 加速度计X轴阈值
#define ICM20602_LACCEL_WOM_Y_THR 0x21      // 加速度计Y轴阈值
#define ICM20602_LACCEL_WOM_Z_THR 0x22      // 加速度计Z轴阈值
#define ICM20602_FIFO_EN 0x23               // GYRO/ACCEL _FIFO_EN
#define ICM20602_FSYNC_INT 0x36
#define ICM20602_INT_PIN_CFG 0x37           // 中断引脚配置
#define ICM20602_INT_ENABLE_REG 0x38        // interrupt enable
#define ICM20602_INT_STATUS 0x3A            // INTERRUPT STATUS
#define ICM20602_ACCEL_XOUT_H 0x3B          // accelerometer measurements
#define ICM20602_ACCEL_XOUT_L 0x3C
#define ICM20602_ACCEL_YOUT_H 0x3D
#define ICM20602_ACCEL_YOUT_L 0x3E
#define ICM20602_ACCEL_ZOUT_H 0x3F
#define ICM20602_ACCEL_ZOUT_L 0x40
#define ICM20602_TEMP_OUT_H 0x41            // TEMPERATURE MEASUREMENT,Temperature = 36.53 + regval/340
#define ICM20602_TEMP_OUT_L 0x42
#define ICM20602_GYRO_XOUT_H 0x43           // gyroscope measurements
#define ICM20602_GYRO_XOUT_L 0x44
#define ICM20602_GYRO_YOUT_H 0x45
#define ICM20602_GYRO_YOUT_L 0x46
#define ICM20602_GYRO_ZOUT_H 0x47
#define ICM20602_GYRO_ZOUT_L 0x48
#define ICM20602_SELF_TEST_X_GYRO 0x50
#define ICM20602_SELF_TEST_Y_GYRO 0x51
#define ICM20602_SELF_TEST_Z_GYRO 0x52
#define ICM20602_SIGNAL_PATH_RESET 0x68     // ACCEL_RST,TEMP_RST
#define ICM20602_ACCEL_INTEL_CTRL 0x69
#define ICM20602_USER_CTRL 0x6A             // FIFO_EN,FIFO_RST,SIG_COND_RST
#define ICM20602_PWR_MGMT1_REG 0x6B         // DEVICE_RESET,SLEEP,CYCLE,GYRO_STANDBY,TEMP_DIS,CLKSEL
#define ICM20602_PWR_MGMT2_REG 0x6C         // STBY_XA - STBY_ZG
#define ICM20602_I2C_IF 0x70                //1 – Disable I2C Slave module and put the serial interface in SPI mode only.
#define ICM20602_FIFO_COUNTH 0x72
#define ICM20602_FIFO_R_W 0x74              //FIFO READ WRITE
#define ICM20602_WHO_AM_I 0x75              //RO, default value ID = 0x12;
#define ICM20602_CONFIG 0x80
#define ICM20602_ADDR 0x69                  // Slave address, ad0 set 0/*------------------------- 初始化ICM20602 -----------------------------*/
u8 ICM20602_sensor_init(void);
int Set_Accl_Thresh(u8 threshold);/*------------------------ 设置加速度计和陀螺仪 -------------------------*/
u8 ICM_Set_Gyro_Fsr(u8 fsr);
u8 ICM_Set_Accel_Fsr(u8 fsr);
u8 ICM_Set_DLPF(u16 lpf);
u8 ICM_Set_Rate(u16 rate);/*---------------------- 获取 加速度计、陀螺仪和温度 数据 ----------------*/
short ICM_Get_Temperature(void);
u8 ICM_Get_Gyroscope(short* gx, short* gy, short* gz);
u8 ICM_Get_Accelerometer(short* ax, short* ay, short* az);

注意事项

(一)ICM20602 从地址

从下面的数据手册节选可以看出:SA0引脚决定了从机地址的值,从下面的我的ICM20602原理图可以看出,我的SA0引脚接VCC,故始终为高电平,因此:ICM20602_ADDR = 0x69;又CS片选始终也为高电平,即为IIC通信模式。具体的使用要看原理图,硬件工程师将SA0和CS引脚是怎么接的,是接地还是接的VCC。

(二)ICM20602 器件id(0x12)

内部寄存器:WHO_AM_I ,不同的芯片的地址有可能不同,具体的还详细请看传感器的数据手册。

ICM20602六轴传感器-IIC通信模式相关推荐

  1. 【开源教程13】疯壳·开源编队无人机-SPI(六轴传感器数据获取)

    COCOFLY教程 --疯壳·无人机·系列 SPI(六轴传感器数据获取)          图1               一.ICM20602 简介     六轴传感器在当今智能穿戴和定位导航产品 ...

  2. 【飞控开发基础教程6】疯壳·开源编队无人机-SPI(六轴传感器数据获取)

    COCOFLY教程 --疯壳·无人机·系列 SPI(六轴传感器数据获取)          图1               一.ICM20602 简介     六轴传感器在当今智能穿戴和定位导航产品 ...

  3. 【STM32Cube】学习笔记(三):六轴传感器

    文章目录 摘要 一.简介 1.I2C原理 2.MPU6050介绍 3.MPU6050寄存器介绍 4.DMP使用 二.硬件电路设计 三.软件设计 1.CubeMX配置 2.CubeIDE代码 3.结果显 ...

  4. Micro Python———MPU6050六轴传感器

    目录 1.什么是MPU6050? MPU6050介绍: MPU6050寄存器介绍: 2.例程 1.平台 2.目的 3.讲解 1.查阅原理图 2.流程分析 3.代码讲解 3.结果 1.什么是MPU605 ...

  5. 六轴传感器基础知识学习:MPU6050特性,四元数,姿态解算,卡尔曼滤波

    实际上,只要说到多少轴的传感器一般是就是指加速度传感器(即加速计).角速度传感器(即陀螺仪).磁感应传感器(即电子罗盘).这三类传感器测量的数据在空间坐标系中都可以被分解为X,Y,Z三个方向轴的力,因 ...

  6. C语言 | 基于MPU605(六轴传感器)的I2C实现LCD1602显示(代码类)

    博主github:https://github.com/MichaelBeechan 博主CSDN:https://blog.csdn.net/u011344545 基于MPU605(六轴传感器)的I ...

  7. LSM6DS3(六轴传感器)STM32驱动及6D功能实现

    刚使用了STM32测试了LSM6DS3该六轴传感器,顺便也测试了其6D方向检测功能,效果是能满足对6个面方向的识别需求. 该六轴传感器支持I2C/SPI通信.在读取该六轴传感器寄存器时,采用I2C通信 ...

  8. android六轴传感器,6轴传感器、IP67防水:AMAZFIT米动智芯2 上架有品

    6轴传感器.IP67防水:AMAZFIT米动智芯2 上架有品49元 2018-07-09 10:23:57 29点赞 35收藏 39评论 直达链接 作为智能跑鞋的核心,智能运动芯片通常会随着运动鞋一起 ...

  9. keil4怎么移植其他人的程序_【调试笔记】韦东山:在100ask_imx6ull上移植使用六轴传感器ICM20608...

    之前发了LCD调试笔记,大家很感兴趣,所以这次再来一篇:六轴传感器ICM20608驱动移植笔记,大家还需要什么移植笔记?可以留言.我们尽量满足. 1.1 移植思路 先找到驱动:也许内核里已经有,也许需 ...

最新文章

  1. 最新调查,48%的美国人表示不会乘坐自动驾驶汽车
  2. Code review制度推不下去,CTO说我是废物,让我学习“热炉法则”
  3. figure文本框乱码 matlab_Matlab给系统自动生成的窗体Figure1改名称
  4. 干货:产品经理怎么做才能在需求评审中少挨打?
  5. 页面图片延时加载(附实例下载)
  6. MSTP:多生成树实例——应用案列及配置命令(实验)
  7. k8s上安装并初始化Helm,helm基础使用教程
  8. 【Python】Tanimoto相似度算法实现
  9. 利用after和before伪元素在文字两边写横线
  10. 深度WindowsXp错误的打了SP3补丁之后,无法进入系统
  11. 权限控制-@Secured注解
  12. 小程序之botton默认带边框的问题
  13. windows server2008 部署项目环境总结
  14. 算法工程师0——算法工程师学习进阶路线
  15. 华为u8825d手机root和google play安装有教程和相关文件
  16. 关于mac下搭建php、apache、mysql环境
  17. 句子深度假说——冯志伟
  18. 亚马逊云科技的Graviton3为什么只有64核,官方回应来了!
  19. QQ聊天功能在局域网中的实现
  20. 面向spi和面向api_面向API的设计的重要性

热门文章

  1. 基于xilinx fpga的ofdm通信系统基带设计_基于嵌入式Wi-Fi处理器的无线系统设计...
  2. matlab菜鸡学习日志--------使用matlab解析NMEA-0183 协议获取经纬度以及航向角
  3. 在js中对数值进行取整、四舍五入等方法汇总
  4. 将页面中的指定 div 下载为图片
  5. 倍福触摸屏维修倍福工控机维修CP3916-0010详解
  6. C#多线程工业源码 替代传统plc搭载的触摸屏 工控屏幕一体机直接和plc通信
  7. python 给QQ好友发信息
  8. 一个汽车软件测试工程师的三年工作总结
  9. linux监控ftp stp日志,一篇文章让你了解STP、SFTP、UTP、FTP、ASTP分别是什么网线?...
  10. class 和 def