这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » KIT-PSE84-AI开发指南【IMU姿态与磁力计数据可视化】

共1条 1/1 1 跳转至页

KIT-PSE84-AI开发指南【IMU姿态与磁力计数据可视化】

菜鸟
2026-11-10 23:57:00     打赏
一、硬件介绍

1、产品特点

PSOC E84 Edge AI KIT开发板配备双 CPU 内核(400 MHz Arm Cortex‑M55和200 MHz Arm Cortex‑M33),芯片集成图形音频模块、数字信号处理 DSP 单元、安全隔离区、高性能存储扩展等接口;

板载KitProg3编程调试器、SWD调试排针、6轴IMU传感器、3轴磁力计、气压传感器、温湿度传感器、雷达模块以及64MB QSPI Flash、16MB Octal RAM以及具有Wi‑Fi、蓝牙二合一的CYW55513无线模块模组;

979.png

image-20261030161259571


主要特性

  • 双核CPU:400MHz Cortex‑M55(高性能) + 200MHz Cortex‑M33(低功耗)

  • 支持1.8V、3.3V工作电压


主要原理图

9.png


二、功能效果

通过板载的6轴IMU、3轴磁力计采集相关数据,并通过IMU View插件将相关数据进行可视化3D效果显示;

IMU View

6轴IMU通过I2C方式进行连接

3轴磁力计通过I3C方式进行连接

6轴IMU (BMI270)

BMI270是一款低功耗IMU,IMU通过精准的加速度与角速度测量功能,结合智能化的片上运动触发中断特性,实现高效集成;


主要特性

加速度计(A):16位或0.06 mg/LSB (± 0.4%)

陀螺仪(G):16位或0.004 dps/LSB(± 0.4%)

52.png


3轴磁力计(BMM350)

BMM350是一款高性能、低功耗的16位3轴磁力计,该传感器基于Bosch Sensortec专有的TMR技术;


主要特性

± 190 nTrms(x、y轴)和 ± 450 nT rms(z轴)

灵敏度温度漂移:± -0.010 %/K

4.png

三、代码编写

在之前例程的基础上,继续添加相关传感器功能库;

在Library Manager中分别搜索 BMI270 和 BMM350 并添加到cm33_ns工程中;

5.png


在proj_cm33_ns的Makefile文件里,在对应的位置,添加以下内容;

使用COMPONENT_BMM350_I3C组件

COMPONENTS+=BMM350_I3C
PREBUILD=$(SEARCH_sensor-orientation-bmm350)/COMPONENT_BMM350_I3C/bmm350_fix.bash "$(SEARCH_BMM350_SensorAPI)/bmm350.c"

0.png


在cm33_ns中的main.c中编写相关代码

IMU View接收数据格式

字段长度说明
帧头 (Sync)2 字节固定为 0xAA 0xFF
加速度 (Accel)6 字节ax, ay, az,每个为 int16,小端字节序
陀螺仪 (Gyro)6 字节gx, gy, gz,每个为 int16,小端字节序
磁力计 (Mag)6 字节mx, my, mz,每个为 int16,小端字节序


#include "cy_pdl.h"
#include "cybsp.h"
#include "mtb_bmi270.h"
#include "mtb_bmm350.h"
#include "mtb_hal.h"
#include "retarget_io_init.h"
#include <inttypes.h>


/* BMI270 使用的 I2C 硬件及 HAL 对象 */
static mtb_hal_i2c_t CYBSP_I2C_CONTROLLER_hal_obj;
cy_stc_scb_i2c_context_t CYBSP_I2C_CONTROLLER_context;

/* BMM350 I3C 上下文 */
cy_stc_i3c_context_t CYBSP_I3C_CONTROLLER_context;

/* 传感器实例 */
mtb_bmi270_t bmi270;
mtb_bmm350_t magnetometer;


/* BMM350 I3C 中断服务函数 */
void CYBSP_I3C_CONTROLLER_Interrupt(void) {
  Cy_I3C_Interrupt(CYBSP_I3C_CONTROLLER_HW, &CYBSP_I3C_CONTROLLER_context);
}

