MMA845x数据处理

更新时间:2023-09-19 21:17:01 阅读量: 小学教育 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

资料整理 7.0 14位,12位或10位数据流和数据转换

MMA8451Q具有14位的XYZ数据。 MMA8452Q具有12位XYZ数据而MMA8453具有10位的数据。本节概述了如何根据不同的MCU以及不同的数据格式来处理这些不断产生的14位数据数据。 “示例将以14位数据为例给出,但读者可以理解对于12位数据或10位数据应当作出怎样的变化。驱动程序代码具有所有的数据格式的所有功能。 事件标志可以通过读状态寄存器(0×00)来监视。监视事件标志可以通过本文件的第9.0节中所讨论的轮询或中断技术来完成。完全没有必要读状态寄存器来将其清除。读取数据将会清除状态寄存器。

表9。0X00 状态寄存器:数据状态寄存器(只读)

每当有新的数据在任何轴出现时,ZYXDR标志将被置位。下面的示例代码演示了如何监视这个标志位,当检测到新的数据时,通过一个单次的多字节I2C访问,将14/12/10-bit的XYZ数据读取到RAM中的一个数组(value[])。然后这些值被复制到16-bit变量以进行进一步加工。 Code Example: /*

** Poll the ZYXDR status bit and wait for it to set. */

RegisterFlag.Byte = IIC_RegRead(STATUS_00_REG); if (RegisterFlag.ZYXDR_BIT == 1) { /*

** Read 14/12/10-bit XYZ results using a 6 byte IIC access. */

IIC_RegReadN(OUT_X_MSB_REG, 6, &value[0]); /*

** Copy and save each result as a 16-bit left-justified value. */

x_value.Byte.hi = value[0]; x_value.Byte.lo = value[1]; y_value.Byte.hi = value[2]; y_value.Byte.lo = value[3]; z_value.Byte.hi = value[4]; z_value.Byte.lo = value[5]; }

下面的例子展示了一个与寄存器对应的左对齐的16bit X轴数据结果 表10。0X00 x_value.B yte.hi:MMA8451Q X_MSB寄存器(只读)

表11。0X01 x_value.B yte.lo:MMA8451Q X_LSB寄存器(只读)

2013年8月27日星期二 沨 第 1 页 共 11 页

资料整理

表12。 x_value16位二进制结果

7.1将14位二进制数转换成十六进制有符号整数(计数)

转换为有符号数值意味着,二进制的十六进制数转换为有+或 - 符号的整数。 例如:0xABCC=-1349 0x5443=1349

正负号可以通过检查高字节的值是否大于0x7F来确定。如果大于0x7F,则值是一个负数,并需要通过执行一个二进制补码操作来转换。这涉及到执行1的补码(即取反操作,将所有的“1”换成“0”并且将所有“0”换成“1”),并将结果加1。

下面的代码演示了这种转换。它也增加了额外的输出格式化步骤,用空格字符替换每一个前导零的数字,这是通过传递0xF0到SCI_NibbOut()函数来实现的。仔细研究后可以看出,此例程将把0x30加到0xF0,得到的结果0x120被截断为0x20- 空格字符的ASCII码值。 Code Example:

void SCI_s14dec_Out (tword data) {

byte a, b, c, d; word r; /*

** Determine sign and output */

if (data.Byte.hi > 0x7F) {

SCI_CharOut ('-');

data.Word = ~data.Word + 1; } else {

SCI_CharOut ('+'); } /*

** Calculate decimal equivalence: ** a = thousands ** b = hundreds ** c = tens ** d = ones */

a = (byte)((data.Word >>2) / 1000); r = (data.Word >>2) % 1000; b = (byte)(r / 100); r %= 100; c = (byte)(r / 10);

2013年8月27日星期二 沨 第 2 页 共 11 页

资料整理 d = (byte)(r % 10); /*

** Format adjustment for leading zeros */ if (a == '0') { a = 0xF0; if (b == '0') { b = 0xF0; if (c == '0') { c = 0xF0; } } } /*

* Output result */

SCI_NibbOut (a); SCI_NibbOut (b); SCI_NibbOut (c); SCI_NibbOut (d); }

7.2将14位二进制的十六进制数转换成以重力加速度g为单位的单精度浮点数

