STM32 SPI驱动读取LSM6DSRTR

打印 上一主题 下一主题

主题 685|帖子 685|积分 2055

提示:通过SPI驱动读取传感器数据
  
  

媒介

制作一个倾角传感器,通过SPI读取LSM6DSRTR的加速度数据转换为角度,不用IIC的原因是考虑IIC通讯的协议过于繁琐,且会影响后续的发包速率。

一、LSM6DSRTR

六轴传感器,最好用ST的芯片来读取,紧张是ST在这块已经提供好驱动了,其它也行,都一样简单。其次就是,你必要配置好SPI,这个很紧张,不然很容易读不出来。
二、配置步调

1.配置SPI

注意:通过STM32CUBEMX 来构建代码

  1. static void MX_SPI1_Init(void)
  2. {
  3.   hspi1.Instance = SPI1;
  4.   hspi1.Init.Mode = SPI_MODE_MASTER;
  5.   hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  6.   hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  7.   hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
  8.   hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  9.   hspi1.Init.NSS = SPI_NSS_SOFT;
  10.   hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
  11.   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  12.   hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  13.   hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  14.   hspi1.Init.CRCPolynomial = 7;
  15.   if (HAL_SPI_Init(&hspi1) != HAL_OK)
  16.   {
  17.     Error_Handler();
  18.   }
  19.   /* USER CODE BEGIN SPI1_Init 2 */
  20.   /* USER CODE END SPI1_Init 2 */
  21. }
复制代码
2.引入 LSM驱动库