/*
 * 功能:将 9 轴数据打包成 IMUView "Default 9-axis" 协议的20字节帧。
 * 格式:[0xAA 0xFF] + [ax ay az (6B)] + [gx gy gz (6B)] + [mx my mz (6B)]
 * 所有数据均为 int16 小端格式。
 */
void send_imu_frame(int16_t ax, int16_t ay, int16_t az, int16_t gx, int16_t gy,
                    int16_t gz, int16_t mx, int16_t my, int16_t mz) {
  uint8_t frame[20];

  // 帧头
  frame[0] = 0xAA;
  frame[1] = 0xFF;

  // 加速度计 (小端字节序)
  frame[2] = (uint8_t)(ax & 0xFF);
  frame[3] = (uint8_t)((ax >> 8) & 0xFF);
  frame[4] = (uint8_t)(ay & 0xFF);
  frame[5] = (uint8_t)((ay >> 8) & 0xFF);
  frame[6] = (uint8_t)(az & 0xFF);
  frame[7] = (uint8_t)((az >> 8) & 0xFF);

  // 陀螺仪 (小端字节序)
  frame[8] = (uint8_t)(gx & 0xFF);
  frame[9] = (uint8_t)((gx >> 8) & 0xFF);
  frame[10] = (uint8_t)(gy & 0xFF);
  frame[11] = (uint8_t)((gy >> 8) & 0xFF);
  frame[12] = (uint8_t)(gz & 0xFF);
  frame[13] = (uint8_t)((gz >> 8) & 0xFF);

  // 磁力计 (小端字节序)
  frame[14] = (uint8_t)(mx & 0xFF);
  frame[15] = (uint8_t)((mx >> 8) & 0xFF);
  frame[16] = (uint8_t)(my & 0xFF);
  frame[17] = (uint8_t)((my >> 8) & 0xFF);
  frame[18] = (uint8_t)(mz & 0xFF);
  frame[19] = (uint8_t)((mz >> 8) & 0xFF);

  // 使用 PDL 底层接口直接输出二进制流
  Cy_SCB_UART_PutArray(CYBSP_DEBUG_UART_HW, frame, 20);
}

/*
 * 功能:初始化 I2C 外设并配置 BMI270 传感器
 */
static cy_rslt_t init_bmi270(void) {
  cy_rslt_t result;
  cy_en_scb_i2c_status_t i2cStatus;

  // 初始化 I2C 硬件
  i2cStatus =
      Cy_SCB_I2C_Init(CYBSP_I2C_CONTROLLER_HW, &CYBSP_I2C_CONTROLLER_config,
                      &CYBSP_I2C_CONTROLLER_context);
  if (CY_SCB_I2C_SUCCESS != i2cStatus)
    return (cy_rslt_t)i2cStatus;

  Cy_SCB_I2C_Enable(CYBSP_I2C_CONTROLLER_HW);

  // 设置 HAL I2C 对象
  result = mtb_hal_i2c_setup(&CYBSP_I2C_CONTROLLER_hal_obj,
                             &CYBSP_I2C_CONTROLLER_hal_config,
                             &CYBSP_I2C_CONTROLLER_context, NULL);
  if (CY_RSLT_SUCCESS != result)
    return result;

  // 初始化 BMI270 驱动
  result = mtb_bmi270_init_i2c(&bmi270, &CYBSP_I2C_CONTROLLER_hal_obj,
                               MTB_BMI270_ADDRESS_DEFAULT);
  if (CY_RSLT_SUCCESS != result)
    return result;

  // 默认配置 (100Hz ODR, Accel ±4g, Gyro ±2000dps)
  return mtb_bmi270_config_default(&bmi270);
}

/*
 * 功能:初始化 I3C 外设并配置 BMM350 磁力计
 */
