【STEVAL-STWINKT1B测评5--六轴 ISM330DHCX(3轴陀螺仪 + 3轴陀加速度计)】
其中,INT1,INT2我们在CUBEMX中是不需要进行配置的,因为查看数据手册我们可以得知,这两个引脚的功能是一个中断的作用,我们无需在CUBEMX和后面的程序中对此做任何修改。CPHA = 1 :在 “时钟完成一次跳变后的第二个边沿” 采样(比如 CPOL=1 时,先从高→低(下降沿 ),再低→高(上升沿 ),第二个边沿是上升沿,就用上升沿采样 )。首先,在CUBEMX中进行SPI 的配置。首
一、外设配置
首先,查阅原理图,如下图:


这款传感器仍旧采用spi与MCU进行通信。
首先,在CUBEMX中进行SPI 的配置。由于需要将采集到的数据显示在PC端,我们采用USART2利用串口的方式与PC端通信。这些的配置和测评4的cubemx配置除过SPI参数部分其他完全相同,大家可以点击链接参考CUBEMX的基础配置,此处我不再赘述。(后面仅讲解SPI参数部分配置)
这里首先想通过这个芯片的数据手册和大家进行一些分享学习,这款ISM330DHCX芯片功能比较强大,可以测试加速度,角速度,芯片内部温度三种数据,支持spi/i2c通信。

此外,这款芯片还支持机器学习

ISM330DHCX内嵌了专门的机器学习处理核心,从而提供了系统灵活性,使得原本在应用处理器中运行的某些算法可以迁移到MEMS传感器上,同时还能实现一致的功耗降低。
在cubemx配置过程中,发现这款芯片上还有其他三个引脚,我们是否需要配置呢?

其中,INT1,INT2我们在CUBEMX中是不需要进行配置的,因为查看数据手册我们可以得知,这两个引脚的功能是一个中断的作用,我们无需在CUBEMX和后面的程序中对此做任何修改。

但是,CS片选引脚,我们需要再后面的程序中将其拉低,才可以让芯片正常工作。


根据时序图配置CPOL和CPHA
CPOL: CS 拉低(选中从机 )后,SPC 在 “等待传输” 的那段空闲期(最开始的水平段 )是高电平 → 所以 CPOL = 1 。
CPHA: 这个相较于CPOL而言较为复杂。
首先看他的定义:决定 “数据采样是在时钟的上升沿还是下降沿” ,本质是 “数据与时钟沿的对齐方式” 。
CPHA = 0 :在 “时钟空闲电平跳变到相反电平的第一个边沿” 采样(比如 CPOL=1 时,空闲是高,第一个边沿是 “下降沿” ,就用下降沿采样 )。
CPHA = 1 :在 “时钟完成一次跳变后的第二个边沿” 采样(比如 CPOL=1 时,先从高→低(下降沿 ),再低→高(上升沿 ),第二个边沿是上升沿,就用上升沿采样 )。
根据我们这个时序图发现,时钟空闲电平跳变到相反电平的第一个边沿,并没有进行数据采样

而是,在时钟完成一次跳变后的第一个边沿采样。
CUBEMX中这部分的配置如下,其他部分完全相同

二、BSP包下载与安装,代码编写
参考测评3下载对应的板级支持包,也同样参考测评3将下载的BSP包安装到相应路径


