[PSOC™] 【英飞凌 CY8CKIT-062S2-AI评测】第二篇:传感器数据采集与处理

[复制链接]
48|1
hbzjt2011 发表于 2025-10-27 13:37 | 显示全部楼层 |阅读模式
[i=s] 本帖最后由 hbzjt2011 于 2025-10-27 22:49 编辑 [/i]

在第一篇测评中,主要进行了CY8CKIT-062S2-AI开发板的硬件介绍和开发环境搭建。本篇将深入探讨这块开发板最核心的功能——多传感器数据采集与处理。作为一款专为边缘AI设计的开发板,它集成了6种不同类型的传感器,涵盖了声音、运动、环境、位置等多个维度。接下来将通过代码示例和实际测试,全面掌握这些传感器的使用方法。


一、传感器系统概览

1.1 传感器阵列架构

CY8CKIT-062S2-AI的传感器系统采用分布式架构设计:

                    PSoC™ 6 MCU (双核)
                          |
        +----------------+|+----------------+
        |                ||                 |
    I2C总线(P0[2:3])   SPI总线          PDM接口
    400kHz, 3.3V    (P12[0:3])        (P10[4:5])
        |              1.8V              3.3V
        |                |                 |
   +----+----+-------+   |            +----+----+
   |    |    |       |   |            |         |
  IMU  MAG  气压   (预留) 雷达      麦克风1  麦克风2
BMI270 BMM350 DPS368    BGT60TR13C  IM72D128 IM72D128

关键设计特点:

  • I2C共享总线: 3个传感器共用一条I2C总线,地址不冲突
  • 独立中断线: 每个I2C传感器都有独立的中断引脚
  • 电平隔离: 雷达使用1.8V逻辑,其他使用3.3V
  • 双麦克风差分: 支持波束成形和声源定位

1.2 传感器参数对比

传感器 接口 采样率 分辨率 功耗 主要应用
BMI270 IMU I2C 25-1600 Hz 16-bit 0.7 mA 运动检测、手势识别
BMM350磁力计 I2C 50-400 Hz 16-bit 0.17 mA 指南针、定向
DPS368气压 I2C 1-200 Hz 24-bit 1.7 µA 高度计、天气预报
BGT60TR13C雷达 SPI 可配置 12-bit 70 mW 存在检测、手势
IM72D128麦克风 PDM 16/48 kHz 61 dB SNR 1.2 mA 语音识别、声学
S25HS512闪存 QSPI 133 MHz 512 Mbit 25 mA 数据存储、XIP

二、I2C传感器数据采集

新建mtb-example-sensors-cy8ckit-062s2-ai工程

image.png

image.png

2.1 LED闪烁实验

目标: 验证开发环境,熟悉编译下载流程

1.1 硬件连接

CY8CKIT-062S2-AI → PC
    J1口 ──────────→ USB端口

板载LED位置:

  • D2: 用户LED1 (红色) - 连接到P5[3]
  • D3: 用户LED2 (红色) - 连接到P5[4]

1.2 编写代码

在项目的 main.c 中输入以下代码:

/******************************************************************************
 * 文件名: main.c
 * 实验1: LED闪烁 - 验证环境
 *****************************************************************************/

#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"

int main(void)
{
    cy_rslt_t result;

    /* 初始化板级支持包 */
    result = cybsp_init();
    CY_ASSERT(result == CY_RSLT_SUCCESS);

    /* 使能全局中断 */
    __enable_irq();

    /* 初始化调试串口 */
    result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, 
                                  CYBSP_DEBUG_UART_RX,
                                  CY_RETARGET_IO_BAUDRATE);
    CY_ASSERT(result == CY_RSLT_SUCCESS);

    /* 打印欢迎信息 */
    printf("\r\n=================================\r\n");
    printf("实验1: LED闪烁测试\r\n");
    printf("开发板: CY8CKIT-062S2-AI\r\n");
    printf("=================================\r\n\r\n");

    /* 初始化LED引脚 */
    cyhal_gpio_init(CYBSP_USER_LED1, CYHAL_GPIO_DIR_OUTPUT, 
                    CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_OFF);
    cyhal_gpio_init(CYBSP_USER_LED2, CYHAL_GPIO_DIR_OUTPUT,
                    CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_OFF);

    printf("LED初始化完成\r\n");
    printf("开始闪烁...\r\n\r\n");

    uint32_t count = 0;

    for (;;)
    {
        /* 切换LED1状态 */
        cyhal_gpio_toggle(CYBSP_USER_LED1);
  
        /* LED2相反相位 */
        cyhal_gpio_toggle(CYBSP_USER_LED2);
  
        /* 打印计数 */
        printf("闪烁次数: %lu\r\n", ++count);
  
        /* 延时500ms */
        cyhal_system_delay_ms(500);
    }
}

