你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32C031 评测】I2C 接口读取KX224传感器数据

[复制链接]
andey 发布时间:2024-3-14 15:50

我们可以使用Arduino IDE和相关的STM32开发板来进行STM32的开发。STM32是一系列由STMicroelectronics开发的32位ARM Cortex-M微控制器,而Arduino是一个开源电子原型平台,提供了简单易用的开发环境和库函数,因此两者结合可以为开发者提供便利。要在Arduino IDE中使用STM32开发板,首先需要安装STM32的支持库和板支持文件。你可以通过添加额外的硬件支持来安装STM32支持。

在”文件-》首选项-》其他开发板管理器地址“ 添加如下url即可更新STM32的支持包。

arduino.png

https://github.com/stm32duino/BoardManagerFiles/raw/master/package_stmicroelectronics_index.json

更新过程会持续短时间更新完即可使用了。

创建工程后会自动创建如下两个函数由于初始化及循环调用处理,对应的注释能看出这两函数需要填充的内容。

start_up.png

这两个接口是何时被调用的,我们查看stm32 对应的固件代码对应的入口函数就知道了,以上俩函数的调用位置(C:\Users\Administrator\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.7.1\cores\arduino\main.cpp)。


#define ARDUINO_MAIN
#include "Arduino.h"

// Force init to be called *first*, i.e. before static object allocation.
// Otherwise, statically allocated objects that need HAL may fail.
__attribute__((constructor(101))) void premain()
{

  // Required by FreeRTOS, see http://www.freertos.org/RTOS-Cortex-M3-M4.html
#ifdef NVIC_PRIORITYGROUP_4
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
#endif
#if (__CORTEX_M == 0x07U)
  // Defined in CMSIS core_cm7.h
#ifndef I_CACHE_DISABLED
  SCB_EnableICache();
#endif
#ifndef D_CACHE_DISABLED
  SCB_EnableDCache();
#endif
#endif

  init();
}

/*
 * \brief Main entry point of Arduino application
 */
int main(void)
{
  initVariant();

  setup();

  for (;;) {
#if defined(CORE_CALLBACK)
    CoreCallback();
#endif
    loop();
    serialEventRun();
  }

  return 0;
}

添加测试代码读取I2C寄存器

选择硬件为STM32C031C6,添加如下测试代码访问I2C读取传感器数据。

/*
  DigitalReadSerial

  Reads a digital input on pin 2, prints the result to the Serial Monitor

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/DigitalReadSerial
*/
#include <Wire.h>

#define KX224_DEVICE_ADDRESS_1E   (0x1E)    // 7bit Addrss
#define KX224_DEVICE_ADDRESS_1F   (0x1F)    // 7bit Address
#define KX224_WAI_VAL             (0x2B)

#define KX224_XOUT_L              (0x06)
#define KX224_WHO_AM_I            (0x0F)
#define KX224_CNTL1               (0x18)
#define KX224_ODCNTL              (0x1B)

#define KX224_CNTL1_TPE           (1 << 0)
#define KX224_CNTL1_WUFE          (1 << 1)
#define KX224_CNTL1_TDTE          (1 << 2)
#define KX224_CNTL1_GSELMASK      (0x18)
#define KX224_CNTL1_GSEL_8G       (0x00)
#define KX224_CNTL1_GSEL_16G      (0x08)
#define KX224_CNTL1_GSEL_32G      (0x10)
#define KX224_CNTL1_DRDYE         (1 << 5)
#define KX224_CNTL1_RES           (1 << 6)
#define KX224_CNTL1_PC1           (1 << 7)

#define KX224_ODCNTL_OSA_50HZ     (2)
#define KX224_ODCNTL_LPRO         (1 << 6)
#define KX224_IIR_BYPASS          (1 << 7)

#define KX224_CNTL1_VAL           (KX224_CNTL1_RES | KX224_CNTL1_GSEL_8G)
#define KX224_ODCNTL_VAL          (KX224_ODCNTL_OSA_50HZ)

unsigned short _g_sens = 4096;



byte kx224_read(unsigned char memory_address, unsigned char *data, int size)
{
  byte rc;
  unsigned char cnt;

  Wire.beginTransmission(KX224_DEVICE_ADDRESS_1E);
  Wire.write(memory_address);
  rc = Wire.endTransmission(false);
  if (rc != 0) {
    return (rc);
  }

  Wire.requestFrom(KX224_DEVICE_ADDRESS_1E, size, true);
  cnt = 0;
  while(Wire.available()) {
    data[cnt] = Wire.read();
    cnt++;
  }

  return (0);
}

byte kx224_write(unsigned char memory_address, unsigned char *data, unsigned char size)
{
  byte rc;

  Wire.beginTransmission(KX224_DEVICE_ADDRESS_1E);
  Wire.write(memory_address);
  Wire.write(data, size);
  rc = Wire.endTransmission(true);
  return (rc);
}