我将修改好的ism330dhcx_read_data_polling.c文件同样分享给大家,可以直接粘贴替换。
/*
******************************************************************************
* @file read_data_polling.c
* @author Sensors Software Solution Team
* @brief This file shows how to get data from ISM330DHCX sensor on STWINKT1B.
*
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* 仅启用STWINKT1B开发板定义 */
#define STWINKT1B /* 主控为STM32L4R9ZIJ6的STWINKT1B开发板 */
#if defined(STWINKT1B)
/* 传感器通信接口:SPI3(STWINKT1B上ISM330DHCX连接SPI3,原理图3/7节) */
#define SENSOR_BUS hspi3
/* 片选引脚定义(根据STWINKT1B原理图3/7,ISM330DHCX的CS引脚为PF13){insert\_element\_0\_} */
#define CS_PORT GPIOF
#define CS_PIN GPIO_PIN_13
/* 串口输出接口:USART2(TX=PA2,RX=PA3,用于数据发送到PC) */
#define COM_UART huart2
#endif
/* Includes ------------------------------------------------------------------*/
#include <string.h>
#include <stdio.h>
#include "ism330dhcx_reg.h"
#include "stm32l4xx_hal.h" /* STM32L4系列HAL库 */
#include "usart.h" /* USART2初始化代码(CubeMX生成) */
#include "spi.h" /* SPI3初始化代码(CubeMX生成) */
#include "gpio.h" /* GPIO初始化代码(CubeMX生成) */
/* Private macro -------------------------------------------------------------*/
#define BOOT_TIME 10 // 传感器启动时间(ms),符合数据手册4.2节电气特性
/* Private variables ---------------------------------------------------------*/
static int16_t data_raw_acceleration[3]; // 加速度原始数据
static int16_t data_raw_angular_rate[3]; // 角速度原始数据
static int16_t data_raw_temperature; // 温度原始数据
static float_t acceleration_mg[3]; // 加速度转换后数据(mg)
static float_t angular_rate_mdps[3]; // 角速度转换后数据(mdps)
static float_t temperature_degC; // 温度转换后数据(℃)
static uint8_t whoamI, rst; // 设备ID和复位状态
static uint8_t tx_buffer[256]; // 串口发送缓冲区
/* Private functions ---------------------------------------------------------*/
static int32_t platform_write(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len);
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len);
static void tx_com(uint8_t *tx_buffer, uint16_t len);
static void platform_delay(uint32_t ms);
static void platform_init(void);
/* Main Example --------------------------------------------------------------*/
void ism330dhcx_read_data_polling(void)
{
stmdev_ctx_t dev_ctx; // 传感器设备上下文
/* 初始化设备接口 */
dev_ctx.write_reg = platform_write; // 绑定写函数
dev_ctx.read_reg = platform_read; // 绑定读函数
dev_ctx.mdelay = platform_delay; // 绑定延时函数
dev_ctx.handle = &SENSOR_BUS; // 绑定SPI句柄
/* 初始化硬件平台 */
platform_init();
/* 等待传感器启动(数据手册4.2节规定启动时间Typ=35ms,此处留有余量) */
platform_delay(BOOT_TIME);
/* 读取设备ID(数据手册9.11节,WHO_AM_I寄存器地址0Fh,默认值6Bh) */
ism330dhcx_device_id_get(&dev_ctx, &whoamI);
if (whoamI != ISM330DHCX_ID) // 校验设备ID
while (1); // ID错误则卡死
/* 软件复位传感器(数据手册9.14节,CTRL3_C寄存器SW_RESET位) */
ism330dhcx_reset_set(&dev_ctx, PROPERTY_ENABLE);
do {
ism330dhcx_reset_get(&dev_ctx, &rst);
} while (rst); // 等待复位完成
/* 配置传感器工作模式 */
ism330dhcx_device_conf_set(&dev_ctx, PROPERTY_ENABLE); // 使能设备
ism330dhcx_block_data_update_set(&dev_ctx, PROPERTY_ENABLE); // 使能块数据更新(BDU)
/* 配置输出数据率(ODR):根据数据手册9.12/9.13节 */
ism330dhcx_xl_data_rate_set(&dev_ctx, ISM330DHCX_XL_ODR_12Hz5); // 加速度计12.5Hz
ism330dhcx_gy_data_rate_set(&dev_ctx, ISM330DHCX_GY_ODR_12Hz5); // 陀螺仪12.5Hz
/* 配置量程:根据数据手册4.1节机械特性 */
ism330dhcx_xl_full_scale_set(&dev_ctx, ISM330DHCX_2g); // 加速度计量程±2g
ism330dhcx_gy_full_scale_set(&dev_ctx, ISM330DHCX_2000dps); // 陀螺仪量程±2000dps
/* 配置滤波器(数据手册6.4节):加速度计LPF2使能 */
ism330dhcx_xl_filter_lp2_set(&dev_ctx, PROPERTY_ENABLE);
/* 轮询模式读取数据 */
while (1) {
uint8_t reg;
/* 读取加速度数据(数据就绪标志:STATUS_REG寄存器XLDA位) */
ism330dhcx_xl_flag_data_ready_get(&dev_ctx, ®);
if (reg) {
ism330dhcx_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
acceleration_mg[0] = ism330dhcx_from_fs2g_to_mg(data_raw_acceleration[0]);
acceleration_mg[1] = ism330dhcx_from_fs2g_to_mg(data_raw_acceleration[1]);
acceleration_mg[2] = ism330dhcx_from_fs2g_to_mg(data_raw_acceleration[2]);
snprintf((char *)tx_buffer, sizeof(tx_buffer),
"Acceleration [mg]: X=%.2f, Y=%.2f, Z=%.2f\r\n",
acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);
tx_com(tx_buffer, strlen((char const *)tx_buffer));
}
/* 读取角速度数据(数据就绪标志:STATUS_REG寄存器GDA位) */
ism330dhcx_gy_flag_data_ready_get(&dev_ctx, ®);
if (reg) {
ism330dhcx_angular_rate_raw_get(&dev_ctx, data_raw_angular_rate);
angular_rate_mdps[0] = ism330dhcx_from_fs2000dps_to_mdps(data_raw_angular_rate[0]);
angular_rate_mdps[1] = ism330dhcx_from_fs2000dps_to_mdps(data_raw_angular_rate[1]);
angular_rate_mdps[2] = ism330dhcx_from_fs2000dps_to_mdps(data_raw_angular_rate[2]);
snprintf((char *)tx_buffer, sizeof(tx_buffer),
"Angular rate [mdps]: X=%.2f, Y=%.2f, Z=%.2f\r\n",
angular_rate_mdps[0], angular_rate_mdps[1], angular_rate_mdps[2]);
tx_com(tx_buffer, strlen((char const *)tx_buffer));
}
/* 读取温度数据(数据就绪标志:STATUS_REG寄存器TDA位) */
ism330dhcx_temp_flag_data_ready_get(&dev_ctx, ®);
if (reg) {
ism330dhcx_temperature_raw_get(&dev_ctx, &data_raw_temperature);
temperature_degC = ism330dhcx_from_lsb_to_celsius(data_raw_temperature);
snprintf((char *)tx_buffer, sizeof(tx_buffer),
"Temperature: %.2f\r\n", temperature_degC);
tx_com(tx_buffer, strlen((char const *)tx_buffer));
}
platform_delay(100); // 轮询间隔100ms
}
}
/* SPI写函数(平台相关) */
static int32_t platform_write(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
/* 片选拉低(选中传感器) */
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);
/* 发送寄存器地址(SPI写命令:地址最高位为0,数据手册5.1.2节) */
uint8_t tx_reg = reg & 0x7F;
HAL_SPI_Transmit(handle, &tx_reg, 1, 100);
/* 发送数据 */
HAL_SPI_Transmit(handle, (uint8_t*)bufp, len, 100);
/* 片选拉高(释放传感器) */
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
return 0;
}
/* SPI读函数(平台相关) */
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
/* 片选拉低(选中传感器) */
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);
/* 发送寄存器地址(SPI读命令:地址最高位为1,数据手册5.1.2节) */
uint8_t tx_reg = reg | 0x80;
HAL_SPI_Transmit(handle, &tx_reg, 1, 100);
/* 接收数据 */
HAL_SPI_Receive(handle, bufp, len, 100);
/* 片选拉高(释放传感器) */
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
return 0;
}
/* 串口发送函数(平台相关) */
static void tx_com(uint8_t *tx_buffer, uint16_t len)
{
HAL_UART_Transmit(&COM_UART, tx_buffer, len, 1000); // 通过USART2发送
}
/* 延时函数(平台相关) */
static void platform_delay(uint32_t ms)
{
HAL_Delay(ms); // 使用HAL库延时
}
/* 平台初始化函数(硬件初始化) */
static void platform_init(void)
{
/* 初始化SPI3、USART2、GPIO(由CubeMX自动生成,需确保以下配置):
* - SPI3配置:模式3(CPOL=1,CPHA=1),速率≤10MHz(数据手册4.4.1节)
* - CS_PIN(PF13):推挽输出,初始高电平(原理图3/7节){insert\_element\_1\_}
* - USART2:波特率115200,8N1
*/
MX_SPI3_Init();
MX_USART2_UART_Init();
MX_GPIO_Init();
/* 初始化片选引脚为高电平(未选中传感器) */
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
}
在主函数中添加相应的.h文件和一部分代码

然后,编译烧录即可
三、效果实现
通过串口打印到PC端,可以接收到三种数据,如下图所示:

其中角速度单位为: mdps ( milli degrees per second) 表示 毫度每秒
同样,我们MATLAB生成对应的折线图,观测数据变化


在两侧的红框里边是处于静止状态,中间的部分是我进行抖动的变化,据图可见数据变化还是比较灵敏,但是在静止状态下我们发现会出现一些抖动的点,这部分还没有理解是怎么回事。
更多推荐






所有评论(0)