MMA8451 KE02 IIC连续读第一字节不知道什么意义之后六字节为...
本帖最后由 laotui 于 2015-2-6 11:27 编辑我在使用MMA8451时使用了IIC连续读的方法,但第一字节总是0xfc,之后为6字节数据。
现在的办法是写0x01地址之后连读7字节第一字节不要,读出数据是对的但不和IIC协议不知道什么原因。
地址写0x01,需要读出0x01-0x06的六个数据,实际读了7次第一个不知道是什么但之后六个是正确的。 跟IIC协议没关系吧, 看看MMA8451手册是怎么说的 mcucow 发表于 2015-2-6 11:00
跟IIC协议没关系吧, 看看MMA8451手册是怎么说的
我找到的中文手册非常笼统,英文关于连续读的描述为:
Multiple Byte Read
When performing a multi-byte read or “burst read”, the MMA8451Q automatically increments the received register address
commands after a read command is received. Therefore, after following the steps of a single byte read, multiple bytes of data
can be read from sequential registers after each MMA8451Q acknowledgment (AK) is received until a no acknowledge (NAK)
occurs from the Master followed by a stop condition (SP) signaling an end of transmission.
没有提到会加什么东西啊,之前没太多用飞思卡尔的传感器。
一字节一字节读是正常的0x01-0x06读6次就可以。 没用过这个传感器 只能看手册了可以查一下官网看看有没有关于MMA8451的例程 子鱼 发表于 2015-2-6 16:35
没用过这个传感器 只能看手册了可以查一下官网看看有没有关于MMA8451的例程 ...
我找到的官方程序是一位一位读的,没有用连续读。代码如下:
u16Result_x = HAL_DevMma8451ReadReg(0x01)<<8;
u16Result_x|= HAL_DevMma8451ReadReg(0x02);
u16Result_x >>= 8;
u16Result_y = HAL_DevMma8451ReadReg(0x03)<<8;
u16Result_y|= HAL_DevMma8451ReadReg(0x04);
u16Result_y >>= 8;
u16Result_z = HAL_DevMma8451ReadReg(0x05)<<8;
u16Result_z|= HAL_DevMma8451ReadReg(0x06);
u16Result_z >>= 8;
这是那什么看的啊 ,还能直接读数据? 连续读的例子也有吧 波型是用什么抓的 ? holts2 发表于 2015-2-6 21:53
波型是用什么抓的 ?
逻辑分析仪吧 jinyi7016 发表于 2015-2-6 23:22
逻辑分析仪吧
什么逻辑分析仪 holts2 发表于 2015-2-7 08:13
什么逻辑分析仪
X 宝上找找,有很多,2、3百吧 jinyi7016 发表于 2015-2-7 10:34
X 宝上找找,有很多,2、3百吧
大哥,是什么牌子的 holts2 发表于 2015-2-7 10:42
大哥,是什么牌子的
2个波形图可看不出来吧。 jinyi7016 发表于 2015-2-7 10:51
2个波形图可看不出来吧。
所以应该 是LZ回答是不? 楼主你好!
你可以参考下KL25的I2C例程
例程下载链接:
例程路径:kl25_sc_rev10\klxx-sc-pex\projects\accelerometer_demo\iar
我这边测试下MMA8451是正常的,
FSL_TICS_ZJJ 发表于 2015-2-9 10:38
楼主你好!
你可以参考下KL25的I2C例程
例程下载链接:
谢谢版主回复,我只有KE02的板子没有KL25实验不了。
程序在官网下载了,看不懂。
LDD_TError I2C2_MasterReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, LDD_I2C_TSize Size, LDD_I2C_TSendStop SendStop)
{
I2C2_TDeviceData *DeviceDataPrv = (I2C2_TDeviceData *)DeviceDataPtr;
if (Size == 0x00U) { /* Test variable Size on zero */
return ERR_OK; /* If zero then OK */
}
if (SendStop == LDD_I2C_NO_SEND_STOP) { /* Test variable SendStop on supported value */
return ERR_PARAM_MODE; /* If not supported value then error */
}
if ((DeviceDataPrv->SerFlag & GENERAL_CALL) != 0x00U) { /* Is the general call flag set (SelectSlaveDevice - address type is general call) ? */
return ERR_NOTAVAIL; /* It is not possible to receive data - Call SelectSlaveDevice method */
}
if (DeviceDataPrv->SendStop == LDD_I2C_SEND_STOP) {
if ((I2C_PDD_GetBusStatus(I2C0_BASE_PTR) == I2C_PDD_BUS_BUSY) || /* Is the bus busy? */\
((DeviceDataPrv->SerFlag & MASTER_IN_PROGRES) != 0x00U) || \
(DeviceDataPrv->InpLenM != 0x00U)) {
return ERR_BUSY; /* If yes then error */
}
} else {
if(((DeviceDataPrv->SerFlag & MASTER_IN_PROGRES) != 0x00U) || /* Is the bus busy? */\
(DeviceDataPrv->InpLenM != 0x00U)) {
return ERR_BUSY; /* If yes then error */
}
}
/* {Default RTOS Adapter} Critical section begin, general PE function is used */
EnterCritical();
DeviceDataPrv->SerFlag |= MASTER_IN_PROGRES; /* Set flag "busy" */
DeviceDataPrv->InpPtrM = (uint8_t *)BufferPtr; /* Save pointer to data for reception */
DeviceDataPrv->InpLenM = Size; /* Set the counter of input bufer's content */
DeviceDataPrv->SendStop = SendStop;/* Set generating stop condition */
I2C_PDD_SetTransmitMode(I2C0_BASE_PTR, I2C_PDD_TX_DIRECTION); /* Set TX mode */
if (I2C_PDD_GetMasterMode(I2C0_BASE_PTR) == I2C_PDD_MASTER_MODE) { /* Is device in master mode? */
I2C_PDD_RepeatStart(I2C0_BASE_PTR); /* If yes then repeat start cycle generated */
} else {
I2C_PDD_SetMasterMode(I2C0_BASE_PTR, I2C_PDD_MASTER_MODE); /* If no then start signal generated */
}
if ((DeviceDataPrv->SerFlag & ADDR_7) != 0x00U) { /* Is 7-bit addressing set ? */
DeviceDataPrv->SerFlag |= (ADDR_COMPLETE|REP_ADDR_COMPLETE); /* Only one byte of address will be sent 7-bit address mode*/
I2C_PDD_WriteDataReg(I2C0_BASE_PTR, (uint8_t)(DeviceDataPrv->SlaveAddr | 0x01U)); /* Send slave address */
} else {
if ((DeviceDataPrv->SerFlag & ADDR_10) != 0x00U) { /* Is 10-bit addressing set ? */
DeviceDataPrv->SerFlag &= (uint8_t)~(ADDR_COMPLETE | REP_ADDR_COMPLETE); /* Second byte of address will be sent later */
I2C_PDD_WriteDataReg(I2C0_BASE_PTR, DeviceDataPrv->SlaveAddrHigh); /* Send slave address - high byte*/
}
}
/* {Default RTOS Adapter} Critical section end, general PE function is used */
ExitCritical();
return ERR_OK; /* OK */
}
不明白怎么实现读的。
对比波形我的在每一字节后明显有明显的一段时钟低电平,请问是什么原因造成的。
而且从波形上看我的也是符合IIC协议的。 laotui 发表于 2015-2-9 12:00
谢谢版主回复,我只有KE02的板子没有KL25实验不了。
程序在官网下载了,看不懂。
LDD_TError I2C2_Master ...
那个是用CW的PE生成的,你可以用CW,或者KDS照着CW工程配置下,然后把代码拷贝进去。
laotui 发表于 2015-2-9 12:00
谢谢版主回复,我只有KE02的板子没有KL25实验不了。
程序在官网下载了,看不懂。
LDD_TError I2C2_Master ...
不过你每个字节之后有一点低电平的空档期,是没有关系的。
你照这个这个工程:kl25_sc_rev10\klxx-sc-pex\projects\accelerometer_demo\cw
用CW打开,然后自己新建个KE的,照着配置下,把主程序中代码拷贝过去试下。 FSL_TICS_ZJJ 发表于 2015-2-9 14:04
不过你每个字节之后有一点低电平的空档期,是没有关系的。
你照这个这个工程:kl25_sc_rev10\klxx-sc-pex ...
版主,我是用MDK的,而且不会用CW和PE,没有直接操作寄存器的版本可以参考吗? laotui 发表于 2015-2-10 11:29
版主,我是用MDK的,而且不会用CW和PE,没有直接操作寄存器的版本可以参考吗? ...
暂时没有连续读的KEIL工程,这样你把你的keil代码给我,我这边看下并测试下。
你是基于FRDM-KE02的板子吗? FSL_TICS_ZJJ 发表于 2015-2-10 11:50
暂时没有连续读的KEIL工程,这样你把你的keil代码给我,我这边看下并测试下。
你是基于FRDM-KE02的板子吗 ...
OK拜托版主了,是基于FRDM-KE02板子的。 laotui 发表于 2015-2-10 12:01
OK拜托版主了,是基于FRDM-KE02板子的。
你给我的是单字节操作?
把你多字节操作的代码给我看看。 用你的代码我直接读,并没有看到3B之后是FC
你把板子换换位置看看,读出的第一个值变不变。
我用你的代码,读出来是对的。 另外,你把你逻辑分析仪的线换根试试,是不是干扰到了。 FSL_TICS_ZJJ 发表于 2015-2-10 14:19
另外,你把你逻辑分析仪的线换根试试,是不是干扰到了。
不可能啊,程序一共读7字节,第一字节是0xfc,干扰不可能多出正好一字节。 laotui 发表于 2015-2-10 15:07
不可能啊,程序一共读7字节,第一字节是0xfc,干扰不可能多出正好一字节。 ...
你把板子位置换一换,然后看看读出的第一个字节还是不是FC,我直接用你代码,跑出来,第一个字节是0.
你把你板子位置拍张照片给我看看呢。
楼主可以检测一下是否和硬件有关系?
页:
[1]