你好,
我试着与传感器通信。传感器数据表说我需要写一个命令进行测量。它的值(12或14位)存储在它的记忆。我必须得到这个数据读出2字节。但每当我尝试读取数据的“i2c_eeprom_read_data (uint8_t * rd_data_ptr、uint32_t地址uint32_t大小)
“我困在”read_data_single ()
“在”WAIT_FOR_RECEIVED_BYTE ();
”循环。DA14580似乎收不到东西。
为* rd_data_ptr
我有一个指针指向一个值变量uint32_t mes_val
。地址我用了I2C_SLAVE_ADDRESS
在user_periph_setup配置。h。为大小
我有2两个字节。
我能做些什么来接受两个字节?它是怎么存储的?我需要存储在一个变量值的大小是2字节。发送“读”命令后,传感器发送“MOST_SIGNIFICANT_BYTE _ACK_“LEAST_SIGNIFICANT_BYTE _ACK_(可能校验和)_NACK_ STOP_CONDITION。
更好地描述它,我也试过了i2c_eeprom_read_byte
第一个字节。但这并不奏效。也BLE-connection丢失,我无法连接。整个系统只有在“等待循环”。我不得不取消,复位并重新启动系统蓝牙再次工作。我想通过BLE-command触发测量与写作1到一个特征值。写1 char值触发命令(1个字节长度)的测量应该被解雇。之后我想读出的值(2字节)将存储在另一个特点。
当一切工作我想使用通知来更新我的电话上的价值与传感器的新值。
谢谢!
1月
设备:
嗨JanFeld,
如果你被困在WAIT_FOR_RECEIVE_BYTE()然后是的580没有收到从另一边。我不认为这是由于代码实现,但由于580年和传感器连接,或传感器由于某种原因没有回复你发送的命令。逻辑分析仪采集将大有帮助。
关于祝福,I2C司机投票I2C接口为了得到一些数据,因为没有数据返回司机等待,祝福连接丢失自M0坚持I2C轮询。你将会得到一个捕获的I2C总线,看看580发送在公共汽车上,如果它是正确的(传感器得到的命令他希望),如果有回复的传感器。
关于I2C的阅读程序驱动程序,您可以使用read_data_single()函数设置传感器的地址,你想读(传感器)的一些内部地址和值2中设置大小。将迫使司机送两个时钟周期,以读取数据的指定地址,你宣称。然后司机将接收到的数据的指针传递的函数作为一个参数。
由于MT_dialog
谢谢你的回答。我没有任何关于传感器的内部地址的信息。arduino的效果好。我发送“测量CMD”传感器,等待一段毫秒时测量然后我发送读取请求。在那之后我会读两个字节的数据。没有什么内部地址的传感器。我认为它的工作原理是这样的:
µC: _____ S___ADDR + WR_BIT_____Meas_CMD_____ADDR + RD_BIT______ACK_____ACK____________NACK___P
传感器:______________________ACK____________ACK_________________MSB______LSB_____CHECKSUM__________
这就是它的传感器数据表中描述。没有特定的奥得河指针地址可用。有另一种方法得到的值?也许类似“听”功能?
我会试着尽快分析示波器的传播。但也许你有一个想法我能做什么。
谢谢,
1月
嗨JanFeld,
看来你需要发送Meas_CMD作为read_data_single地址参数()的大小2为了执行两个读数。为了i2c传感器提供一些值回它需要知道数据emmit和设备,或一般要做什么,所以你必须提供设备的i2c总线地址,您还想交流和写传感器(i2c的写命令)你要什么值(Meas_CMD)。所以当你试图访问总线与read_data_single()函数I2C奴隶设备会自动提供的地址,你应该设定在I2C模块的初始化(在i2c_init())和写一点,一旦i2c_send_address (Meas_CMD)后执行,奴隶地址(Meas_CMD)会在公共汽车上,然后I2C模块提供时钟带传感器的两个字节。我希望我是足够清晰。
由于MT_dialog
你好再次,它仍然不工作。我试着发送MEAS_CMD作为地址参数。
我把计划从传感器的数据表。它显示了该传感器适用于通信序列。现在我看不到的可能性i2c_eeprom文件可以提供这种类型的通信流。
我仍然被困在试图接收字节。
在我的理解我发送measuerment write函数命令。我没有一个内存地址但只有传感器的I2C地址。后测量(介于20 -80µs)我可以发送一个读取命令(i2c_address + read-bit)。然后传感器开始发送数据。首先最重要的字节。当它收到DA14580提供ACK。第二个字节(LSB)将发送(ACK DA14580)紧随其后。校验和将被发送。
我得到一个错误的想法如何工作或有别的东西我看不见吗?
沟通有引体向上对通信线路。我使用内部引体向上”ConfigurePin (……INPUT_PULLUP .....)”是错误的吗?我试着外部引体向上。(
ConfigurePin (.....输入.....)
)。也没有工作。谢谢,
1月
嗨JanFeld,
正如我提到的,没有截图,没有简单的调试方法,你必须检查车上的信号,通过猜测我们不能跟踪问题的原因。你需要检查出什么I2C总线。I2C功能当执行一个读将执行写第一次(最后一点I2C奴隶地址设置为0),为了写设备的内部地址,或者一个命令在你的情况中,然后将读取命令(奴隶地址最后位设置为1)为了从传感器开始阅读,你不该问题写和读命令之间的延迟。你可以检查传感器的配置的I2C对应于初始化期间I2C模块的设置。但你真的需要捕捉公共汽车以解决这个问题。
由于MT_dialog
你好再次,
我检查了示波器和发现的通信
SEND_I2C_COMMAND
不正常工作。当我想写一个命令发送ADDR + WR_BIT命令后向右转一点。(大多数时候,并不是所有的时间。有时它的工作原理)例如:
SEND_I2C_COMMAND (0 xf3)
将发送:ADDR + WR_BIT和0 x71命令。7位addr (1000 ' 0000。+ wr位0和0111年1001年而不是1111年的0011)。地址是正确的,有时它的工作原理和传感器是做它的工作。但是大多数时候它不工作和发送错误的价值观。当我试着读一些。我想把
SEND_I2C_COMMAND (0 x0100)
。它发送:ADDR + WR_BIT(而不是RD_BIT)和之后,一些随机值。有时它的工作原理,它将发送ADDR + RD_BIT。(1000 0001),但大多数时候它不正常工作。我有另一个问题是,是ACK后收到的字节集自动或我必须手动设置ACK第一个字节传感器可以发送第二个呢?
谢谢,
1月
嗨JanFeld,
关于SEND_I2C_COMMAND(),我不认为命令做任何与你面临什么,如果有时候工作和其他人没有我想它做一些与你的连接。
I2C控制器将生成ACK时自动接收的数据,你不需要做任何额外的代码。
由于MT_dialog
你好,
我有同样的问题,我阅读多字节I2C总线卡住了。我已经修改了I2C-Multi-read fucntioin从“i2c_eeprom.c”之一。功能描述如下。
问题是,当我试图读取192字节的传感器(加速度计MMA8652),程序将停在“WAIT_FOR_RECEIVED_BYTE();“已经读取数据的索引总是66(12月)。
和我的通信图逻辑信号分析仪,似乎DA14580之间的通信和加速度计是正确的,信号持续了192字节的时期!整个时期的时间是相同的,当我取消“WAIT_FOR_RECEIVED_BYTE”的代码。甚至之前可用数据I2C-STOP信号根据图表。
所以,似乎DA14580之间的“连接问题”和加速度计是不正确的原因。
希望你的帮助。
空白I2C_ReadMultiByte (uint8_t regAddr uint8_t数据[],uint8_t大小)
{
uint8_t指数;
WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();
WAIT_UNTIL_NO_MASTER_ACTIVITY ();
/ /寄存器地址
SEND_I2C_COMMAND (regAddr);
(指数= 0;指数<大小;指数+ +)
{
WAIT_WHILE_I2C_FIFO_IS_FULL ();/ /等待如果Tx FIFO
SEND_I2C_COMMAND (0 x0100);/ /设置读访问
}
/ /读数据
(指数= 0;指数<大小;指数+ +)
{
WAIT_FOR_RECEIVED_BYTE ();
数据(指标)= (uint8_t) (GetWord16 (I2C_DATA_CMD_REG) & 0 xff);
}
}
和I2C的初始化控制部:
i2cInitParam_t参数;
参数。periAdrr = 0 x1d;
参数。addressMode = I2C_7BIT_ADDR;
参数。speedMode = I2C_FAST;
空白I2C_Init (const i2cInitParam_t *参数)
{
SetBits16 (CLK_PER_REG I2C_ENABLE 1);/ /启用I2C的时钟
SetWord16 (I2C_ENABLE_REG 0 x0);/ /禁用I2C控制器
SetWord16 (I2C_CON_REG I2C_MASTER_MODE | I2C_SLAVE_DISABLE | I2C_RESTART_EN);/ /奴隶是禁用的
SetBits16 (I2C_CON_REG I2C_SPEED, param - > speedMode);/ /设置速度
SetBits16 (I2C_CON_REG I2C_10BITADDR_MASTER, param - > addressMode);/ /设置寻址模式
SetWord16 (I2C_TAR_REG param - > periAdrr & 0 x3ff);/ /设置奴隶设备地址
SetWord16 (I2C_ENABLE_REG 0 x1);/ /启用I2C控制器
而((GetWord16 (I2C_STATUS_REG) & 0 x20) ! = 0);/ /等待I2C主FSM闲置
}
你好,
我有同样的问题,我阅读多字节I2C总线卡住了。我已经修改了I2C-Multi-read fucntioin从“i2c_eeprom.c”之一。功能描述如下。
问题是,当我试图读取192字节的传感器(加速度计MMA8652),程序将停在“WAIT_FOR_RECEIVED_BYTE();“已经读取数据的索引总是66(12月)。
和我的通信图逻辑信号分析仪,似乎DA14580之间的通信和加速度计是正确的,信号持续了192字节的时期!整个时期的时间是相同的,当我取消“WAIT_FOR_RECEIVED_BYTE”的代码。甚至之前可用数据I2C-STOP信号根据图表。
所以,似乎DA14580之间的“连接问题”和加速度计是不正确的原因。
希望你的帮助。
空白I2C_ReadMultiByte (uint8_t regAddr uint8_t数据[],uint8_t大小)
{
uint8_t指数;
WAIT_UNTIL_I2C_FIFO_IS_EMPTY ();
WAIT_UNTIL_NO_MASTER_ACTIVITY ();
/ /寄存器地址
SEND_I2C_COMMAND (regAddr);
(指数= 0;指数<大小;指数+ +)
{
WAIT_WHILE_I2C_FIFO_IS_FULL ();/ /等待如果Tx FIFO
SEND_I2C_COMMAND (0 x0100);/ /设置读访问
}
/ /读数据
(指数= 0;指数<大小;指数+ +)
{
WAIT_FOR_RECEIVED_BYTE ();
数据(指标)= (uint8_t) (GetWord16 (I2C_DATA_CMD_REG) & 0 xff);
}
}
和I2C的初始化控制部:
i2cInitParam_t参数;
参数。periAdrr = 0 x1d;
参数。addressMode = I2C_7BIT_ADDR;
参数。speedMode = I2C_FAST;
空白I2C_Init (const i2cInitParam_t *参数)
{
SetBits16 (CLK_PER_REG I2C_ENABLE 1);/ /启用I2C的时钟
SetWord16 (I2C_ENABLE_REG 0 x0);/ /禁用I2C控制器
SetWord16 (I2C_CON_REG I2C_MASTER_MODE | I2C_SLAVE_DISABLE | I2C_RESTART_EN);/ /奴隶是禁用的
SetBits16 (I2C_CON_REG I2C_SPEED, param - > speedMode);/ /设置速度
SetBits16 (I2C_CON_REG I2C_10BITADDR_MASTER, param - > addressMode);/ /设置寻址模式
SetWord16 (I2C_TAR_REG param - > periAdrr & 0 x3ff);/ /设置奴隶设备地址
SetWord16 (I2C_ENABLE_REG 0 x1);/ /启用I2C控制器
而((GetWord16 (I2C_STATUS_REG) & 0 x20) ! = 0);/ /等待I2C主FSM闲置
}
我有一个解决方案,适合我,但我想它也许不够安全的很多连续的字节数。也许你可以试试. .
我解决它通过删除
WAIT_FOR_RECEIVED_BYTE ();
并试图获取值,并将其保存到一个数组后直接通过指针。我现在的功能是这样的:
空白i2c_cust_read_bytes (uint8_t * val_ptr)
{
val_ptr [0] = 0 x00;
val_ptr [1] = 0 x00;
WAIT_UNTIL_NO_MASTER_ACTIVITY ();
SEND_I2C_COMMAND (0 x0100);
WAIT_WHILE_I2C_FIFO_IS_FULL ();
val_ptr [1] = GetWord16 (I2C_DATA_CMD_REG);
SEND_I2C_COMMAND (0 x0100);
WAIT_WHILE_I2C_FIFO_IS_FULL ();
val_ptr [0] = GetWord16 (I2C_DATA_CMD_REG) & 0 xfc;
}
它适合我。原因我有第一个值数组的第二个元素是,我想要。你可以选择你想点的元素。
我认为它是这样的:
首先:没有主活动。
然后发送“READ_CMD”. .等到FIFO是空接收新的字节(清除在写地址+,0 x00读入I2C_DATA_CMD_REG)。
然后保存到你想要的变量。再次发送一个READ_CMD将覆盖值保存在I2C_DATA_CMD_REG和重复,每个字节连续你想接收。
两个值可能的工作,但我不知道如果这是可能的和保存接收连续超过一个或两个字节没有错误或更改。
遗憾的是我仍然不知道为什么WAIT_FOR_RECEIVED_BYTE()不为我工作。
希望我能帮助你。
欢呼,
1月
你好,
你有试过使用I2C驱动程序(i2c_eeprom_read_data)。捕捉你的高度我看到没有停止条件从580年为了读取数据(FIFO满-32时钟周期emmited和32字节的数据已收到,所以proccessor应该开始阅读FIFO和把数据从I2C FIFO缓冲区),你在读数据FIFO时满了吗?I2C_RX_FLR_REG WAIT_FOR_RECEIVED_BYTE检查,这个寄存器包含有效数据收到,位于FIFO如果没有FIFO中的数据将被困在指示以来阅读。所以在代码大小的值是多少,你是使用作为输入?如果你调用函数,你提到有超过32你FIFO充满和FIFO中的数据在接下来写的输入数据。如果你检查I2C_eeprom司机你会看到i2c_eeprom_read_data是阅读的数据使用read_data_single eepm在32的倍数()函数和当FIFO满32字节I2C模块将停止时钟读取32个字节的数据。
Thansk MT_dialog
嗨。
我有一个同样的问题&解决方案。
你可以阅读两个字节代码。
关键是I2C_CON_REG I2C_RESTART_EN禁用。
空白init_i2c(空白)
{
SetBits16 (CLK_PER_REG I2C_ENABLE 1);/ /启用I2C的时钟
SetWord16 (I2C_ENABLE_REG 0 x0);/ /禁用I2C控制器
/ /这是关键的解决方案。
/ / SetWord16 (I2C_CON_REG I2C_MASTER_MODE | I2C_SLAVE_DISABLE | I2C_RESTART_EN);/ /奴隶是禁用的
SetWord16 (I2C_CON_REG I2C_MASTER_MODE | I2C_SLAVE_DISABLE);
SetBits16 (I2C_CON_REG I2C_SPEED I2C_STANDARD);/ /设置速度
SetBits16 (I2C_CON_REG I2C_10BITADDR_MASTER I2C_7BIT_ADDR);/ /设置寻址模式
/ / I2C设备地址设置。
SetWord16 (I2C_TAR_REG、地址);/ /设置奴隶设备地址
SetWord16 (I2C_ENABLE_REG 0 x1);/ /启用I2C控制器
而((GetWord16 (I2C_STATUS_REG) & 0 x20) ! = 0);/ /等待I2C主FSM闲置
}
无符号短readShortI2C(空白)
{
无符号短v, v1、v2;
WAIT_WHILE_I2C_FIFO_IS_FULL ();/ /将R / W位设置为1(读访问)
SEND_I2C_COMMAND (0 x0100);/ /设置读访问。2次电话
WAIT_WHILE_I2C_FIFO_IS_FULL ();
SEND_I2C_COMMAND (0 x0100);
WAIT_FOR_RECEIVED_BYTE ();/ /等待接收的数据
v1 = 0 xff & GetWord16 (I2C_DATA_CMD_REG);/ /收到的字节,最高有效位
WAIT_FOR_RECEIVED_BYTE ();/ /等待接收的数据
v2 = (0 xff & GetWord16 (I2C_DATA_CMD_REG));/ /接收字节,LSB
v = v1 < < 8 | v2;
arch_printf (“04 x: \ r \ nV % % 04 x = % 04 x (% d)”v1、v2, v, v);
返回v;
}
谢谢你!