[STM32L5] 【STM32L562E-DK试用】3D加速度计和陀螺仪测试

[复制链接]
 楼主| 傅沈骁 发表于 2025-3-15 16:43 | 显示全部楼层 |阅读模式
<
本帖最后由 傅沈骁 于 2025-3-15 16:42 编辑

开发板上有个LSM6DSO,这是3D加速度计和陀螺仪的组合,其系统如下图所示。
2880667d53908bbe33.png

板载的LSM6DSO如下图所示。

9667167d5381f67ab6.png

可以看到,LSM6DSO的CS引脚和SDO/SAO已经分别被上拉和下拉了,说明该传感器已经使能,并且工作在IIC模式下。我们程序的重点在于如何读取该传感器内部的值。
根据下表可以看出该传感器运行在IIC模式下。
3690467d5395061796.png

对于相关的LSM6DSO驱动文件,已在ST官方github中提供https://github.com/STMicroelectronics/lsm6dso-pid
首先在CubeMX中新建工程,并按照默认初始化STM32L562E-DK开发板的芯片引脚。为了在屏幕上显示相关信息,需要定义LCD屏幕的相关参数,可以参见我之前的帖子https://bbs.21ic.com/icview-3435852-1-1.html
首先定义相关变量
  1. #define SENSOR_BUS hi2c1

  2. /* Private macro -------------------------------------------------------------*/
  3. #define    BOOT_TIME      10

  4. /* Private variables ---------------------------------------------------------*/
  5. static int16_t data_raw_acceleration[3];
  6. static int16_t data_raw_angular_rate[3];
  7. static int16_t data_raw_temperature;
  8. static float_t acceleration_mg[3];
  9. static float_t angular_rate_mdps[3];
  10. static float_t temperature_degC;
  11. static uint8_t whoamI, rst;
  12. static uint8_t buffer[1000];
定义读写函数
  1. static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp,
  2.                               uint16_t len)
  3. {
  4.   HAL_I2C_Mem_Write(handle, LSM6DSO_I2C_ADD_L, reg,
  5.                     I2C_MEMADD_SIZE_8BIT, (uint8_t*) bufp, len, 1000);
  6.   return 0;
  7. }

  8. /*
  9. * [url=home.php?mod=space&uid=247401]@brief[/url]  Read generic device register (platform dependent)
  10. *
  11. * @param  handle    customizable argument. In this examples is used in
  12. *                   order to select the correct sensor bus handler.
  13. * @param  reg       register to read
  14. * @param  bufp      pointer to buffer that store the data read
  15. * @param  len       number of consecutive register to read
  16. *
  17. */
  18. static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,
  19.                              uint16_t len)
  20. {
  21.   HAL_I2C_Mem_Read(handle, LSM6DSO_I2C_ADD_L, reg,
  22.                    I2C_MEMADD_SIZE_8BIT, bufp, len, 1000);
  23.   return 0;
  24. }
初始化mems,其中由于LSM6DSO使用的是IIC,所以要关闭I3C
  1.   stmdev_ctx_t dev_ctx;
  2.   /* Initialize mems driver interface */
  3.   dev_ctx.write_reg = platform_write;
  4.   dev_ctx.read_reg = platform_read;
  5.   dev_ctx.mdelay = platform_delay;
  6.   dev_ctx.handle = &SENSOR_BUS;
  7.   /* Init test platform */
  8.   /* Wait sensor boot time */
  9.   platform_delay(BOOT_TIME);
  10.   /* Check device ID */
  11.   lsm6dso_device_id_get(&dev_ctx, &whoamI);
  12.   printf("LSM6DSO_ID=0x%x,whoamI=0x%x",LSM6DSO_ID,whoamI);
  13.   if (whoamI != LSM6DSO_ID)
  14.     while (1);

  15.   /* Restore default configuration */
  16.   lsm6dso_reset_set(&dev_ctx, PROPERTY_ENABLE);

  17.   do {
  18.     lsm6dso_reset_get(&dev_ctx, &rst);
  19.   } while (rst);

  20.   /* Disable I3C interface */
  21.   lsm6dso_i3c_disable_set(&dev_ctx, LSM6DSO_I3C_DISABLE);
  22.   /* Enable Block Data Update */
  23.   lsm6dso_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
  24.   /* Set Output Data Rate */
  25.   lsm6dso_xl_data_rate_set(&dev_ctx, LSM6DSO_XL_ODR_12Hz5);
  26.   lsm6dso_gy_data_rate_set(&dev_ctx, LSM6DSO_GY_ODR_12Hz5);
  27.   /* Set full scale */
  28.   lsm6dso_xl_full_scale_set(&dev_ctx, LSM6DSO_2g);
  29.   lsm6dso_gy_full_scale_set(&dev_ctx, LSM6DSO_2000dps);
  30.   /* Configure filtering chain(No aux interface)
  31.    * Accelerometer - LPF1 + LPF2 path
  32.    */
  33.   lsm6dso_xl_hp_path_on_out_set(&dev_ctx, LSM6DSO_LP_ODR_DIV_100);
  34.   lsm6dso_xl_filter_lp2_set(&dev_ctx, PROPERTY_ENABLE);
