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

[复制链接]
123|1
hbzjt2011 发表于 2025-10-27 13:37 | 显示全部楼层 |阅读模式
, , , , , CY8CKIT-062S2-AI
[i=s] 本帖最后由 hbzjt2011 于 2025-10-29 17:09 编辑 [/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 实验

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

实验4: 雷达存在检测 - 60GHz毫米波雷达

目标: 使用SPI接口的雷达传感器,实现人体存在检测

4.1 雷达原理简介

BGT60TR13C是一颗60GHz FMCW雷达:

  • 检测距离: 0.2m ~ 15m
  • 应用: 存在检测、运动检测
  • 接口: SPI (5MHz)

4.2 添加库

修改 Makefile:

makefile

COMPONENTS=sensor-xensiv-bgt60trxx

运行:

bash

make getlibs

4.3 实现代码

/*******************************************************************************
 * 文件名: main.c
 * 功能:60GHz 雷达人体存在检测
 *******************************************************************************/

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

#include "xensiv_bgt60trxx_mtb.h"
#include "xensiv_bgt60trxx.h"
#include "xensiv_radar_presence.h"

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

/*============================= 雷达配置 =============================*/
#define XENSIV_BGT60TRXX_CONF_NUM_REGS              (38)
#define XENSIV_BGT60TRXX_CONF_NUM_SAMPLES_PER_CHIRP (128)
#define XENSIV_BGT60TRXX_CONF_NUM_CHIRPS_PER_FRAME  (16)
#define XENSIV_BGT60TRXX_CONF_NUM_RX_ANTENNAS       (1)

static const uint32_t register_list[XENSIV_BGT60TRXX_CONF_NUM_REGS] = {
    0x11e8270UL, 0x3088210UL, 0x9e967fdUL, 0xb0805b4UL, 0xdf02fffUL,
    0xf010700UL, 0x11000000UL, 0x13000000UL, 0x15000000UL, 0x17000be0UL,
    0x19000000UL, 0x1b000000UL, 0x1d000000UL, 0x1f000b60UL, 0x21130c51UL,
    0x234ff41fUL, 0x25006f7bUL, 0x2d000490UL, 0x3b000480UL, 0x49000480UL,
    0x57000480UL, 0x5911be0eUL, 0x5b3ef40aUL, 0x5d00f000UL, 0x5f787e1eUL,
    0x61f5208cUL, 0x630000a4UL, 0x65000252UL, 0x67000080UL, 0x69000000UL,
    0x6b000000UL, 0x6d000000UL, 0x6f092910UL, 0x7f000100UL, 0x8f000100UL,
    0x9f000100UL, 0xad000000UL, 0xb7000000UL
};

#define XENSIV_BGT60TRXX_SPI_FREQUENCY      (25000000UL)
#define PIN_XENSIV_BGT60TRXX_SPI_SCLK       CYBSP_RSPI_CLK
#define PIN_XENSIV_BGT60TRXX_SPI_MOSI       CYBSP_RSPI_MOSI
#define PIN_XENSIV_BGT60TRXX_SPI_MISO       CYBSP_RSPI_MISO
#define PIN_XENSIV_BGT60TRXX_SPI_CS         CYBSP_RSPI_CS
#define PIN_XENSIV_BGT60TRXX_IRQ            CYBSP_RSPI_IRQ
#define PIN_XENSIV_BGT60TRXX_RSTN           CYBSP_RXRES_L

#define NUM_SAMPLES_PER_FRAME (XENSIV_BGT60TRXX_CONF_NUM_SAMPLES_PER_CHIRP * \
                               XENSIV_BGT60TRXX_CONF_NUM_CHIRPS_PER_FRAME * \
                               XENSIV_BGT60TRXX_CONF_NUM_RX_ANTENNAS)

#define GPIO_INTERRUPT_PRIORITY             (7)
#define FIFO_FAIL_THRESHOLD                 (5)   // 连续失败次数阈值

/*============================= 全局变量 =============================*/
static xensiv_bgt60trxx_mtb_t radar_obj;
static cyhal_spi_t spi_obj;

static uint16_t radar_buffer_raw[NUM_SAMPLES_PER_FRAME];
static float32_t radar_buffer_float[NUM_SAMPLES_PER_FRAME];
static volatile bool radar_data_ready = false;

static xensiv_radar_presence_handle_t presence_handle;
static xensiv_radar_presence_config_t presence_cfg;

