OneNET麒麟座应用开发之五:获取加速度传感器ADXL345数据

OneNET麒麟座应用开发之五:获取加速度传感器ADXL345数据由于数据采集站基本都安装在野外或者楼顶 安装位置以及震动对检测数据的准确性有一定影响 所以想要有一个位置状态数据 正好发现麒麟作上有 ADXL345 这样一个数字输出的加速度传感器 如图中红框所示 1 ADXL345 概述 ADXL345 是 ADI 公司推出的基于 iMEMS 技术的 3 轴 数字输出加速度传感器

大家好,我是讯享网,很高兴认识大家。

由于数据采集站基本都安装在野外或者楼顶,安装位置以及震动对检测数据的准确性有一定影响。所以想要有一个位置状态数据,正好发现麒麟作上有ADXL345,这样一个数字输出的加速度传感器。如图中红框所示:


讯享网

1ADXL345概述

ADXL345是ADI公司推出的基于iMEMS技术的3轴、数字输出加速度传感器。该加速度传感器的特点如下:

  • 分辨率高。最高13位分辨率。
  • 量程可变。具有+/-2g,+/-4g,+/-8g,+/-16g可变的测量范围。
  • 灵敏度高。最高达3.9mg/LSB,能测量不到1.0°的倾斜角度变化。
  • 功耗低。 40~145uA 的超低功耗,待机模式只有 0.1uA。
  • 尺寸小。整个 IC 尺寸只有 3mm*5mm*1mm, LGA 封装。

ADXL支持标准的I2C或SPI数字接口,自带32级FIFO存储,并且内部有多种运动状态检测和灵活的中断方式等特性。ADXL345传感器的检测轴如下图所示:

 

当 ADXL345 沿检测轴正向加速时,它对正加速度进行检测。在检测重力时用户需要注意,当检测轴的方向与重力的方向相反时检测到的是正加速度。下图所示为输出响应与相对于重力的方向的关系:

 

2、硬件设计

ADXL345支持SPI 和I2C两种通信方式,麒麟座采用的I2C通讯方式,具体连接如下图所示:

 

对于任何不使用的引脚,没有内部上拉或下拉电阻,因此,CS引脚或ALT ADDRESS引脚悬空或不连接时,任何已知状态或默认状态不存在。使用I2C时, CS引脚必须连接至VDD I/O, ALT ADDRESS引脚必须连接至任一VDD I/O或接地。

ALT ADDRESS引脚处于高电平,器件的7位I2C地址是0x1D,随后为R / W位。这转化为0x3A写入,0x3B读取。通过ALT ADDRESS引脚(引脚12)接地,可以选择备用I2C地址0x53(随后为R / W位)。这转化为0xA6写入, 0xA7读取。

由于在麒麟座中,ALT ADDRESS引脚(引脚12)接地,所以地址为0x53,也就是0xA6写入, 0xA7读取。此外2个终端信号也引入了MCU。

3、软件设计

接下来我们开始软件方面的设计。因为麒麟座中ADXL345使用I2C接口与MCU通讯,并连接到了I2C2(PB10、PB11)端口,接下来我们将逐步实现这部分软件。

(1)I2C读写操作

因为ADXL345加速度传感器使用了标准的I2C通讯接口,所以我们来看一看I2C读写单个或多个子解释的报文格式(如下图)。

 

根据以上报文图示,并结合STM32F1的库函数我们封装读写字节操作的函数。封装发送命令和获取数据函数:

/*向ADXL345下发指令,指令格式均为1个字节*/ void WriteByteToADXL345(I2C_TypeDef* I2Cx,uint8_t deviceAddress,uint8_t command) { uint16_t i2cTimeout=TimeoutPeriod; /*产生I2C起始信号*/ I2C_GenerateSTART(I2C2, ENABLE); /*检测 EV5 事件并清除标志*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) { if ((i2cTimeout--) == 0) return ; } /*发送ADXL345的地址*/ I2C_Send7bitAddress(I2Cx,deviceAddress,I2C_Direction_Transmitter); i2cTimeout=TimeoutPeriod; /*检测 EV6 事件并清除标志*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if ((i2cTimeout--) == 0) return ; } /*下发操作命令*/ I2C_SendData(I2Cx, command); i2cTimeout=TimeoutPeriod; /*检测 EV8 事件并清除标志*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if ((i2cTimeout--) == 0) return ; } /* 产生I2C停止信号 */ I2C_GenerateSTOP(I2Cx, ENABLE); } /*从ADXL345读取多个字节数据的值*/ void ReadBytesFromADXL345(I2C_TypeDef* I2Cx,uint8_t deviceAddress,uint8_t *pData,uint16_t bytesNum) { uint16_t i2cTimeout=TimeoutPeriod; /*如果I2C总线忙,则等待一段时间*/ while (I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)) { if ((i2cTimeout--) == 0) return ; } /* 产生 I2C 起始信号 */ I2C_GenerateSTART(I2Cx, ENABLE); /*检测 EV5 事件并清除标志*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) { if ((i2cTimeout--) == 0) return ; } /*发送ADXL345的地址*/ I2C_Send7bitAddress(I2Cx,deviceAddress,I2C_Direction_Receiver); i2cTimeout=TimeoutPeriod; /*检测 EV6 事件并清除标志*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if ((i2cTimeout--) == 0) return ; } while(bytesNum) { if(bytesNum==1) { I2C_AcknowledgeConfig(I2Cx, DISABLE);//关闭应答  I2C_GenerateSTOP(I2Cx, ENABLE);//停止信号  } i2cTimeout=TimeoutPeriod; /*检测 EV7 事件并清除标志*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)) { if ((i2cTimeout--) == 0) return ; } /*通过 I2C,从设备中读取一个字节的数据 */ *pData=I2C_ReceiveData(I2Cx); pData++; bytesNum--; } /*使能应答,方便下一次 I2C 传输*/ I2C_AcknowledgeConfig(I2Cx, ENABLE); }

讯享网
小讯
上一篇 2025-02-06 16:46
下一篇 2025-04-09 21:26

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/126190.html