案例代码
  1. #include <string.h>
  2. #include <stdio.h>
  3. #include "lsm6dsr_reg.h"
  4. #include "stm32l0xx_hal.h"
  5. #include "main.h"
  6. #define CS_Pin GPIO_PIN_4
  7. #define CS_GPIO_Port GPIOA
  8. #define LED_Pin GPIO_PIN_12
  9. #define LED_GPIO_Port GPIOA
  10. #define BOOT_TIME 10 // ms
  11. #define PI 3.1415926
  12. extern SPI_HandleTypeDef hspi1;
  13. extern UART_HandleTypeDef huart1;
  14. static stmdev_ctx_t dev_ctx;
  15. /* Private variables ---------------------------------------------------------*/
  16. static int16_t data_raw_acceleration[3];
  17. static int16_t data_raw_angular_rate[3];
  18. static int16_t data_raw_temperature;
  19. static float acceleration_mg[3];
  20. static float angular_rate_mdps[3];
  21. static uint8_t whoamI, rst;
  22. static uint8_t tx_buffer[1000];
  23. static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp,
  24.                               uint16_t len);
  25. static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,
  26.                              uint16_t len);
  27. static void tx_com(uint8_t *tx_buffer, uint16_t len);
  28. static void platform_delay(uint32_t ms);
  29. /* Main Example --------------------------------------------------------------*/
  30. //在主函数里面调用这个接口就行
  31. void lsm6dsr_read_angle_data_polling(void)
  32. {
  33.     uint8_t reg;
  34.     /* Read output only if new xl value is available */
  35.     lsm6dsr_xl_flag_data_ready_get(&dev_ctx, &reg);
  36.     if (reg)
  37.     {
  38.         /* Read acceleration field data */
  39.         memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
  40.         lsm6dsr_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
  41.         acceleration_mg[0] =
  42.             lsm6dsr_from_fs2g_to_mg(data_raw_acceleration[0]);
  43.         acceleration_mg[1] =
  44.             lsm6dsr_from_fs2g_to_mg(data_raw_acceleration[1]);
  45.         acceleration_mg[2] =
  46.             lsm6dsr_from_fs2g_to_mg(data_raw_acceleration[2]);
  47.         /* 注意:atan算出来的是弧度值, 然后1弧度 = 180/Π */
  48.         float angle_x = atan(acceleration_mg[0] / sqrt(acceleration_mg[2] * acceleration_mg[2] + acceleration_mg[1] * acceleration_mg[1])) * 180 / PI;
  49.         float angle_y = atan(acceleration_mg[1] / sqrt(acceleration_mg[0] * acceleration_mg[0] + acceleration_mg[2] * acceleration_mg[2])) * 180 / PI;
  50.         float angle_z = atan(acceleration_mg[2] / sqrt(acceleration_mg[0] * acceleration_mg[0] + acceleration_mg[1] * acceleration_mg[1])) * 180 / PI;
  51.         sprintf((char *)tx_buffer,
  52.                 "Acceleration [mg]:%4.2f\t%4.2f\t%4.2f\r\n",
  53.                 acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);
  54.         //这边是计算出来的角度值
  55.         sprintf((char *)tx_buffer,
  56.                 "Angle :x %4.2f\t y %4.2f\t z %4.2f\r\n",
  57.                 angle_x, angle_y, angle_z);
  58.         tx_com(tx_buffer, strlen((char const *)tx_buffer));
  59.     }
  60.     // lsm6dsr_gy_flag_data_ready_get(&dev_ctx, &reg);
  61.     // if (reg)
  62.     // {
  63.     //     /* Read angular rate field data */
  64.     //     memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));
  65.     //     lsm6dsr_angular_rate_raw_get(&dev_ctx, data_raw_angular_rate);
  66.     //     angular_rate_mdps[0] =
  67.     //         lsm6dsr_from_fs2000dps_to_mdps(data_raw_angular_rate[0]);
  68.     //     angular_rate_mdps[1] =
  69.     //         lsm6dsr_from_fs2000dps_to_mdps(data_raw_angular_rate[1]);
  70.     //     angular_rate_mdps[2] =
  71.     //         lsm6dsr_from_fs2000dps_to_mdps(data_raw_angular_rate[2]);
  72.     //     sprintf((char *)tx_buffer,
  73.     //             "Angular rate [mdps]:%4.2f\t%4.2f\t%4.2f\r\n",
  74.     //             angular_rate_mdps[0], angular_rate_mdps[1], angular_rate_mdps[2]);
  75.     //     tx_com(tx_buffer, strlen((char const *)tx_buffer));
  76.     // }
  77.     platform_delay(1000);
  78. }
  79. /*
  80. * @brief  Write generic device register (platform dependent)
  81. *
  82. * @param  handle    customizable argument. In this examples is used in
  83. *                   order to select the correct sensor bus handler.
  84. * @param  reg       register to write
  85. * @param  bufp      pointer to data to write in register reg
  86. * @param  len       number of consecutive register to write
  87. *
  88. */
  89. static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp,
  90.                               uint16_t len)
  91. {
  92.     HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
  93.     HAL_SPI_Transmit(handle, &reg, 1, 1000);
  94.     HAL_SPI_Transmit(handle, (uint8_t *)bufp, len, 1000);
  95.     HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
  96.     return 0;
  97. }
  98. /*
  99. * @brief  Read generic device register (platform dependent)
  100. *
  101. * @param  handle    customizable argument. In this examples is used in
  102. *                   order to select the correct sensor bus handler.
  103. * @param  reg       register to read
  104. * @param  bufp      pointer to buffer that store the data read
  105. * @param  len       number of consecutive register to read
  106. *
  107. */
  108. static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,
  109.                              uint16_t len)
  110. {
  111.     reg |= 0x80;
  112.     HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
  113.     HAL_SPI_Transmit(handle, &reg, 1, 1000);
  114.     HAL_SPI_Receive(handle, bufp, len, 1000);
  115.     HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
  116.     return 0;
  117. }
  118. /*
  119. * @brief  Send buffer to console (platform dependent)
  120. *
  121. * @param  tx_buffer     buffer to transmit
  122. * @param  len           number of byte to send
  123. *
  124. */
  125. static void tx_com(uint8_t *tx_buffer, uint16_t len)
  126. {
  127.     HAL_UART_Transmit(&huart1, tx_buffer, len, 1000);
  128. }
  129. /*
  130. * @brief  platform specific delay (platform dependent)
  131. *
  132. * @param  ms        delay in ms
  133. *
  134. */
  135. static void platform_delay(uint32_t ms)
  136. {
  137.     HAL_Delay(ms);
  138. }
  139. /*
  140. * @brief  platform specific initialization (platform dependent)
  141. */
  142. void platform_init(void)
  143. {
  144.     /* Initialize mems driver interface */
  145.     dev_ctx.write_reg = platform_write;
  146.     dev_ctx.read_reg = platform_read;
  147.     dev_ctx.handle = &hspi1;
  148.     /* Wait sensor boot time */
  149.     platform_delay(BOOT_TIME);
  150.     /* Check device ID */
  151.     while (1)
  152.     {
  153.         // 考虑如何喂狗
  154.         lsm6dsr_device_id_get(&dev_ctx, &whoamI);
  155.         if (whoamI == LSM6DSR_ID)
  156.         {
  157.             sprintf((char *)tx_buffer,
  158.                     "Read id :0x%2x\r\n",
  159.                     whoamI);
  160.             tx_com(tx_buffer, strlen((char const *)tx_buffer));
  161.             break;
  162.         }
  163.         platform_delay(BOOT_TIME);
  164.     }
  165.     /* Restore default configuration */
  166.     lsm6dsr_reset_set(&dev_ctx, PROPERTY_ENABLE);
  167.     do
  168.     {
  169.         lsm6dsr_reset_get(&dev_ctx, &rst);
  170.     } while (rst);
  171.     /* Disable I3C interface */
  172.     lsm6dsr_i3c_disable_set(&dev_ctx, LSM6DSR_I3C_DISABLE);
  173.     /* Enable Block Data Update */
  174.     lsm6dsr_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
  175.     /* Set Output Data Rate */
  176.     lsm6dsr_xl_data_rate_set(&dev_ctx, LSM6DSR_XL_ODR_12Hz5);
  177.     lsm6dsr_gy_data_rate_set(&dev_ctx, LSM6DSR_GY_ODR_12Hz5);
  178.     /* Set full scale */
  179.     lsm6dsr_xl_full_scale_set(&dev_ctx, LSM6DSR_2g);
  180.     lsm6dsr_gy_full_scale_set(&dev_ctx, LSM6DSR_2000dps);
  181.     /* Configure filtering chain(No aux interface)
  182.      * Accelerometer - LPF1 + LPF2 path
  183.      */
  184.     lsm6dsr_xl_hp_path_on_out_set(&dev_ctx, LSM6DSR_LP_ODR_DIV_100);
  185.     lsm6dsr_xl_filter_lp2_set(&dev_ctx, PROPERTY_ENABLE);
  186. }
复制代码
3.结果



总结

有什么题目,可以评论区内里提一下,看到都会帮助办理,这个案例只是简单应用,没有涉及复杂的使用过程。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用户云卷云舒

金牌会员
这个人很懒什么都没写!

标签云

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