1.3 编译与下载

使用命令行:

bash

make build -j8
make program

image.png

image.png

1.4 验证结果

现象:

  • ✅ 两个LED以0.5秒间隔交替闪烁
  • ✅ 串口终端每0.5秒打印一次计数

**1761543235281_435x9601.gif
**

串口输出:

image.png

实验2: 第一个传感器 - IMU数据采集

目标: 读取BMI270六轴IMU数据,理解I2C通信

2.1 硬件原理

BMI270传感器连接:

PSoC™ 6                BMI270 (U18)
─────────              ──────────
P0[2] (SCL) ────────→  SCL
P0[3] (SDA) ←───────→  SDA
P0[4] (INT) ←────────  INT1
3.3V        ────────→  VDD
GND         ────────→  GND

I2C地址: 0x68 (默认)
I2C速率: 400kHz

2.2 添加库依赖

在项目根目录的 Makefile 中,找到 COMPONENTS= 这一行,添加:

makefile

COMPONENTS=sensor-motion-bmi270

然后在Modus Shell中运行:

bash

make getlibs

这会自动下载BMI270驱动库。

image.png

2.3 完整代码

修改 main.c:

/******************************************************************************
 * 文件名: main.c
 * 实验2: IMU数据采集
 *****************************************************************************/

#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
#include "mtb_bmi270.h"

/*******************************************************************************
 * 全局变量
 ******************************************************************************/
cyhal_i2c_t i2c_obj;              // I2C对象
mtb_bmi270_t motion_sensor;       // IMU传感器对象

/*******************************************************************************
 * 函数声明
 ******************************************************************************/
cy_rslt_t i2c_init(void);
cy_rslt_t imu_init(void);
void imu_read_and_print(void);

/*******************************************************************************
 * 主函数
 ******************************************************************************/
int main(void)
{
    cy_rslt_t result;

    /* 初始化BSP */
    result = cybsp_init();
    CY_ASSERT(result == CY_RSLT_SUCCESS);
    __enable_irq();

    /* 初始化串口 */
    result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, 
                                  CYBSP_DEBUG_UART_RX,
                                  CY_RETARGET_IO_BAUDRATE);
    CY_ASSERT(result == CY_RSLT_SUCCESS);

    printf("\r\n=================================\r\n");
    printf("实验2: IMU传感器数据采集\r\n");
    printf("传感器: BMI270 (6轴IMU)\r\n");
    printf("=================================\r\n\r\n");

    /* 初始化I2C */
    result = i2c_init();
    if (result != CY_RSLT_SUCCESS)
    {
        printf("I2C初始化失败!\r\n");
        CY_ASSERT(0);
    }
    printf("I2C初始化成功 (400kHz)\r\n");

    /* 初始化IMU */
    result = imu_init();
    if (result != CY_RSLT_SUCCESS)
    {
        printf("IMU初始化失败!\r\n");
        CY_ASSERT(0);
    }
    printf("IMU初始化成功\r\n\r\n");

    printf("开始采集数据...\r\n");
    printf("格式: [加速度(g)] [陀螺仪(dps)]\r\n\r\n");

    for (;;)
    {
        /* 读取并打印IMU数据 */
        imu_read_and_print();
  
        /* 每100ms采集一次 */
        cyhal_system_delay_ms(100);
    }
}

/*******************************************************************************
 * 函数: i2c_init
 * 功能: 初始化I2C接口
 ******************************************************************************/
