|
电子元器件产品技术的更新迭代速度快,惯性测量单元也是如此。TDK公司作为国际上领先的惯性测量单元生产设计提供商,发布了多款产品,从之前MPU6050、ICM-20602,到ICM-42688、ICM-45686等,性能越来越强。ICM-45686作为TDK InvenSense公司最新推出的一款超高性能六轴MEMS运动传感器,采用独特的BalancedGyro技术,可实现极佳的抗震和温度稳定性性能,并提供超低功耗。该传感器包括片上嵌入式APEX运动功能:计步器、倾斜和轻击检测、自由落体检测、超低功耗运动唤醒和运动检测。
在本篇帖子中,我们将主要介绍使用NUCLEO-G070开发板通过SPI方式读取YBX-ICM45686模块的数据,实现读取加速度计和陀螺仪的原始数据。
所需的组件 ● NUCLEO-G070开发板 ● YBX-ICM45686六轴惯性测量单元模块(淘宝链接) ● 连接跳线 ● USB线缆 ● STM32CubeMX工具 ● 友善串口调试助手
YBX-ICM45686六轴惯性测量单元模块 YBX-ICM45686模块是一板科技推出的模块扩展板,采用TDK InvenSense 6轴MEMS运动传感器ICM-45686。该运动传感器是一款高性能双接口 (UI + AUX) 六轴MEMS运动跟踪器件。ICM-45686支持此IMU类中最低的陀螺仪和加速度传感器噪声,并且具有最高的温度、冲击或弯曲引起的偏移稳定性,以及对带外振动引起的噪声的免疫力。其他业界领先的功能包括用于手势识别、活动分类和计步器的片上APEX运动处理引擎,以及可编程数字滤波器和嵌入式温度传感器。
该模块加速度传感器同时支持SPI和I2C接口方式,板载电源LDO,支持3.3V和5V电源输入。
硬件连接 YBX-ICM45686传感器模块连接到NUCLEO-G070RB的SPI1接口,对应的引脚分别是PA5(SCK)、PA6(MISO)和PA7(MOSI),片选引脚CSB连接到PB0。模块的VCC连接到+5V引脚,GND引脚连接到NUCLEO-G070RB的任意GND引脚。
使用跳线按照以上示例图连接模块和开发板。
STM32CubeMX工具配置 STM32CubeMX工具是ST提供的一个免费的软件配置工具,它提供了一些工程模板,可以快速创建基于MCU、开发板以及示例程序的工程。使用该工具,我们可以快速新建一个基于NUCLEO-G070开发板的工程。
首先打开STM32CubeMX工具,点击ACCESS TO BOARD SELECTOR,在弹出的界面中找到NUCLEO-G070RB开发板,然后点击右上角的Start Project。
在Pinout布局中,已经初始化好RCC、Debug、UART2、LED等外设。 我们使用SPI1外设连接传感器模块,设置SPI1的模式为Full Duplex Master,将A5、PA6和PA7分别设为SPI1_SCK、SPI1_MISO和SPI1_MOSI。然后将PB0定义为CS输出。然后根据手册中的SPI时序图,设置SPI通讯的参数。 注意,SPI的时钟频率不能超过12MHz。
最后,生成基于Keil MDK的工程文件。
驱动文件 TDK提供了基于ICM-45686的驱动文件和示例代码,可以在Github进行下载:motion.mcu.icm45686.driver。也可以在TDK的官网页面下载。
代码 TDK的驱动文件中包含多个示例代码,我们选择基于basic_read_registers代码进行移植,该代码采用API函数直接读取寄存器的方式采集数据,中断标志位置位时读取数据。以下是代码: - printf("\nICM45686 SPI Test\n");
- printf("Bolgen Studio\n");
- /* Initialize MCU hardware */
- rc |= setup_mcu();
- SI_CHECK_RC(rc);
- INV_MSG(INV_MSG_LEVEL_INFO, "###");
- INV_MSG(INV_MSG_LEVEL_INFO, "### Example Read registers (using basic API)");
- INV_MSG(INV_MSG_LEVEL_INFO, "###");
- /* Reset commands interface states */
- print_si = 1;
- print_lsb = 0;
- accel_en = 1;
- gyro_en = 1;
- use_ln = 1;
- rc |= setup_imu();
- SI_CHECK_RC(rc);
- /* Reset timestamp and interrupt flag */
- int1_flag = 0;
- int1_timestamp = 0;
- uint64_t timestamp;
- inv_imu_sensor_data_t d;
- float accel_g[3];
- float gyro_dps[3];
- float temp_degc;
- inv_imu_int_state_t int_state;
-
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- /* Retrieve timestamp */
- timestamp = int1_timestamp;
- /* Read interrupt status */
- rc |= inv_imu_get_int_status(&imu_dev, INV_IMU_INT1, &int_state);
- SI_CHECK_RC(rc);
- if (int_state.INV_UI_DRDY)
- {
- rc |= inv_imu_get_register_data(&imu_dev, &d);
- SI_CHECK_RC(rc);
- /*
- * Convert data to SI units
- * Accel and gyro data are coded as 16-bits signed (max_lsb = 2^(16-1) = 32768) with
- * the configured FSR (4 g and 2000 dps, see `setup_imu()` function).
- * Temperature is coded as 16-bits signed with a scale factor of 128 and an offset
- * of 25 ?.
- */
- accel_g[0] = (float)(d.accel_data[0] * 4 /* gee */) / 32768;
- accel_g[1] = (float)(d.accel_data[1] * 4 /* gee */) / 32768;
- accel_g[2] = (float)(d.accel_data[2] * 4 /* gee */) / 32768;
- gyro_dps[0] = (float)(d.gyro_data[0] * 2000 /* dps */) / 32768;
- gyro_dps[1] = (float)(d.gyro_data[1] * 2000 /* dps */) / 32768;
- gyro_dps[2] = (float)(d.gyro_data[2] * 2000 /* dps */) / 32768;
- temp_degc = (float)25 + ((float)d.temp_data / 128);
- /* Print data in SI units */
- if (print_si)
- {
- char accel_str[40];
- char gyro_str[40];
- char temp_str[20];
- if (accel_en && (discard_accel_samples == 0) &&
- (d.accel_data[0] != INVALID_VALUE_FIFO) &&
- (d.accel_data[1] != INVALID_VALUE_FIFO) &&
- (d.accel_data[2] != INVALID_VALUE_FIFO))
- snprintf(accel_str, 40, "Accel:% 8.2f % 8.2f % 8.2f g", accel_g[0],
- accel_g[1], accel_g[2]);
- else
- snprintf(accel_str, 40, "Accel: - - - ");
- if (gyro_en && (discard_gyro_samples == 0) &&
- (d.gyro_data[0] != INVALID_VALUE_FIFO) &&
- (d.gyro_data[1] != INVALID_VALUE_FIFO) &&
- (d.gyro_data[2] != INVALID_VALUE_FIFO))
- snprintf(gyro_str, 40, "Gyro:% 8.2f % 8.2f % 8.2f dps", gyro_dps[0],
- gyro_dps[1], gyro_dps[2]);
- else
- snprintf(gyro_str, 40, "Gyro: - - - ");
- snprintf(temp_str, 20, "Temp: % 4.2f degC", temp_degc);
- INV_MSG(INV_MSG_LEVEL_INFO, "SI %10llu us %s %s %s", timestamp,
- accel_str, gyro_str, temp_str);
- }
- /* Print LSB data. */
- if (print_lsb)
- {
- char accel_str[40];
- char gyro_str[40];
- char temp_str[20];
- if (accel_en && (discard_accel_samples == 0) &&
- (d.accel_data[0] != INVALID_VALUE_FIFO) &&
- (d.accel_data[1] != INVALID_VALUE_FIFO) &&
- (d.accel_data[2] != INVALID_VALUE_FIFO))
- snprintf(accel_str, 40, "Accel:% 8d % 8d % 8d", (int)d.accel_data[0],
- (int)d.accel_data[1], (int)d.accel_data[2]);
- else
- snprintf(accel_str, 40, "Accel: - - -");
- if (gyro_en && (discard_gyro_samples == 0) &&
- (d.gyro_data[0] != INVALID_VALUE_FIFO) &&
- (d.gyro_data[1] != INVALID_VALUE_FIFO) &&
- (d.gyro_data[2] != INVALID_VALUE_FIFO))
- snprintf(gyro_str, 40, "Gyro:% 8d % 8d % 8d", (int)d.gyro_data[0],
- (int)d.gyro_data[1], (int)d.gyro_data[2]);
- else
- snprintf(gyro_str, 40, "Gyro: - - -");
- snprintf(temp_str, 20, "Temp: % 6d", (int)d.temp_data);
- INV_MSG(INV_MSG_LEVEL_INFO, "LSB %10llu us %s %s %s", timestamp,
- accel_str, gyro_str, temp_str);
- }
- if (accel_en && discard_accel_samples)
- discard_accel_samples--;
- if (gyro_en && discard_gyro_samples)
- discard_gyro_samples--;
- }
- rc |= get_uart_command();
- si_sleep_ms(1000);
- /* USER CODE END 3 */
- }
复制代码
输出结果 使用USB线缆给NUCLEO-G070开发板上电,然后将代码上传至开发板,打开友善串口调试助手,选择正确的端口号,设置波特率115200,在串口中应该能显示数据:
以上就是NUCLEO-G070开发板读取YBX-ICM45686模块的全部内容,如果有任何疑问,请随时在本帖下面回复。
|