static cy_rslt_t init_bmm350(void) {
  cy_rslt_t result;
  cy_en_i3c_status_t i3cStatus;
  cy_en_sysint_status_t sysStatus;

  // 配置中断
  cy_stc_sysint_t irq_cfg = {.intrSrc = CYBSP_I3C_CONTROLLER_IRQ,
                             .intrPriority = 2UL};

  // I3C 从机静态地址
  cy_stc_i3c_device_t i3c_dev_addr = {.staticAddress = MTB_BMM350_ADDRESS_SEC};

  // 初始化 I3C 硬件
  i3cStatus = Cy_I3C_Init(CYBSP_I3C_CONTROLLER_HW, &CYBSP_I3C_CONTROLLER_config,
                          &CYBSP_I3C_CONTROLLER_context);
  if (CY_I3C_SUCCESS != i3cStatus)
    return (cy_rslt_t)i3cStatus;

  // 注册并使能 I3C 中断
  sysStatus = Cy_SysInt_Init(&irq_cfg, &CYBSP_I3C_CONTROLLER_Interrupt);
  if (CY_SYSINT_SUCCESS != sysStatus)
    return (cy_rslt_t)sysStatus;

  NVIC_EnableIRQ((IRQn_Type)irq_cfg.intrSrc);
  Cy_I3C_Enable(CYBSP_I3C_CONTROLLER_HW, &CYBSP_I3C_CONTROLLER_context);

  // 初始化 BMM350
  return mtb_bmm350_init_i3c(&magnetometer, CYBSP_I3C_CONTROLLER_HW,
                             &CYBSP_I3C_CONTROLLER_context, &i3c_dev_addr);
}


int main(void) {
  cy_rslt_t result;

  result = cybsp_init();
  if (CY_RSLT_SUCCESS != result) {
    CY_ASSERT(0);
  }
  __enable_irq();

  init_retarget_io();
  printf("System Init...\r\n");

  /* 初始化传感器 */
  if (CY_RSLT_SUCCESS != init_bmi270()) {
    printf("BMI270 init FAILED!\r\n");
    CY_ASSERT(0);
  }

  if (CY_RSLT_SUCCESS != init_bmm350()) {
    printf("BMM350 init FAILED!\r\n");
    CY_ASSERT(0);
  }

  Cy_SysLib_Delay(100); 

  /* 读取并发送数据 */
  for (;;) {
    mtb_bmi270_data_t bmi270_data;
    mtb_bmm350_data_t mag_data;

    // 读取 IMU 数据
    if (mtb_bmi270_read(&bmi270, &bmi270_data) != CY_RSLT_SUCCESS)
      continue;

    // 读取磁力计数据
    if (mtb_bmm350_read(&magnetometer, &mag_data) != CY_RSLT_SUCCESS)
      continue;

    // 提取原始数据
    int16_t ax = bmi270_data.sensor_data.acc.x;
    int16_t ay = bmi270_data.sensor_data.acc.y;
    int16_t az = bmi270_data.sensor_data.acc.z;
    int16_t gx = bmi270_data.sensor_data.gyr.x;
    int16_t gy = bmi270_data.sensor_data.gyr.y;
    int16_t gz = bmi270_data.sensor_data.gyr.z;

    // BMM350 浮点转 int16 (舍弃小数部分)
    int16_t mx = (int16_t)mag_data.sensor_data.x;
    int16_t my = (int16_t)mag_data.sensor_data.y;
    int16_t mz = (int16_t)mag_data.sensor_data.z;

    ax = -ax;
    gy = -gy;
    gz = -gz;

    // 打包发送
    send_imu_frame(ax, ay, az, gx, gy, gz, mx, my, mz);
    Cy_SysLib_Delay(10);
  }
}



四、程序烧录

1、连接设备至电脑端;

连接至开发板的J1 USB口(KitProg3)

2、选择Application页面的 Program 进行程序烧录;

Build:增量编译

Rebuild:重新编译

Clean:清空编译内容

Erase:擦除 Flash

Program:编译并烧录程序到开发板中

326.png


五、效果演示

左侧显示当前开发板具体运动情况

右侧显示对应的相关数据

13.png

2304.gif



IMU





共1条 1/1 1 跳转至页

回复

匿名不能发帖!请先 [ 登陆 注册 ]