将结果转换成以重力加速度g为单位的单精度浮点数与上面例程的操作步骤相类似,但需要添加处理整数和小数部分值的过程。加速度计主动模式(即,无论是2G,4G或8G)的量程设置决定了小数点的位置以及传感器的灵敏度和精度。在任何情况下,最重要的位,第13位,代表结果的符号(正或负)。

?在2g主动模式1g=4096计数。因此,12位是唯一的整数位,决定了整数值是0或1。 212 = 4096。 11至0位是小数的数值。

?在4g主动模式1g= 2048个字。因此,位12和位11将表示整数值0,1,2,或3。 10到0位是小数的数值。 ?在8g的主动模式1g=1024个。因此,位12,11和10将表示整数值是0,1,2,3,4,5,6,和7。 9至0位是小数的数值。

表13。满量程值与相应的整数位和小数位

7.2.1 2G主动模式

在表14中可以看出,在2g主动模式时的结果调整数据转换成16位的左对齐格式后,小数点隐含于13和14位之间。表格中标记为“MMA8451Q 14b”的行显示的是这种格式中的14bit结果,而标记为“MSB / LSB”的行中加粗的(“M”)和不加粗的(“L”)表示数据来源于哪个结果寄存器。标记为“Integer/Fraction” 的行显示, 15位是符号位(“±”),而唯一一个整数位位于word格式的第14位(“I”)

2013年8月27日星期二 沨 第 3 页 共 11 页

资料整理 表14。2G主动模式下的14位数据转换为小数

确定符号和整数的结果后,结果逻辑左移两个二进制位,只留下的小数部分的结果,如表15所示。 表15。Word格式的2G主动模式下的14位数据左移后,消除整数和符号位

左移2位后剩下6个MSB位和6个LSB位。因此在2G主动模式有12位的小数部分。2g的主动模式下具有最高编号的位数为12的小数部分,因此它具有最高的灵敏度。在表16中的十进制值的最后小数四舍五入至小数点第四位的地方,因为将有四位有效数字。这应该是足够的。

表16所示的值被转换成的C的宏定义将在本节结束的代码示例中使用: 表16中。 2G主动模式下的分数值

#define FRAC_2d1 5000 #define FRAC_2d2 2500 #define FRAC_2d3 1250 #define FRAC_2d4 625 #define FRAC_2d5 313 #define FRAC_2d6 156 #define FRAC_2d7 78 #define FRAC_2d8 39 #define FRAC_2d9 20 #define FRAC_2d10 10 #define FRAC_2d11 5 #define FRAC_2d12 2

2013年8月27日星期二 沨 第 4 页 共 11 页

资料整理 对于12个分数位的每一位,如果该位被置位那么相应的十进制值将被加到最终结果。例如,如果8,6和4位被置位,那么,总数将是(625+156+ 39=820),其对应于0.0820。最高分数值出现时,所有的小数位数都被置位(5000+ 2500+1250+625+313+156+ 78+ 39+ 20+10+ 5 + 2=9998),对应于0.9998。在2g主动模式下的分辨率为0.244mg(1/4096)。计算出四个数字的比例,决定了2g主动模式下,分辨率为0.2mg。

Code Example:

