4个职位/ 0个新职位
最后发表
jamesleo-konka
离线
最后看到:4年3个月前
加入:2017-01-22 02:42
I2C启动信号

嗨,对话框中,
我有一个外设,是这个时序:
开始
发送Device_addr (W)
发送Reg_addr
重新启动
发送Device_addr(右)
读取数据
....
停止

看了demo_i2c.c还是没搞清楚如何实现这个时序。
一般的I2C时序是这样的:
开始
发送Device_addr (W / R)
发送Reg_addr
写/读数据
....
停止

该如何利用I2C的库函数来实现?hw_i2c_set_restart_enabled (HW_I2C_ID id, bool启用)如何使用吗?
在芯片硬件设计中,重启是怎样触发的吗?

另外,一个I2C操作过程是如何启动的?(产生开始信号开始)。demo_i2c.c里,FM75的例子,貌似只有一个set_target_address,这个函数可以启动I2C吗?即使可以,这次I2C完成之后,下次的操作也应该重复启动I2C才对。

谢谢

关键词:
设备:
Qinjiny_Dialog
离线
最后看到:2个月2周以前
工作人员
加入:2016-11-01 05:47
你好,

你好,

hw_i2c_set_restart_enabled这个函数是把I2C_CON_REG里的I2C_RESTART_EN位设为1,目的在做为I2C主机的时候允许发送重启信号,并且这个钻头默认就是1,也就是允许的。

重启信号一般不需要手动设置,底层协议根据奴隶反馈ACR的情况自行判断是发送重启继续进行I2C数据传输还是发送停止结束。

681年建议看一下数据表的114页开始,对芯片的I2C功能和时序有很详细的说明。除了demo_i2c.c外,也可以看看demo_i2c_async.c和适配器里面的ad_i2c.c

jamesleo-konka
离线
最后看到:4年3个月前
加入:2017-01-22 02:42
Qinjiny_Dialog,您的好

Qinjiny_Dialog,您的好
我看演示里的peripheral_demo工程,隐含了很多细节,包括启动开始,停止信号等等
一般步骤:
1.设置目标地址
2.资源需要(I2C)

然后就是读写I2C,比如
Static void fm75_read_reg(uint8_t reg, uint8_t *val, uint8_t len)

Size_t rd_status = 0;
HW_I2C_ABORT_SOURCE abt_src = HW_I2C_ABORT_NONE;

/*
*在从传感器寄存器读取值之前,我们需要向它发送一个字节的信息
*通知现在将读取哪个传感器寄存器。
*/
hw_i2c_write_byte (HW_I2C1 reg);
rd_status = hw_i2c_read_buffer_sync(HW_I2C1, val, len, & abt_src, HW_I2C_F_NONE);
if ((rd_status < (size_t)len) || (abt_src != HW_I2C_ABORT_NONE)) {
printf("fm75 read failure: %u" NEWLINE, abrt_src);

那我理解的话:hw_i2c_write_byte (HW_I2C1 reg);这个语句会启动开始,并发送奴隶地址(写),然后发送注册
接下来,hw_i2c_read_buffer_sync这个函数,读,改变了I2C的方向,会自动产生一个重启,并自动发送奴隶地址(读),然后读取数据。。。读取完成之后,I2C控制器自动产生停止。

几个关键的开始,启动,停止都是隐含而且自动完成的?包括奴隶地址都是自动发送的吗?——没有看到发送奴隶地址的函数语句。
那我要求的时序,也可以用上面这段代码来实现了 ?万能啊

开始——|
发送Device_addr(W)——| ---- hw_i2c_write_byte(HW_I2C1, reg);
发送Reg_addr——|
重启——自动生成——|
发送Device_addr(R)——|——hw_i2c_read_buffer_sync
读取数据——|
....
停止——|

是这样吗?如果这样,真是万能了

Qinjiny_Dialog
离线
最后看到:2个月2周以前
工作人员
加入:2016-11-01 05:47
发生方向改变的话I2C模块是会发送重启命令的

发生方向改变的话I2C模块是会发送重启命令的,不过还是建议使用适配器里面的函数而不是直接调用底层驱动