65.9K
CodeProject 正在变化。 阅读更多。
Home

Intel® Quark™ Microcontroller D2000 - 加速计教程

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2016年9月8日

CPOL

5分钟阅读

viewsIcon

18954

此示例应用程序读取加速度计数据并将其输出到串行端口,同时使用 Intel® 集成性能基元微控制器库(DSP 函数)计算最后 15 个 Z 轴读数的均方根、方差和平均值。

获取新的 Intel® 物联网开发者套件,这是一个完整的软硬件解决方案,使开发人员能够使用 Intel® Galileo 和 Intel® Edison 主板创建令人兴奋的新解决方案。请访问 Intel® 物联网开发者中心

Intel® System Studio for Microcontrollers 包含多个示例,可帮助您快速掌握其基本功能并熟悉 Intel® Quark™ Microcontroller Software Interface (Intel® QMSI)。此示例应用程序读取加速度计数据并将其输出到串行端口,同时使用 Intel® 集成性能基元微控制器库(DSP 函数)计算最后 15 个 Z 轴读数的均方根、方差和平均值。

要求

说明

  1. 通过以下配置连接 FTDI 数据线进行串行输出:
    • 将串行数据线的 GND(黑色)连接到主板的 GND 引脚。
    • 将串行数据线的 TXD(橙色)连接到主板的 RX 引脚。
    • 将串行数据线的 RXD(黄色)连接到主板的 TX 引脚。
  2. 启动 Intel ® System Studio for Microcontrollers IDE。
  3. 使用“加速度计”示例项目文件创建一个项目,如下所示:
    1. 从 **文件** 菜单中,选择 **新建**,然后选择 **Intel Project for Microcontrollers**。此时会显示“创建新项目”向导。
    2. 在“创建新项目”向导中指定以下值:
      • 开发板: **Intel® Quark™ D2000 Developer Board**
      • 项目类型: **Intel® QMSI (1.1)**
      • 连接类型: **USB-Onboard**
      • 项目名称: **Accelerometer**
  4. 点击 **完成。**
  5. 设置串行终端视图以查看传感器输出。此窗口将通过串行数据线通过 UART 接口显示加速度计的传感器数据。

    提示: 端口会因使用的串行硬件而异,并且可能列出多个端口。有几种方法可以检查您的端口。

    注意: 如果关闭了“串行终端”窗口,可以通过选择 **窗口 > 显示视图 > 其他 > Intel ISSM > 串行终端** 重新打开它。

    1. 在窗口的右下角,选择“串行终端”选项卡,然后点击 ISSM Window Serial Terminal Add icon 图标以打开新的串行终端连接。
    2. 确保已选择正确的串行端口。您还可以点击“自定义配置”菜单来修改默认的串行连接设置。
      • 断开 FTDI 数据线与 PC 的连接,并刷新“打开串行终端”窗口以确定哪个 COM 端口是活动的。
      • Linux*:使用 ‘dmesg’ 命令查看端口状态。
      • Windows*:打开设备管理器查看端口(COM 和 LPT)状态。
      • 点击 **确定**,串行终端的连接即建立。您应该在串行控制台中看到“已连接”状态。
  6. 构建并部署您的项目。

    注意: 您也可以部署和调试。从 **调试** ISSM Window Debug drop-down list 下拉列表中,选择“Accelerometer (flashing)”。

    1. 在“项目浏览器”中选择“Accelerometer”项目。
    2. 点击 **构建** ISSM Window Build button 按钮来编译您的项目。
    3. 从 **运行** ISSM Window Run drop-down list 下拉列表中,选择“Accelerometer (flashing)”。
    4. 在终端中查看加速度计的 X、Y 和 Z 值。

工作原理

加速度计示例使用板载 Bosch BMC150 加速度计,该加速度计通过 I2C 接口连接到微控制器,并使用 Intel® Quark™ 微控制器中集成的 RTC(实时时钟)。它还使用集成的 UART 模块通过串行端口输出数据。

示例从 main 函数开始,在 rtc 配置结构中设置 RTC 参数。

      /* Configure the RTC and request the IRQ. */
      rtc.init_val = 0;
      rtc.alarm_en = true;
      rtc.alarm_val = INTERVAL;
      rtc.callback = accel_callback;
      rtc.callback_data = NULL;

此配置启用了 RTC 警报,并将 accel_callback 设置为 RTC 警报的回调函数。它用于定期打印加速度计数据。

接下来,代码使用 QMSI API 调用请求 RTC 中断,并启用 RTC 时钟。

      qm_irq_request(QM_IRQ_RTC_0, qm_rtc_isr_0);

      /* Enable the RTC. */
      clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK);