void SCI_s14frac_Out (tword data) {

BIT_FIELD value; word result; byte a, b, c, d; word r; /*

** Determine sign and output */

if (data.Byte.hi > 0x7F) {

SCI_CharOut ('-'); data.Word &= 0xFFFC; data.Word = ~data.Word + 1; } else {

SCI_CharOut ('+'); } /*

** Determine integer value and output */

if (full_scale == FULL_SCALE_2G) {

SCI_NibbOut((data.Byte.hi & 0x40) >>6); data.Word = data.Word <<2; }

else if (full_scale == FULL_SCALE_4G) {

SCI_NibbOut((data.Byte.hi & 0x60) >>5); data.Word = data.Word <<3; } else {

SCI_NibbOut((data.Byte.hi & 0x70) >>4); data.Word = data.Word <<4; }

SCI_CharOut ('.'); /*

** Determine mantissa value

2013年8月27日星期二沨 第 5 页 共 11 页

资料整理 */ result = 0;

value.Byte = data.Byte.hi; if (value.Bit._7 == 1) result += FRAC_2d1; if (value.Bit._6 == 1) result += FRAC_2d2; if (value.Bit._5 == 1) result += FRAC_2d3; if (value.Bit._4 == 1) result += FRAC_2d4; //

data.Word = data.Word <<4; value.Byte = data.Byte.hi; //

if (value.Bit._7 == 1) result += FRAC_2d5; if (value.Bit._6 == 1) result += FRAC_2d6; if (value.Bit._5 == 1) result += FRAC_2d7; if (value.Bit._4 == 1) result += FRAC_2d8; if (value.Bit._3 ==1) result += FRAC_2d9; if (value.Bit._2 ==1) result += FRAC_2d10; //

if (full_scale != FULL_SCALE_8G) {

if (value.Bit._1 == 1) { result += FRAC_2d11; }

if (full_scale == FULL_SCALE_2G) {

if (value.Bit._0 == 1) result += FRAC_2d12; } }

9.0轮询数据与中断

数据可以连续被轮询,或者被设置为每次有新数据已经准备好时发送一个硬件中断或异常到MCU。具体哪种方式更有效,需要视情况而定,虽然轮询通常是低效率的。 9.1轮询数据

轮询需要进行较少的配置,实施起来也很方便。然而,MCU必须轮询传感器的速度必须快于数据采集速率。否则,如

2013年8月27日星期二 沨 第 6 页 共 11 页

资料整理 果在轮询太慢,数据样本可能会错过。该MCU通过检查状态寄存器的覆盖标志(即,ZYXOW,ZOW,YOW,和XOW)可以检测这种情况。到目前为止,这个文件主要示例代码都是采用轮询技术。作为一个总结,这里是一个比较完整的例子的基本代码,特定的IC MMA8451,2,3Q,需要不断轮询14位,12位或10 - 位的XYZ数据的操作。 Code Example: /*

** Go to the Standby Mode */

MMA845xQ_Standby(); /*

** Clear the F_Read bit to ensure both MSB’s and LSB’s are indexed */

IIC_RegWrite(CTRL_REG1,(IIC_RegRead(CTRL_REG1)& ~FREAD_MASK); /*

** Go back to Active Mode */

MMA845xQ_Active(); /*

** Using a basic control loop, continuously poll the sensor. */ for (;;) { /*

** Poll the ZYXDR status bit and wait for it to set. */

RegisterFlag.Byte = IIC_RegRead(STATUS_00_REG); if (RegisterFlag.ZYXDR_BIT == 1) { /*

** Read 14/12/10-bit XYZ results using a 6 byte IIC access. */

IIC_RegReadN(OUT_X_MSB_REG, 6, &value[0]); /*

** Copy and save each result as a 16-bit left-justified value. */

x_value.Byte.hi = value[0]; x_value.Byte.lo = value[1]; y_value.Byte.hi = value[2]; y_value.Byte.lo = value[3]; z_value.Byte.hi = value[4]; z_value.Byte.lo = value[5]; /*

** Go process the XYZ data. */

GoProcessXYZ(&value[0]); } /*

2013年8月27日星期二 沨 第 7 页 共 11 页

资料整理 ** Perform other necessary operations. */ etc(); }

9.2中断程序访问数据

通过硬件中断传输数据与轮询相比是更高效,因为MCU只有当有新的数据时才访问加速度计。只有当新的数据可用时,该数据才被读取。如果在新的样本数据产生时上一个数据还未被读取,覆盖寄存器的标志位将被置位。以下是用来设置每次产生新数据后产生中断信号的寄存器配置。 下面所示的MCU的中断服务程序(ISR)对应地读取14位,12位或10位的XYZ数据和设置软件标志指示收到新数据。保持尽可能快的中断服务程序被认为是很好的做法,所以在中断程序中没有做实际的数据处理。请注意与轮询方法的相似性。访问8位数据,也可以用类似的方式。 Code Example: /*

** Go to the Standby Mode */

MMA845xQ_Standby(); /*

** Clear the F_Read bit to ensure both MSB’s and LSB’s are indexed */

IIC_RegWrite(CTRL_REG1,(IIC_RegRead(CTRL_REG1)& ~FREAD_MASK); /*

** Configure the INT pins for Open Drain and Active Low */

IIC_RegWrite(CTRL_REG3, PP_OD_MASK); /*

** Enable the Data Ready Interrupt and route it to INT1. */

IIC_RegWrite(CTRL_REG4, INT_EN_DRDY_MASK); IIC_RegWrite(CTRL_REG5, INT_CFG_DRDY_MASK); /*

** Go back to Active Mode */

MMA845xQ_Active(); /* ** etc. */

/*********************************************************\\ * MMA8451,2Q Interrupt Service Routine

\\*********************************************************/ interrupt void isr_MMA8451Q (void) { /*

** Clear the MCU’s interrupt flag */

CLEAR_MMA8451Q_INTERRUPT; /*

2013年8月27日星期二 沨 第 8 页 共 11 页

资料整理 ** Go read the Interrupt Source Register */

RegisterFlag.Byte = IIC_RegRead(INT_SOURCE_REG); if (RegisterFlag.SRC_DRDY_BIT == 1) { /*

** Read 14 12 or 10-bit XYZ results using a 6 byte IIC access. */

IIC_RegReadN(OUT_X_MSB_REG, 6, &value[0]); /*

** Copy and save each result as a 16-bit left-justified value. */

x_value.Byte.hi = value[0]; x_value.Byte.lo = value[1]; y_value.Byte.hi = value[2]; y_value.Byte.lo = value[3]; z_value.Byte.hi = value[4]; z_value.Byte.lo = value[5]; /*

** Indicate that new data exists to be processed. */

NEW_DATA = TRUE; } }

10.0使用32采样堆栈

访问数据最有效的方式特别是在数据记录是采用32个内部样本FIFO缓冲器。这最大限度地减少了I2C总线数据量。有关如何配置FIFO的更多信息请参考AN4073。FIFO可配置为循环缓冲模式,每次刷新数据时丢弃最旧的数据。这将设置FIFO中断。 配置FIFO:

?循环缓冲模式F_MODE= 01 ?设置水印 ?设置FIFO中断

?链接FIFO中断到INT1或INT2 ?中断引脚设置为低电平有效的漏极开路 Example Code: /*

** Go to Standby Mode */

MMA845xQ_Standby(); /*

** Set F_Mode to Circular, Set the Watermark Value into the F_SETUP register */

IIC_RegWrite(F_SETUP_REG, F_MODE0_MASK + WATERMARK_VAL); /*

** Enable the FIFO Interrupt and Set it to INT2

2013年8月27日星期二 沨 第 9 页 共 11 页

资料整理 */

IIC_RegWrite(CTRL_REG4, INT_EN_FIFO_MASK); IIC_RegWrite(CTRL_REG5, ~INT_CFG_FIFO_MASK); /** Configure the INT pins for Open Drain and Active Low */

IIC_RegWrite(CTRL_REG3, PP_OD_MASK); /*

** Go to Active Mode */

MMA845xQ_Active();

/*********************************************************\\ * MMA8451Q Interrupt Service Routine for the FIFO

\\*********************************************************/ interrupt void isr_MMA8451Q (void) { /*

** Clear the MCU’s interrupt flag */

CLEAR_MMA8451Q_INTERRUPT; /*

** Go read the Interrupt Source Register */

RegisterFlag.Byte = IIC_RegRead(INT_SOURCE_REG); if (RegisterFlag.SRC_FIFO_BIT == 1) { /*

** Read 14-bit XYZ results using a multi-read IIC access. */

IIC_RegReadN(OUT_X_MSB_REG, WATERMARK_VAL*6, &value[0]); /*

** Copy and save each result as a 16-bit left-justified value. */

x_value.Byte.hi = value[0]; x_value.Byte.lo = value[1]; y_value.Byte.hi = value[2]; y_value.Byte.lo = value[3]; z_value.Byte.hi = value[4]; z_value.Byte.lo = value[5]; /*

** Indicate that new data exists to be processed. */

NEW_DATA = TRUE; } }

The HP_FILTER_CUTOFF register (at 0x0F) sets the high-pass cutoff frequency, Fc, for the data. Th e output of this filter is

2013年8月27日星期二 沨 第 10 页 共 11 页

资料整理 provided in the output data registers (0x01 to 0x06). Note that the high-pass filtered output data is available for the MMA8451Q and the MMA8452Q only. The MMA8453Q has the internal high-pass filter for the embedded functions but does not have access to the output data. The available cutoff frequencies change depending upon the set Output Data Rate.

This register sets the high-pass filter cutoff frequency for removal of the offset and slower changing acceleration data. The output of this filter is indicated by the data registers (0x01-0x06) when bit 4 (HPF_OUT) of Register 0x0E is set. The filter cutoff options change based on the data rate selected as shown in Ta b l e 2 3 . For details of implementation on the high-pass filter, refer to Freescale application note, AN4071.

2013年8月27日星期二 沨 第 11 页 共 11 页

本文来源:https://www.bwwdw.com/article/x5ph.html

Top