初始化LCD
  1.   LCD_UTILS_Drv_t lcdDrv;
  2.   /* Initialize the LCD */
  3.   BSP_LCD_Init(0, LCD_ORIENTATION_PORTRAIT);
  4.   /* Set UTIL_LCD functions */
  5.   lcdDrv.DrawBitmap  = BSP_LCD_DrawBitmap;
  6.   lcdDrv.FillRGBRect = BSP_LCD_FillRGBRect;
  7.   lcdDrv.DrawHLine   = BSP_LCD_DrawHLine;
  8.   lcdDrv.DrawVLine   = BSP_LCD_DrawVLine;
  9.   lcdDrv.FillRect    = BSP_LCD_FillRect;
  10.   lcdDrv.GetPixel    = BSP_LCD_ReadPixel;
  11.   lcdDrv.SetPixel    = BSP_LCD_WritePixel;
  12.   lcdDrv.GetXSize    = BSP_LCD_GetXSize;
  13.   lcdDrv.GetYSize    = BSP_LCD_GetYSize;
  14.   lcdDrv.SetLayer    = BSP_LCD_SetActiveLayer;
  15.   lcdDrv.GetFormat   = BSP_LCD_GetFormat;
  16.   UTIL_LCD_SetFuncDriver(&lcdDrv);
  17.   /* Clear the LCD */
  18.   UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);
  19.   BSP_LCD_DisplayOn(0);
  20.   UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_BLUE);
  21.   UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
  22.   UTIL_LCD_SetFont(&Font24);
在主循环中,不断读取传感器数值,并显示在LCD屏幕上
  1.   while (1)
  2.   {
  3.             uint8_t reg;
  4.             /* Read output only if new xl value is available */
  5.             lsm6dso_xl_flag_data_ready_get(&dev_ctx, ®);

  6.             if (reg) {
  7.               /* Read acceleration field data */
  8.               memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
  9.               lsm6dso_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
  10.               acceleration_mg[0] =
  11.                 lsm6dso_from_fs2_to_mg(data_raw_acceleration[0]);
  12.               acceleration_mg[1] =
  13.                 lsm6dso_from_fs2_to_mg(data_raw_acceleration[1]);
  14.               acceleration_mg[2] =
  15.                 lsm6dso_from_fs2_to_mg(data_raw_acceleration[2]);
  16. //              printf("Acceleration [mg]:%4.2f,%4.2f,%4.2f\r\n",
  17. //                      acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);
  18.             }
  19.             sprintf((char *)buffer," accX:%4.2f    ",acceleration_mg[0]);
  20.             UTIL_LCD_DisplayStringAt(0, 10, (uint8_t *)buffer, LEFT_MODE);
  21.             memset(buffer,0,sizeof(buffer));
  22.             sprintf((char *)buffer," accY:%4.2f    ",acceleration_mg[1]);
  23.                 UTIL_LCD_DisplayStringAt(0, 40, (uint8_t *)buffer, LEFT_MODE);
  24.                 memset(buffer,0,sizeof(buffer));
  25.                 sprintf((char *)buffer," accZ:%4.2f    ",acceleration_mg[2]);
  26.                 UTIL_LCD_DisplayStringAt(0, 70, (uint8_t *)buffer, LEFT_MODE);
  27.                 memset(buffer,0,sizeof(buffer));
  28.             lsm6dso_gy_flag_data_ready_get(&dev_ctx, ®);

  29.             if (reg) {
  30.               /* Read angular rate field data */
  31.               memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));
  32.               lsm6dso_angular_rate_raw_get(&dev_ctx, data_raw_angular_rate);
  33.               angular_rate_mdps[0] =
  34.                 lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate[0]);
  35.               angular_rate_mdps[1] =
  36.                 lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate[1]);
  37.               angular_rate_mdps[2] =
  38.                 lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate[2]);
  39. //              printf("Angular rate [mdps]:%4.2f,%4.2f,%4.2f\r\n",
  40. //                      angular_rate_mdps[0], angular_rate_mdps[1], angular_rate_mdps[2]);
  41.             }
  42.             sprintf((char *)buffer," angP:%4.2f    ",angular_rate_mdps[0]);
  43.             UTIL_LCD_DisplayStringAt(0, 100, (uint8_t *)buffer, LEFT_MODE);
  44.             memset(buffer,0,sizeof(buffer));
  45.             sprintf((char *)buffer," angY:%4.2f    ",angular_rate_mdps[1]);
  46.                 UTIL_LCD_DisplayStringAt(0, 130, (uint8_t *)buffer, LEFT_MODE);
  47.                 memset(buffer,0,sizeof(buffer));
  48.                 sprintf((char *)buffer," angR:%4.2f    ",angular_rate_mdps[2]);
  49.                 UTIL_LCD_DisplayStringAt(0, 160, (uint8_t *)buffer, LEFT_MODE);
  50.                 memset(buffer,0,sizeof(buffer));

  51.             lsm6dso_temp_flag_data_ready_get(&dev_ctx, ®);

  52.             if (reg) {
  53.               /* Read temperature data */
  54.               memset(&data_raw_temperature, 0x00, sizeof(int16_t));
  55.               lsm6dso_temperature_raw_get(&dev_ctx, &data_raw_temperature);
  56.               temperature_degC =
  57.                 lsm6dso_from_lsb_to_celsius(data_raw_temperature);
  58. //              printf("Temperature [degC]:%6.2f\r\n", temperature_degC);
  59.             }
  60.                 sprintf((char *)buffer," Temp:%6.2f    ",temperature_degC);
  61.                 UTIL_LCD_DisplayStringAt(0, 190, (uint8_t *)buffer, LEFT_MODE);
  62.                 memset(buffer,0,sizeof(buffer));
  63.     /* USER CODE END WHILE */

  64.     /* USER CODE BEGIN 3 */
  65.   }
最终得到结果如下,可以看到输出包括三个方向的加速度、三个方向的角加速度,以及当前温度,温度值有些高,可能是LSM6DSO正好位于蓝牙模块下方,温度较高。
4529167d53ce042ce2.jpg
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

16

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部