之后,它根据加速度计类型(BMC150 或 BMI160)配置加速度计参数。

#if (QUARK_D2000)
      cfg.pos = BMC150_J14_POS_0;
#endif /* QUARK_D2000 */

       /* Initialise the sensor config and set the mode. */
      bmx1xx_init(cfg);
      bmx1xx_accel_set_mode(BMX1XX_MODE_2G);

#if (BMC150_SENSOR)
       bmx1xx_set_bandwidth(BMC150_BANDWIDTH_64MS); /* Set the bandwidth. */
#elif(BMI160_SENSOR)
       bmx1xx_set_bandwidth(BMI160_BANDWIDTH_10MS); /* Set the bandwidth. */
#endif /* BMC150_SENSOR */

cfs.pos 参数用于配置 BMC150 加速度计的加速度计地址。Intel® Quark™ Microcontroller D2000 Developer Kit 主板有一个跳线,允许更改地址。BMC150_J14_POS_0 是默认(无跳线,I2C 地址 0x10)配置。

接下来,设置 RTC 配置,从而启用 RTC 警报。

       /* Start the RTC. */
      qm_rtc_set_config(QM_RTC_0, &rtc); 

使用 while 循环等待读取并打印到串行控制台输出的定义数量的加速度计样本。

       /* Wait for the correct number of samples to be read. */
       while (!complete)
       ;

每次达到 125 毫秒间隔并触发 RTC 警报时,都会调用以下 accel_callback 函数。在函数开头定义的 accel 数据结构被传递到 bmx1xx_read_accel 函数中,该函数用当前读取的加速度计数据填充它。如果读取成功,则将加速度计数据打印到串行控制台输出;否则,打印错误消息。

/* Accel callback will run every time the RTC alarm triggers. */
static void accel_callback(void *data)
{
       bmx1xx_accel_t accel = {0};

       if (0 == bmx1xx_read_accel(&accel)) {
              QM_PRINTF("x %d y %d z %d\n", accel.x, accel.y, accel.z);
       } else {
              QM_PUTS("Error: unable to read from sensor");
       }

如果启用了 IPP(在示例应用程序中默认启用),它将通过调用 print_axis_stats 函数打印 Z 轴的统计信息。(请参阅下面的 print_axis_stats 函数说明。)

#if (__IPP_ENABLED__)
       print_axis_stats(accel.z);
#endif /* __IPP_ENABLE__ */

回调函数检查是否已读取定义的样本数量;如果没有,则重置 RTC 警报并递增计数,否则将 complete 变量设置为 true。

       /* Reset the RTC alarm to fire again if necessary. */
       if (cb_count < NUM_SAMPLES) {
              qm_rtc_set_alarm(QM_RTC_0,
                            (QM_RTC[QM_RTC_0].rtc_ccvr + INTERVAL));
              cb_count++;
       } else {
              complete = true;
       }

请注意,默认情况下,该应用程序在退出前读取 500 个样本(NUM_SAMPLES)。

最后,当 complete 变量设置为 true 时,while 循环退出,应用程序将最终语句打印到串行控制台输出,然后退出。

       QM_PUTS("Finished: Accelerometer example app");

       return 0;
}

Intel® 集成性能基元微控制器库

Intel® 集成性能基元微控制器库是一系列用于 x86 微控制器的信号和数据处理应用程序的构建模块。Intel® IPP 提供 Intel® IPP 经典样式 API 和通用 DSP 样式 API;此应用程序使用 DSP 样式 API 开发,以演示 Intel® IPP for Microcontrollers 在 DSP 用例中的用法。有关 Intel® IPP 的更多信息,请参阅 Intel® System Studio for Microcontrollers 用户和参考指南

print_axis_stats 函数使用 Intel IPP(Intel® 集成性能基元)库打印最后 15 个(由 NUM_SAMPLES 设置)Z 轴读数的统计信息。

首先,它使用新的 Z 轴样本更新 samples 数组,并在需要时更新样本计数。

static void print_axis_stats(int16_t value)
{
       static uint32_t index = 0;
       static uint32_t count = 0;
       float32_t mean, var, rms;

       /* Overwrite the oldest sample in the array. */
       samples[index] = value;
       /* Move the index on the next position, wrap around if necessary. */
       index = (index + 1) % SAMPLES_SIZE;

       /* Store number of samples until it reaches SAMPLES_SIZE. */
       count = count == SAMPLES_SIZE ? SAMPLES_SIZE : count + 1;

接下来,它使用 ippsq 统计函数计算并打印收集样本的均方根、方差和平均值。

/* Get the root mean square (RMS), variance and mean. */
       ippsq_rms_f32(samples, count, &rms);
       ippsq_var_f32(samples, count, &var);
       ippsq_mean_f32(samples, count, &mean);

       QM_PRINTF("rms %d var %d mean %d\n", (int)rms, (int)var, (int)mean);
}