static cyhal_timer_t timer_obj;    // 毫秒计时器
static uint8_t fifo_fail_count = 0;

/*============================= 毫秒计时器 =============================*/
static void timer_init(void)
{
    cyhal_timer_cfg_t timer_cfg = {
        .compare_value = 0,
        .period = 0xFFFFFFFF,
        .direction = CYHAL_TIMER_DIR_UP,
        .is_compare = false,
        .is_continuous = true,
        .value = 0
    };
    cyhal_timer_init(&timer_obj, NC, NULL);
    cyhal_timer_configure(&timer_obj, &timer_cfg);
    cyhal_timer_start(&timer_obj);
}

static uint32_t millis(void)
{
    return (uint32_t)cyhal_timer_read(&timer_obj);
}

/*============================= 算法回调 =============================*/
static void presence_callback(xensiv_radar_presence_handle_t handle,
                              const xensiv_radar_presence_event_t* event,
                              void* data)
{
    CY_UNUSED_PARAMETER(handle);
    CY_UNUSED_PARAMETER(data);

    const char* state_str = "未知状态";
    switch (event->state)
    {
        case XENSIV_RADAR_PRESENCE_STATE_ABSENCE: state_str = "无目标"; break;
        case XENSIV_RADAR_PRESENCE_STATE_MACRO_PRESENCE: state_str = "宏动作检测"; break;
        case XENSIV_RADAR_PRESENCE_STATE_MICRO_PRESENCE: state_str = "微动作检测"; break;
        default: break;
    }

    printf("[%04lu ms] %-12s | 距离 bin: %ld | 阈值: M=%.2f µ=%.2f\r\n",
           (unsigned long)event->timestamp,
           state_str,
           (long)event->range_bin,
           presence_cfg.macro_threshold,
           presence_cfg.micro_threshold);
}

/*============================= 中断回调 =============================*/
static void radar_interrupt_handler(void *callback_arg, cyhal_gpio_event_t event)
{
    int32_t status;

    status = xensiv_bgt60trxx_get_fifo_data(&radar_obj.dev,
                                            radar_buffer_raw,
                                            NUM_SAMPLES_PER_FRAME);
    if(status == XENSIV_BGT60TRXX_STATUS_OK)
    {
        for(size_t i=0;i<NUM_SAMPLES_PER_FRAME;i++)
            radar_buffer_float[i] = (float32_t)radar_buffer_raw[i];

        radar_data_ready = true;
        fifo_fail_count = 0;
    }
    else
    {
        fifo_fail_count++;
        printf(">>> 中断触发但 FIFO 读取失败: %ld (连续 %d 次)\r\n", (long)status, fifo_fail_count);

        if(fifo_fail_count >= FIFO_FAIL_THRESHOLD)
        {
            printf(">>> 连续 FIFO 读取失败,重启帧采集\r\n");
            xensiv_bgt60trxx_start_frame(&radar_obj.dev, true);
            fifo_fail_count = 0;
        }
    }
}

/*============================= 函数声明 =============================*/
static cy_rslt_t radar_init(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);

    timer_init(); // 初始化毫秒计时器

    printf("\r\n");
    printf("╔════════════════════════════════════════╗\r\n");
    printf("║        实验4: 60GHz 雷达存在检测        ║\r\n");
    printf("╚════════════════════════════════════════╝\r\n\r\n");

    printf("正在初始化雷达及算法...\r\n");
    result = radar_init();
    if (result != CY_RSLT_SUCCESS)
    {
        printf("雷达初始化失败: 0x%08lX\r\n", (unsigned long)result);
        for (;;);
    }

    printf("雷达及算法初始化成功\r\n\r\n");
    printf("开始检测... 请在开发板前方移动手臂或物体\r\n\r\n");
    printf("进入主循环\r\n");

    while(1)
    {
        cyhal_system_delay_ms(5);
        if(radar_data_ready)
        {
            radar_data_ready = false;
            // printf(">>> 处理新帧\r\n");
            xensiv_radar_presence_process_frame(presence_handle,
                                                radar_buffer_float,
                                                (XENSIV_RADAR_PRESENCE_TIMESTAMP)millis());
        }
    }
}