byte kx224_get_rawval(unsigned char *data)
{
  byte rc;

  rc = kx224_read(KX224_XOUT_L, data, 6);
  if (rc != 0) {
    Serial.println(F("Can't get KX224 accel value"));
  }

  return (rc);
}

byte kx224_get_val(float *data)
{
  byte rc;
  unsigned char val[6];
  signed short acc[3];

  rc = kx224_get_rawval(val);
  if (rc != 0) {
    return (rc);
  }

  acc[0] = ((signed short)val[1] << 8) | (val[0]);
  acc[1] = ((signed short)val[3] << 8) | (val[2]);
  acc[2] = ((signed short)val[5] << 8) | (val[4]);

  // Convert LSB to g
  data[0] = (float)acc[0] / _g_sens;
  data[1] = (float)acc[1] / _g_sens;
  data[2] = (float)acc[2] / _g_sens;

  return (rc);  
}


// the setup routine runs once when you press reset:
void setup() {
  unsigned char reg = 0;
  unsigned char rc = 0;
  unsigned char gsel;

  // initialize serial communication at 9600 bits per second:
  Serial.begin(115200);
  Wire.begin();
  rc = kx224_read(KX224_WHO_AM_I, ®, sizeof(reg));
  if (rc != 0) {
    Serial.println(F("Can't access KX224"));
    Serial.println(rc);
  }
  Serial.print(F("KX224_WHO_AMI Register Value = 0x"));
  Serial.println(reg, HEX);

  if (reg != KX224_WAI_VAL) {
    Serial.println(F("Can't find KX224"));
    return;
  }

  reg = KX224_ODCNTL_VAL;
  rc = kx224_write(KX224_ODCNTL, ®, sizeof(reg));
  if (rc != 0) {
    Serial.println("Can't write KX224 ODCNTL register");
    return;
  }

  rc = kx224_read(KX224_CNTL1, ®, sizeof(reg));
  if (rc != 0) {
    Serial.println(F("Can't read KX224 CNTL1 register"));
    return;
  }

  gsel = reg & KX224_CNTL1_GSELMASK;

  reg |= KX224_CNTL1_PC1;
  rc = kx224_write(KX224_CNTL1, ®, sizeof(reg));
  if (rc != 0) {
    Serial.println(F("Can't write KX224 CNTL1 register at second"));
    return;
  }
  switch(gsel) {
    case KX224_CNTL1_GSEL_8G :
      // (Equivalent counts) / (Range) = (32768 / 8)
      _g_sens = 4096;
    break;

    case KX224_CNTL1_GSEL_16G :
      // (Equivalent counts) / (Range) = (32768 / 16)
      _g_sens = 2048;
    break;

    case KX224_CNTL1_GSEL_32G :
      // (Equivalent counts) / (Range) = (32768 / 32)
      _g_sens = 1024;
    break;

    default:
    break;
  }
}

// the loop routine runs over and over again forever:
void loop() {
  byte rc;
  float acc[3];

  rc = kx224_get_val(acc);
  if (rc == 0) {
    Serial.write("KX224 (X) = ");
    Serial.print(acc[0]);
    Serial.println(" [g]");
    Serial.write("KX224 (Y) = ");
    Serial.print(acc[1]);
    Serial.println(" [g]");
    Serial.write("KX224 (Z) = ");
    Serial.print(acc[2]);
    Serial.println(" [g]");
    Serial.println();
  }

  delay(500);
}

setup 函数内添加串口波特率设置及KX224传感器参数配置,loop 接口内周期读取传感器数据并打印。固件的I2C接口使用的GPIO端口是多少,这个从固件库的配置文件(C:\Users\Administrator\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.7.1\variants\STM32C0xx\C031C(4-6)(T-U)\variant_NUCLEO_C031C6.h)中找到答案,默认使用的是PB8/9这组,理论上用户也可以根据自己的配置定义该引脚。

// On-board LED pin number
#define LED_GREEN               PA5
#ifndef LED_BUILTIN
  #define LED_BUILTIN           LED_GREEN
#endif

// On-board user button
#ifndef USER_BTN
  #define USER_BTN              PC13
#endif

// I2C Definitions
#ifndef PIN_WIRE_SDA
  #define PIN_WIRE_SDA          PB9
#endif
#ifndef PIN_WIRE_SCL
  #define PIN_WIRE_SCL          PB8
#endif

按照此定义连接开发板和传感器。

kx224.jpg

上电验证

晃动传感器发现读取的数据会根据角度的不同发生变化,说明已经正常读取到传感器的数据。

20240314-154938.gif

收藏 评论0 发布时间:2024-3-14 15:50

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版