旧乡故客
发表于: 昨天 10:41 | 显示全部楼层

近年来,智能可穿戴设备离普通人的生活越来越近,智能手环、智能手表、智能耳机等一系列的产品逐渐走进了人们的生活中。这些设备通过数据交互、云端交互等方式提供了强大的功能,对我们的生活、感知带来很大的转变。可穿戴设备中的MEMS传感器能够精确捕捉数据,并进行实时更新反馈。惯性测量单元作为一种MEMS传感器,可以用来测量方位、运动或者手势。


博世公司推出的低功耗智能传感器BMI323可以用于穿戴设备,该传感器基于博世的MEMS工艺技术,而且大大提升了加速度计的偏移和灵敏度性能。在本篇文章中,我们将介绍如何基于NUCLEO-G070开发板通过SPI接口读取BMI323的加速度计和陀螺仪数据。


所需的组件

●  NUCLEO-G070RB开发板

●  YBX-BMI323惯性测量单元传感器模块(淘宝链接

●  连接跳线

●  USB线缆

●  友善串口调试助手


YBX-BMI323传感器模块

YBX-BMI323模块采用博世传感器的超低功耗智能惯性测量单元BMI323。该IMU针对可穿戴设备进行了优化,提供精确的加速度、角速率测量和智能片上运动触发中断功能,同时该传感器集成了16位三轴陀螺仪和16位三轴加速度计。该模块支持SPI和I2C接口进行系统集成,可以快速实现与Arduino和STM32等控制器直接相连。该模块板载一颗电源芯片,支持3.3-5V供电。


BMI323包含直观的手势、情景和活动识别功能,并集成了针对腕戴式设备专门进行优化的即插即用计步器。该IMU也非常适合其他类型的可穿戴设备,如耳戴式设备、智能服装、智能鞋、智能眼镜和脚踝带。


Bosch的独特静止组件重新调整 (CRT) 功能可提供内置陀螺仪自校准功能,无需旋转激励,从而在测试和制造过程中为OEM节省宝贵的时间和成本。BMI323的嵌入式即插即用功能有助于缩短产品上市时间。

YBX-BMI323惯性测量单元模块.jpg


主要特性

●  采用Bosch超低功耗智能惯性测量单元BMI323

    ●  16位数字三轴加速度计

    ●  16位数字三轴陀螺仪

    ●  电流消耗:790µA(典型值)

    ●  灵敏度误差:± 0.4%

    ●  通过静止CRT功能实现自校准陀螺仪:

    ●  输出数据速率:12.5Hz至6.4kHz

●  SPI和I2C接口

●  2个独立的可编程I/O引脚,用于中断和同步事件

●  板载一颗高精度DC-DC芯片

●  LED电源指示灯

●  支持Arduino和STM32等微控制器

●  外形尺寸:24mm x 24mm x 5mm


硬件连接

YBX-BMI323模块支持SPI和I2C连接,在本文中,我们将使用四线SPI方式进行连接。首先,将YBX-BMI323模块连接到NUCLEO-G070RB开发板的SPI1接口,对应的引脚分别是PA5(SCK)、PA6(MISO)和PA7(MOSI),片选引脚CSB连接到PB0。YBX-BMI323模块的VCC连接到3V3引脚,GND引脚连接到NUCLEO-G070RB的任意GND引脚。

YBX-BMI323模块通过SPI接口与STM32 Nucleo的硬件连接.jpg


驱动文件

Bosch博世传感器官方提供了基于BMI323的驱动文件BMI323_SensorAPI,该源码可以在GitHub进行下载。下载地址:BMI323_SensorAPI


代码

首先我们使用STM32CubeMX工具生成工程文件,根据硬件连接方式选择引脚的功能,然后启用SPI1通讯。SPI1选择全双工主机模式(Full-Duplex Master),硬件NSS信号选择Disable。在参数设置中,数据位大小选择8位,MSB优先。选择合适的分频系数。在无法进行通讯的情况下,可以适当降低SPI1外设的频率。


生成KEIL工程后,接下来我们需要将BOSCH官方提供的BMI323_SensorAPI驱动集成到工程里面。


首先,将下载的整个驱动文件复制到工程所在的目录,然后将bmi3.cbmi323.ccommon.c添加到工程中。在common.c中重载以下两个函数:bmi3_spi_read和bmi3_spi_write。


在主函数main中,首先初始化BMI323,然后对加速度计和陀螺仪的参数进行配置。在while循环中,读取寄存器的数据,并打印输出到串口。

  1. printf("\nBMI323 SPI Test\n");
  2.   printf("Bolgen Studio\n");

  3.   /* Sensor initialization configuration. */
  4.   struct bmi3_dev dev = { 0 };

  5.   /* Status of API are returned to this variable. */
  6.   int8_t rslt;

  7.   /* Variable to define limit to print accel data. */
  8.   uint16_t limit = 300;

  9.   /* Create an instance of sensor data structure. */
  10.   struct bmi3_sensor_data sensor_data = { 0 };

  11.   /* Initialize the interrupt status of accel. */
  12.   uint16_t int_status = 0;

  13.   uint8_t indx = 0;
  14.   float x = 0, y = 0, z = 0;

  15.   /* Structure to define accelerometer configuration. */
  16.   struct bmi3_sens_config config = { 0 };

  17.   /* Select accel sensor. */
  18.   sensor_data.type = BMI323_ACCEL;

  19.   /* Function to select interface between SPI and I2C, according to that the device structure gets updated.
  20.    * Interface reference is given as a parameter
  21.    * For I2C : BMI3_I2C_INTF
  22.    * For SPI : BMI3_SPI_INTF
  23.    */
  24.   rslt = bmi3_interface_init(&dev, BMI3_SPI_INTF);
  25.   bmi3_error_codes_print_result("bmi3_interface_init", rslt);

  26.         while (1)
  27.   {
  28.                 /* Initialize bmi323. */
  29.                 rslt = bmi323_init(&dev);
  30.                 bmi3_error_codes_print_result("bmi323_init", rslt);

  31.                 if (rslt == BMI323_OK) break;
  32.                
  33.                 HAL_DelayMs(2000);
  34.         }

  35.   /* Accel configuration settings. */
  36.   rslt = set_accel_config(&dev);

  37.   if (rslt == BMI323_OK)
  38.   {
  39.     rslt = bmi323_get_sensor_config(&config, 1, &dev);
  40.     bmi3_error_codes_print_result("bmi323_get_sensor_config", rslt);
  41.   }

  42.   /* Gyro configuration settings. */
  43.   rslt = set_gyro_config(&dev);

  44.   if (rslt == BMI323_OK)
  45.   {
  46.     rslt = bmi323_get_sensor_config(&config, 1, &dev);
  47.     bmi3_error_codes_print_result("bmi323_get_sensor_config", rslt);
  48.   }

  49.   /* USER CODE END 2 */

  50.   /* Infinite loop */
  51.   /* USER CODE BEGIN WHILE */
  52.   while (1)
  53.   {
  54.     /* USER CODE END WHILE */

  55.     /* USER CODE BEGIN 3 */
  56.     while (indx <= limit)
  57.     {
  58.       /* Select accel sensor. */
  59.       sensor_data.type = BMI323_ACCEL;

  60.       printf("\nAccel Sensor");
  61.       printf("\nData set, Range, Acc_Raw_X, Acc_Raw_Y, Acc_Raw_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n\n");

  62.       /* Get accelerometer data for x, y and z axis. */
  63.       rslt = bmi323_get_sensor_data(&sensor_data, 1, &dev);
  64.       bmi3_error_codes_print_result("Get sensor data", rslt);

  65.       /* Converting lsb to meter per second squared for 16 bit accelerometer at 2G range. */
  66.       x = lsb_to_mps2(sensor_data.sens_data.acc.x, 2, dev.resolution);
  67.       y = lsb_to_mps2(sensor_data.sens_data.acc.y, 2, dev.resolution);
  68.       z = lsb_to_mps2(sensor_data.sens_data.acc.z, 2, dev.resolution);

  69.       /* Print the data in m/s2. */
  70.       printf("%d, %d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n",
  71.              indx,
  72.              config.cfg.acc.range,
  73.              sensor_data.sens_data.acc.x,
  74.              sensor_data.sens_data.acc.y,
  75.              sensor_data.sens_data.acc.z,
  76.              x,
  77.              y,
  78.              z);

  79.       /* Select gyro sensor. */
  80.       sensor_data.type = BMI323_GYRO;

  81.       printf("\nGyro Sensor");
  82.       printf("\nData set, Range, Gyr_Raw_X, Gyr_Raw_Y, Gyr_Raw_Z, Gyr_dps_X, Gyr_dps_Y, Gyr_dps_Z\n\n");

  83.       /* Get gyro data for x, y and z axis. */
  84.       rslt = bmi323_get_sensor_data(&sensor_data, 1, &dev);
  85.       bmi3_error_codes_print_result("Get sensor data", rslt);

  86.       /* Converting lsb to degree per second for 16 bit gyro at 2000dps range. */
  87.       x = lsb_to_dps(sensor_data.sens_data.gyr.x, (float)2000, dev.resolution);
  88.       y = lsb_to_dps(sensor_data.sens_data.gyr.y, (float)2000, dev.resolution);
  89.       z = lsb_to_dps(sensor_data.sens_data.gyr.z, (float)2000, dev.resolution);

  90.       /* Print the data in dps. */
  91.       printf("%d, %d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n",
  92.              indx,
  93.              config.cfg.gyr.range,
  94.              sensor_data.sens_data.gyr.x,
  95.              sensor_data.sens_data.gyr.y,
  96.              sensor_data.sens_data.gyr.z,
  97.              x,
  98.              y,
  99.              z);

  100.       indx++;

  101.       HAL_DelayMs(2000);
  102.     }
  103.   }
复制代码

输出结果

将程序下载到NUCLEO-G070开发板中,运行程序,打开友善串口调试助手,选择正确的串口号,稍后将显示接收到的数据:

串口输出.jpg


跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 14 | 回复: 14



手机版|

GMT+8, 2024-12-19 02:07 , Processed in 0.050956 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表