This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

关于I2C控制器的几个疑问

您好,最近在使用DSP6713 的I2C控制器时发现几个问题,请教下各位,还望赐教:

1.向I2C命令寄存器中写入命令0x2420时,通过memory观察命令寄存器地址,发现只写进去了0x0420,如果强行再次写入0x2420时,该寄存器内容为0x2420,请问这是正常的么?(停止命令也一样)

2.I2C初始化时,需要增加将状态寄存器STR中的BB位写1清零的操作么?

3.在设置II2C为Master模式,处于接收状态时,RM=0情况下,采用轮询方式接收数据, 手册中的流程图中显示需要判断状态寄存器的ARDY位,当ARDY位为1时,可以设置停止位STP=1,然后读取I2CDRR最后一个字节数据。

但我在按照此流程图实际编码调试时,发现,当我要接收多个字节的情况下,接收完第一个字节时,ARDY就置1了,这个ARDY位在接收条件下,是每接收1个字节就会变为1么,那么我要接收多个字节的时候,ARDY怎么再变为0呢?

另外在发送状态时,ARDY的含义也是发送了一个字节就置1么?ARDY的含义到底是什么?

ARDY  NACK  ICRRDY (ICXRDY)这些状态位在收发过程中变化的先后是什么样的呢?

4.我采用轮询方法访问I2C,如果我在该发送停止位的时候(向命令寄存器STP位写1)被中断打断,写停止位时间会晚1ms左右,会对总线通讯有影响么,会造成BB一直是忙位的情况么?

5.我遇到过BB一直为1,向命令寄存器写停止位也不恢复的情况(复位I2C控制器可以BB=0),如果发生这种情况,我向I2C状态寄存器BB位写1清零是不是也没有实际作用,只是改变了状态寄存器的值,总线忙的实际状态没有改变呢?