cy_rslt_t i2c_init(void)
{
    cy_rslt_t result;
    cyhal_i2c_cfg_t i2c_config = 
    {
        .is_slave = false,
        .address = 0,
        .frequencyhal_hz = 400000  // 400kHz
    };

    /* 初始化I2C */
    result = cyhal_i2c_init(&i2c_obj, CYBSP_I2C_SDA, CYBSP_I2C_SCL, NULL);
    if (result != CY_RSLT_SUCCESS)
    {
        return result;
    }

    /* 配置I2C */
    result = cyhal_i2c_configure(&i2c_obj, &i2c_config);
  
    return result;
}

/*******************************************************************************
 * 函数: imu_init
 * 功能: 初始化BMI270传感器
 ******************************************************************************/
cy_rslt_t imu_init(void)
{
    cy_rslt_t result;

    /* 初始化BMI270 (使用默认地址0x68) */
    result = mtb_bmi270_init_i2c(&motion_sensor, &i2c_obj, 
                                  MTB_BMI270_ADDRESS_DEFAULT);
    if (result != CY_RSLT_SUCCESS)
    {
        return result;
    }

    /* 配置加速度计: 量程±4g, 采样率100Hz */
    mtb_bmi270_config_default(&motion_sensor);

    return CY_RSLT_SUCCESS;
}

/*******************************************************************************
 * 函数: imu_read_and_print
 * 功能: 读取并打印IMU数据
 ******************************************************************************/
void imu_read_and_print(void)
{
    cy_rslt_t result;
    mtb_bmi270_data_t data;

    /* 读取传感器数据 */
    result = mtb_bmi270_read(&motion_sensor, &data);
  
    if (result == CY_RSLT_SUCCESS)
    {
        /* 转换并打印加速度 (单位: g) */
        float ax = data.sensor_data.acc.x / 1000.0f;
        float ay = data.sensor_data.acc.y / 1000.0f;
        float az = data.sensor_data.acc.z / 1000.0f;
  
        /* 转换并打印角速度 (单位: dps) */
        float gx = data.sensor_data.gyr.x / 1000.0f;
        float gy = data.sensor_data.gyr.y / 1000.0f;
        float gz = data.sensor_data.gyr.z / 1000.0f;
  
        printf("加速度: X=%6.3f Y=%6.3f Z=%6.3f g | ", ax, ay, az);
        printf("陀螺仪: X=%7.2f Y=%7.2f Z=%7.2f dps\r\n", gx, gy, gz);
    }
    else
    {
        printf("读取失败\r\n");
    }
}

2.4 编译下载

bash

make build
make program

2.5 验证结果

转动开发板串口输出:

image.png

实验3: 环境监测站 - 气压+磁力计

目标: 添加更多I2C传感器,构建多传感器系统

3.1 新增传感器

传感器功能I2C地址
DPS368气压+温度0x77
BMM350三轴磁力计0x15

3.2 更新库依赖

修改 Makefile:

makefile

COMPONENTS=sensor-motion-bmi270 sensor-xensiv-dps3xx

⚠️ 注意: BMM350暂无官方库,本实验仅演示DPS368

运行:

bash

make getlibs

3.3 完整代码

/******************************************************************************
 * 文件名: main.c
 * 实验3: 环境监测站 (IMU + 气压计)
 *****************************************************************************/

 #if defined (CY_USING_HAL)
#include "cyhal.h"
#endif
#include "cybsp.h"

#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
#include "mtb_bmi270.h"
#include "xensiv_dps3xx_mtb.h"

/*******************************************************************************
 * 全局变量
 ******************************************************************************/
cyhal_i2c_t i2c_obj;
mtb_bmi270_t motion_sensor;
xensiv_dps3xx_t pressure_sensor;

/*******************************************************************************
 * 函数声明
 ******************************************************************************/
cy_rslt_t sensors_init(void);
void read_all_sensors(void);

/*******************************************************************************
 * 主函数
 ******************************************************************************/