加速度计示例应用程序代码

/*
* Copyright (c) 2016, Intel Corporation
* All rights reserved.
*/
 
/*
* QMSI Accelerometer app example.
*
* This app will read the accelerometer data from the onboard BMC150/160 sensor
* and print it to the console every 125 milliseconds. The app will complete
* once it has read 500 samples.
*
* If the app is compiled with the Intel(R) Integrated Performance Primitives
* (IPP) library enabled, it will also print the Root Mean Square (RMS),
* variance and mean of the last 15 samples each time.
*/

#include 
#if (__IPP_ENABLED__)
#include 
#endif
#include "clk.h"
#include "qm_interrupt.h"
#include "qm_isr.h"
#include "qm_rtc.h"
#include "qm_uart.h"
#include "bmx1xx/bmx1xx.h"

#define INTERVAL (QM_RTC_ALARM_SECOND >> 3) /* 125 milliseconds. */
#define NUM_SAMPLES (500)
#if (__IPP_ENABLED__)
/* Number of samples to use to generate the statistics from. */
#define SAMPLES_SIZE (15)
#endif /* __IPP_ENABLED__ */

static volatile uint32_t cb_count = 0;
static volatile bool complete = false;

#if (__IPP_ENABLED__)
static float32_t samples[SAMPLES_SIZE];

static void print_axis_stats(int16_t value)
{
      static uint32_t index = 0;
      static uint32_t count = 0;
      float32_t mean, var, rms;

      /* Overwrite the oldest sample in the array. */
      samples[index] = value;
      /* Move the index on the next position, wrap around if necessary. */
      index = (index + 1) % SAMPLES_SIZE;

      /* Store number of samples until it reaches SAMPLES_SIZE. */
      count = count == SAMPLES_SIZE ? SAMPLES_SIZE : count + 1;

      /* Get the root mean square (RMS), variance and mean. */
      ippsq_rms_f32(samples, count, &rms);
      ippsq_var_f32(samples, count, &var);
      ippsq_mean_f32(samples, count, &mean);

      QM_PRINTF("rms %d var %d mean %d\n", (int)rms, (int)var, (int)mean);
}
#endif /* __IPP_ENABLE__ */

/* Accel callback will run every time the RTC alarm triggers. */
static void accel_callback(void *data)
{
      bmx1xx_accel_t accel = {0};

      if (0 == bmx1xx_read_accel(&accel)) {
            QM_PRINTF("x %d y %d z %d\n", accel.x, accel.y, accel.z);
      } else {
            QM_PUTS("Error: unable to read from sensor");
      }

#if (__IPP_ENABLED__)
      print_axis_stats(accel.z);
#endif /* __IPP_ENABLE__ */

      /* Reset the RTC alarm to fire again if necessary. */
      if (cb_count < NUM_SAMPLES) {
            qm_rtc_set_alarm(QM_RTC_0,
                        (QM_RTC[QM_RTC_0].rtc_ccvr + INTERVAL));
            cb_count++;
      } else {
            complete = true;
      }
}

int main(void)
{
      qm_rtc_config_t rtc;
      bmx1xx_setup_config_t cfg;

      QM_PUTS("Starting: Accelerometer example app");

      /* Configure the RTC and request the IRQ. */
      rtc.init_val = 0;
      rtc.alarm_en = true;
      rtc.alarm_val = INTERVAL;
      rtc.callback = accel_callback;
      rtc.callback_data = NULL;

      qm_irq_request(QM_IRQ_RTC_0, qm_rtc_isr_0);

      /* Enable the RTC. */
      clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK);

#if (QUARK_D2000)
      cfg.pos = BMC150_J14_POS_0;
#endif /* QUARK_D2000 */

      /* Initialise the sensor config and set the mode. */
      bmx1xx_init(cfg);
      bmx1xx_accel_set_mode(BMX1XX_MODE_2G);

#if (BMC150_SENSOR)
      bmx1xx_set_bandwidth(BMC150_BANDWIDTH_64MS); /* Set the bandwidth. */
#elif(BMI160_SENSOR)
      bmx1xx_set_bandwidth(BMI160_BANDWIDTH_10MS); /* Set the bandwidth. */
#endif /* BMC150_SENSOR */

      /* Start the RTC. */
      qm_rtc_set_config(QM_RTC_0, &rtc);

      /* Wait for the correct number of samples to be read. */
      while (!complete)
            ;

      QM_PUTS("Finished: Accelerometer example app");

      return 0;
}
© . All rights reserved.