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

Intel® Quark™ SE Microcontroller C1000 开发套件 - 加速计教程

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2017年1月16日

CPOL

4分钟阅读

viewsIcon

19112

使用 Intel® Quark™ 微控制器软件接口 (Intel® QMSI),此示例应用程序读取加速度计数据并将其输出到串行端口。

获取 Grove* IoT 商业开发套件,这是一个完整的硬件和软件解决方案,可让专业开发人员使用最新的 Intel® 板卡创建激动人心且可扩展的新型 IoT 解决方案。请访问 Intel® 物联网开发者中心

Intel® System Studio for Microcontrollers 包含多个示例应用程序,可帮助您快速掌握其基本功能并熟悉 Intel® Quark™ 微控制器软件接口 (Intel® QMSI)。此示例应用程序读取加速度计数据并将其输出到串行端口。

要求

说明

  1. 将 USB 数据线连接到开发板和主机 PC

    注意:这是连接到 FTDI 芯片的 USB 端口

  2. 启动 Intel® System Studio for Microcontrollers IDE。
  3. 使用“Accelerometer”示例项目文件创建一个项目

    • 从“文件”菜单中,选择“新建”,然后选择“Intel Project for Microcontrollers”。
    • 按照“创建新项目”屏幕进行操作

      • 开发板:Intel® Quark™ SE C1000 开发板
      • 项目类型:Intel® QMSI (1.1)
      • 核心:传感器子系统
      • 项目名称:Accelerometer,位于“Developer Board Sensors”文件夹中
  4. 单击完成。

    注意:“Accelerometer”示例应用程序运行在传感器子系统核心上,该核心不支持 IPP 库。因此,无法使用 IPP 库构建此示例应用程序。

  5. 配置串行终端窗口以查看传感器输出。此窗口将通过串行电缆通过 UART 接口显示您的加速度计传感器数据。

    • 在屏幕右下角选择“Serial Terminal”窗格,然后单击加号 + 图标以打开新的串行终端连接

    • 确保选择了正确的串行端口;还可以单击“Custom configuration”菜单修改默认的串行连接设置

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

      • Linux*:使用 ‘dmesg’ 命令查看您的端口状态。
      • Windows*:打开设备管理器查看“端口 (COM & LPT)”状态。

        使用以上任一方法,您可以将 USB 数据线从 PC 上拔下并重新连接,以查看板卡对应的 COM 端口。

    • 单击“确定”,连接到串行终端即可建立。您应该在串行控制台中看到“Connected”状态。

      注意:如果您关闭串行终端窗口,可以从以下位置重新打开:
      Window › Show View › Other › Intel ISSM › Serial Terminal

  6. 构建并部署您的项目。

    1. 在“Project Explorer”中选择“Accelerometer”项目。
    2. 单击Build按钮编译项目。
    3. Run下拉列表中,选择“Accelerometer (flashing)”。
      注意:您也可以进行部署和调试。从Debug下拉列表中,选择“Accelerometer (flashing)”。

    4. 现在您可以在串行终端窗口中查看加速度计的 X、Y 和 Z 值。

工作原理

加速度计示例使用板载 Bosch BMC160 加速度计,通过 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 闹钟的 `callback` 函数。它用于定期打印加速度计数据。

接下来,代码通过 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)配置加速度计参数

	/* 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 */

接下来设置 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");
       }

`callback` 函数检查是否已读取定义的样本数量,如果未读取,则重置 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;
}

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

/*
* {% copyright %}
*/

/*
* 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 <unistd.h>
#if (__IPP_ENABLED__)
#include <dsp.h>
#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.