问题有点多,麻烦大家了,谢谢。

  • 1. 请问”命令寄存器“是哪个寄存器?是I2CMDR寄存器?

    2. 初始化时可以不清,因为I2CMDR.IRS=1后,BB位为0。

    3. ARDY是判断I2C寄存器是不是可以被访问,在重新配置I2C寄存器之前,要先判断ARDY位。发送准备和接收准备标致分别是ICXRDY和ICRRDY标志位。从手册中的流程图中可以看出ARDY NACK ICRRDY (ICXRDY)这些状态位在收发过程中变化的先后顺序是先判断NACK,ARDY ,再判断ICRRDY (ICXRDY)。

    4.被什么中断打断?为什么会晚1ms这么长时间,建议中断子程序里做的操作越少越好。

    5. 是的,要找出BB一直为1的原因。
  • 您好,命令寄存器是I2CMDR,另外我再请教一下,当stt stp都设置为1时,当发送字节数Count减少至0时会自动产生停止信号.

    如果我采用restart方式通讯,发送时stt 设置1,stp设置为0,当发送计数清到零时不会自动产生停止位。接着再启动接收时,att和stp都设置为1,接收计数写为要接受的字节数,count还会减么,会自动产生停止位么?我不知道我对restart的这种操作对不对,谢谢您

  • 是的,当stt stp都设置为1时,当发送字节数Count减少至0时会自动产生停止信号。

    还会减的,有START信号,就会开始计数。
  • 好的 谢谢 另外 我上面描述的restart 方式通讯先配置stt为1 stp为0 发送写序列 再配置stt 为1 stp为1 完成读序列 这样操作 对吗 谢谢

  • 您说的restart方式就是repeat方式吗?
  • 是的,repeated start

  • 是的,具体数据格式参考3.5.4 Using a Repeated START Condition
  • ni您好,最近在调试一个产品,其中用6713处理器的I2C控制器访问ADT7410测温芯片,其中使用了repeated start方式,即先是发送写命令,数据为要访问的测温芯片的寄存器地址,然后没有停止命令,再发送读命令,测温芯片返回2个字节数据。

    我的大致流程是I2C控制器初始化后,在BB位=0,ICXRDY位=1的条件下,先设置从地址,数据长度为1,正确填充要访问芯片寄存器地址作为发送的数据,I2CMDR=0x2620。发起主发送流程。

    根据手册说明,如果STP = 0, ARDY位当Counter减少至0时会置1,且在BB=1情况下产生start条件,就是repeated start模式。

    所以我在判断到BB=1且ARDY为1时,继续填写接收数据长度,接收从地址,I2CMDR = 0x2C20,启动接收序列,在判断到ICRRDY位为1时读取接收缓存数据,直至接收到2字节为止。

    最后判断BB=0后完成接收操作。

    产品有2个中断,一个外部中断,一个定时器中断,两个中断一共耗时50us左右。

    现在遇到的现象就是,在I2C通讯过程中,经常会出现启动发送序列后(已经填写完要发送的从地址,数据长度,要访问的从芯片的地址,并填写了I2CMDR=0x2C20),I2CSTR一直为0x400,等多久超时该状态都不会再改变,导致通讯出现错误(很奇怪的状态)。如果关闭两个中断,则通讯正常。

    想请教下其中原理,是我操作带来的问题,还是中断机制会影响I2C的repeated start通讯呢?十分感谢!

  • 如果关闭中断就正常,那应该和中断有关。如果只开一个中断正常吗?中断子程序里做很多处理吗?建议中断子程序越简单越好。
  • 关闭中断正常,如果只开一个定时器中断,里面只做全局变量自增操作也没问题。出问题时我的终端操作也就是50us左右,里面会通过emif访问外设。但我没想明白的是,为什么中断能影响I2C通讯呢?

  • 把中断子程序里的程序简化,如先只置个标志位,看问题还是否存在?
  • 今天试了一下,在100us定时中断内加了简单的三个if(flag1 >10){}

    if(flag2>14){}

    if(flag3>8){}语句和一个变量++操作,if语句的执行分支都是空的。这样i2c通讯就会出错。

    删除一个if语句i2c执行就没问题了。这是什么原因呢?

  • 跟一下代码,看是运行到哪里出错了?I2C是轮询还是中断收发数据?
  • 轮询的,出错时是在启动发送命令之后(stt为1 stp为0),I2CSTR变为0x400就不再改变了。
    如果接收发生溢出会影响I2C控制器继续通讯么?
  • 如果接收发生溢出会影响I2C控制器继续通讯。
  • 那请问,这个溢出是不是当I2CDRR数据没被读走,而且I2CRSR接收满了数据,然后又有1位数据传入,此时发生了溢出,RSFULL置1。如果总线速率400K,采用轮询方式收数,那就是说中断如果耗时超过2.5个us,就有可能发生溢出,从而导致后续通讯不正常,不知道我理解的对么?谢谢您。
  • 我又核实了我的代码,我的I2C通讯都是在一个函数中执行完成的,就是说每调一次函数就会完成此次通讯(发和收都完成了,收到了正确的字节数),应该不是接收溢出导致通讯不正确的问题。
  • 试试把I2C改成中断模式接收,把I2C的中断优先级设成比其他两个中断优先级高。
  • 因为时序要求,我们不能采用中断方式来处理I2C通讯,所以采用的轮询。
  • 那尽量把中断子程序里的操作放到外面处理。要不然一直在执行中断子程序里的操作,I2C不能及时接收数据导致溢出。
  • 您好,我现在是每调用一次函数就完成一次I2C通讯,函数出口是保证总线处于空闲状态的,也就是说能够保证数据按预期字节数进行了发送和接收。不存在溢出的机理啊。
  • 那之前减少中断子程序处理的事情,i2C就能正常工作。应该还是中断子程序影响了I2C。
  • 您好,这两天我又做了一些软件更改,在初始化测温芯片为连续转换模式后,就将测温芯片的地址指针寄存器设置为温度采集结果的地址,这样以后只需要发起读操作就可以获取2字节的温度值(STT=1    STP=1  NACKMOD = 0)。配合示波器验证,偶尔会在主接收了2个字节后,主应该发送NACK应答,但用示波器测量SDA线,在该位置只出现了毛刺(0.5V左右。怀疑被从芯片发送的数据拉低了),并未出现NACK应有的高电平,随后SDA线上又继续有了数据传递,导致主溢出标志置位。

    1还是想确认一下,6713的I2C控制器的时序不会被处理器的定时中断或外部中断打断是么?(比如因为中断产生导致NACK发出时间变晚)

    2如果终端不会产生影响,还想请教下什么原因会造成这种现象呢。(测试期间还出现过I2CSTR的AL置1的情况,我调试的设备只有1个主设备,两个从设备,不应该有仲裁的情况产生啊;目前测试条件下,不存在repeated start的使用,我的接收流程中都是判断到BB=0时才会写I2CMDR0,都不会造成AL=1的条件呢)

    麻烦您给予指导,感谢!

  • 另外我看手册里面I2CMDR0中的NACKMOD位描述,有点疑问:手册中说,当控制器位主接收模式下,如果NACKMOD设置位0,那么在内部计数器没减到0之前,会回应ACK 。当内部计数器减少到0时,会回送NACK。但后面还有一句话,为了使NACK位更早的被发送,你必须设置NACKMOD位。那么当控制器做主接收时,NACKMOD位置0,是不是自动置NACK位呢,不用手动吧。感谢!
  • 硬件上I2c和外部中断是两个独立的模块,不会被打断。在软件处理上,如果外部中断发生后一直在中断子程序中没有及时跳出去接收I2C的数据,就会导致I2C出错。
  • 那定时器中断会影响I2C控制器执行时序么?

  • 请查看一下下面的wiki网站Subtleties of the Master Receiver Mode
    processors.wiki.ti.com/.../I2C_Tips
  • 您好,今天用示波器测量了一下I2C控制器的时钟,我们配置的是400K,测量发现只有370K左右,反复核实了I2C相关寄存器配置,也没有问题,测量了CPU时钟,也都正确,(那就意味着sysclk2正确---我们采用的是sysclk2作为时钟源),请问这是正常现象么?感谢!

  • 请问,我28035芯片,先设置从地址,数据长度为1,正确填充要访问芯片寄存器地址作为发送的数据,I2CMDR=0x2620。然后判断NACK位是否为0或者1,之后再设置STP设置为1,结束控制,然后再重新发送另一个芯片寄存器地址作为发送的数据,I2CMDR=0x2620。但是我的ARDY一直为0,一直卡在这里,请问这个ARDY为什么没有置1呢?