/*============================= 雷达初始化 =============================*/
static cy_rslt_t radar_init(void)
{
    cy_rslt_t result;
    int32_t status;

    // 1. SPI 初始化
    printf("Step 1: 初始化 SPI...\r\n");
    result = cyhal_spi_init(&spi_obj,
                       PIN_XENSIV_BGT60TRXX_SPI_MOSI,
                       PIN_XENSIV_BGT60TRXX_SPI_MISO,
                       PIN_XENSIV_BGT60TRXX_SPI_SCLK,
                       NC,
                       NULL,
                       8,
                       CYHAL_SPI_MODE_00_MSB,
                       false);
    if(result != CY_RSLT_SUCCESS)
        return result;

    Cy_GPIO_SetSlewRate(CYHAL_GET_PORTADDR(PIN_XENSIV_BGT60TRXX_SPI_MOSI), CYHAL_GET_PIN(PIN_XENSIV_BGT60TRXX_SPI_MOSI), CY_GPIO_SLEW_FAST);
    Cy_GPIO_SetDriveSel(CYHAL_GET_PORTADDR(PIN_XENSIV_BGT60TRXX_SPI_MOSI), CYHAL_GET_PIN(PIN_XENSIV_BGT60TRXX_SPI_MOSI), CY_GPIO_DRIVE_1_8);
    Cy_GPIO_SetSlewRate(CYHAL_GET_PORTADDR(PIN_XENSIV_BGT60TRXX_SPI_SCLK), CYHAL_GET_PIN(PIN_XENSIV_BGT60TRXX_SPI_SCLK), CY_GPIO_SLEW_FAST);
    Cy_GPIO_SetDriveSel(CYHAL_GET_PORTADDR(PIN_XENSIV_BGT60TRXX_SPI_SCLK), CYHAL_GET_PIN(PIN_XENSIV_BGT60TRXX_SPI_SCLK), CY_GPIO_DRIVE_1_8);

    result = cyhal_spi_set_frequency(&spi_obj, XENSIV_BGT60TRXX_SPI_FREQUENCY);
    if(result != CY_RSLT_SUCCESS)
        return result;

    printf("SPI 初始化完成\r\n");

    // 2. 雷达驱动初始化
    printf("Step 2: 初始化雷达...\r\n");
    result = xensiv_bgt60trxx_mtb_init(&radar_obj,
                                       &spi_obj,
                                       PIN_XENSIV_BGT60TRXX_SPI_CS,
                                       PIN_XENSIV_BGT60TRXX_RSTN,
                                       register_list,
                                       XENSIV_BGT60TRXX_CONF_NUM_REGS);
    if(result != CY_RSLT_SUCCESS)
        return result;
    printf("雷达初始化完成\r\n");

    // 3. 中断初始化
    printf("Step 3: 配置中断...\r\n");
    result = xensiv_bgt60trxx_mtb_interrupt_init(&radar_obj,
                                                 NUM_SAMPLES_PER_FRAME,
                                                 PIN_XENSIV_BGT60TRXX_IRQ,
                                                 GPIO_INTERRUPT_PRIORITY,
                                                 radar_interrupt_handler,
                                                 NULL);
    if(result != CY_RSLT_SUCCESS)
        return result;
    printf("中断初始化完成\r\n");

    // 4. Presence 算法初始化
    printf("Step 4: 初始化 Presence 算法...\r\n");
    xensiv_radar_presence_init_config(&presence_cfg);
    presence_cfg.max_range_bin   = 200;
    presence_cfg.macro_threshold = 0.5f;
    presence_cfg.micro_threshold = 12.5f;
    presence_cfg.mode            = XENSIV_RADAR_PRESENCE_MODE_MICRO_IF_MACRO;

    status = xensiv_radar_presence_alloc(&presence_handle, &presence_cfg);
    if(status != XENSIV_RADAR_PRESENCE_OK)
        return (cy_rslt_t)status;

    xensiv_radar_presence_set_callback(presence_handle, presence_callback, NULL);
    printf("Presence 算法初始化完成\r\n");

    // 5. 启动帧采集
    printf("Step 5: 启动帧采集...\r\n");
    result = xensiv_bgt60trxx_start_frame(&radar_obj.dev, true);
    if(result != CY_RSLT_SUCCESS)
        return result;

    printf("帧采集启动完成\r\n");
    return CY_RSLT_SUCCESS;
}

4.3 编译下载

bash

make build
make program

4.4 串口输出

image.png

该部分内容的数据处理还可以进一步进行优化处理,具体参考官方示例:

https://github.com/Infineon/mtb-example-psoc6-radar-presence/tree/master

本帖子中包含更多资源

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

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

本版积分规则

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

345

主题

2946

帖子

45

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