int main(void)
{
    cy_rslt_t result;

    /* 初始化 */
    result = cybsp_init();
    CY_ASSERT(result == CY_RSLT_SUCCESS);
    __enable_irq();

    result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, 
                                  CYBSP_DEBUG_UART_RX,
                                  CY_RETARGET_IO_BAUDRATE);
    CY_ASSERT(result == CY_RSLT_SUCCESS);

    printf("\r\n");
    printf("╔════════════════════════════════════════╗\r\n");
    printf("║      实验3: 环境监测站                 ║\r\n");
    printf("║  传感器: IMU + 气压计                  ║\r\n");
    printf("╚════════════════════════════════════════╝\r\n\r\n");

    /* 初始化所有传感器 */
    result = sensors_init();
    if (result != CY_RSLT_SUCCESS)
    {
        printf("传感器初始化失败\r\n");
        CY_ASSERT(0);
    }

    printf("所有传感器初始化成功\r\n\r\n");
    printf("开始监测...\r\n\r\n");

    for (;;)
    {
        read_all_sensors();
        printf("\r\n");
        cyhal_system_delay_ms(1000);  // 每秒更新一次
    }
}

/*******************************************************************************
 * 函数: sensors_init
 * 功能: 初始化所有传感器
 ******************************************************************************/
cy_rslt_t sensors_init(void)
{
    cy_rslt_t result;
    cyhal_i2c_cfg_t i2c_config = {
        .is_slave = false,
        .address = 0,
        .frequencyhal_hz = 400000
    };

    /* 初始化I2C */
    printf("初始化I2C总线...\r\n");
    result = cyhal_i2c_init(&i2c_obj, CYBSP_I2C_SDA, CYBSP_I2C_SCL, NULL);
    if (result != CY_RSLT_SUCCESS) return result;
  
    result = cyhal_i2c_configure(&i2c_obj, &i2c_config);
    if (result != CY_RSLT_SUCCESS) return result;
  
    printf("I2C: 400kHz\r\n");

    /* 初始化IMU */
    printf("初始化IMU传感器...\r\n");
    result = mtb_bmi270_init_i2c(&motion_sensor, &i2c_obj,
                                  MTB_BMI270_ADDRESS_DEFAULT);
    if (result != CY_RSLT_SUCCESS)
    {
        printf("BMI270初始化失败\r\n");
        return result;
    }
    mtb_bmi270_config_default(&motion_sensor);
    printf("BMI270 @ 0x68\r\n");

    /* 初始化气压计 */
    printf("初始化气压传感器...\r\n");
    result = xensiv_dps3xx_mtb_init_i2c(&pressure_sensor, &i2c_obj, 
                                         XENSIV_DPS3XX_I2C_ADDR_DEFAULT);
    if (result != CY_RSLT_SUCCESS)
    {
        printf("DPS368初始化失败\r\n");
        return result;
    }
    printf("DPS368 @ 0x77\r\n");

    return CY_RSLT_SUCCESS;
}

/*******************************************************************************
 * 函数: read_all_sensors
 * 功能: 读取并显示所有传感器数据
 ******************************************************************************/
void read_all_sensors(void)
{
    /* 读取IMU */
    mtb_bmi270_data_t imu_data;
    if (mtb_bmi270_read(&motion_sensor, &imu_data) == CY_RSLT_SUCCESS)
    {
        float ax = imu_data.sensor_data.acc.x / 1000.0f;
        float ay = imu_data.sensor_data.acc.y / 1000.0f;
        float az = imu_data.sensor_data.acc.z / 1000.0f;
    
        printf("速度: X=%6.3f Y=%6.3f Z=%6.3f g\r\n", ax, ay, az);
    }

    /* 读取气压计 */
    float pressure, temperature;
    if (xensiv_dps3xx_read(&pressure_sensor, &pressure, &temperature) 
        == CY_RSLT_SUCCESS)
    {
        // 计算海拔高度
        float altitude = 44330.0f * (1.0f - powf(pressure / 101325.0f, 0.1903f));
    
        printf("温度: %.2f °C\r\n", temperature);
        printf("气压: %.2f hPa (%.1f Pa)\r\n", 
               pressure / 100.0f, pressure);
        printf("估算海拔: %.1f 米\r\n", altitude);
    }
}

3.4 验证结果

串口输出:

image.png

3.5 实验

实验操作观察
温度测试用手握住开发板温度逐渐上升
气压测试上下移动开发板海拔高度变化
运动检测快速晃动加速度突变

本帖子中包含更多资源

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

×
星辰大海不退缩 发表于 2025-10-27 22:34 | 显示全部楼层
传感器数据采集与处理
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:欢迎参与LabVIEW版块的讨论学习! 点我一键即达

341

主题

2938

帖子

45

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