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.

对MSP430F4152的硬件I2C的一处疑惑

Other Parts Discussed in Thread: MSP430F4152

最近用MSP430F4152做一个项目,在调试其USCI的I2C发现个严重问题,就是:假若430作为主机,接收从机的数据,但该型号没有设置指定接收字节个数的寄存器,而主机又是自动应答,那么数据就是一直接收,而接受的BUFFER是8位的,那么我去读接收寄存器就会读到最新的一个数据而已。

但我现在需要读一开始的4个字节,这个怎么处理好呢?急急急啊,请大虾们赐教。

  • lz是怕自己还没来得急读数据,就会被后面的数据覆盖吗?

  • 如果是这样的话那么完全没必要担心,lz可以设置一个char型的数组,用于接收从机发来的数据,只有你读了buffer里的数据,从机才会发送下一个数据。

  • 嗯,明白你的意思。也去看了官方代码示例。

    但现在还是卡住了,我用430单片机模拟I2C写了个程序去配置从设备AD芯片和读数据,一切正常没问题(说明芯片电路啥的是没问题的),用单片机硬件I2C却始终不行,如果按照文档说的(写完配置数据UCB0TXBUF = 0x1c,从机应答则UCB0TXIFG=1和UCTXSTT=0),我单步调试发现运行正常,那意思说明配置成功了,但我用我模拟I2C的读函数去去AD,发现回来的数据完全说明数据没有配置成功。

    这是怎么回事呢?

  • 先确定楼主的意思:是想让工作在主机的MSP430固定从I2C从机读一定字节数的数据上来。而如果采样硬件I2C的话,由于时钟和应答(ACK)是由MSP430发出的,所以在接收到最后一个字节后,MSP430无法发出NACK信号,而MSP430还会继续发送CLK读下一个字节。

    其实MSP430是支持在读到最后一位后发送N-ACK信号的。楼主需要用软件做个计数器,在接收到倒数一个字节数时,设置UCTXSTP=1,这样在接收完下一个数据后,MSP430会自动发送N-ACK信号,并且发送停止信号,并停止从从机读数上来.

  • 另外关于BUFFER中的数据会不会被新的数据覆盖,不用担心,因为:

    If UCBxRXBUF is not read the master holds the bus during reception of the last data bit and until the UCBxRXBUF is read.

    UCBxRXBUF的数据不被读出,MSP430会拉住总线直到BUF的数被读走.

  • 嗯,虽然没及时看到您的回复,但已经在上周三解决了,问题就是你说的,得在最后一个接收的字节到来时设置UCTXSTP=1,我之前是在接收所有字节完设置UCTXSTP=1,所以得到的数据怎么都不对劲。好的,谢谢TI的大虾了。

  • 自认为硬件I2C都调试好了,但昨天又发现了奇怪的问题,下面是我读slave device数据的一小段代码(问题在代码注释中提到):

    //简单的读EEPROM的程序,写地址有应答,用的等待读标志UCB0RXIFG来读取数据,没有用到中断
    void Read_EEPROM(unsigned char row,unsigned char page)
    {
      unsigned char i=6,Rx_data[6];
      while (UCB0CTL1 & UCTXSTP);
      UCB0CTL1 |= UCTR + UCTXSTT;
      UCB0I2CSA = 0x57;
      while((IFG2&UCB0TXIFG)==0);
      UCB0TXBUF = row;
      while((IFG2&UCB0TXIFG)==0);//(1)?程序时常会在这句卡住不运行
      UCB0TXBUF = page;
    //上面部分是写EEPROM设备地址和读地址(page,row) 
    //下面部分是从指定的地址读6个字节
      IFG2 &= ~UCB0TXIFG;
      UCB0CTL1 &=~UCTR;
      UCB0CTL1 |=UCTXSTT;
      while((IFG2&UCTXSTT)==1);  //等待从机地址是否应答
      while(i--)                //(2)?单步调试的时候,每运行一行程序, UCB0RXBUF的值都会发生变化,最后得到的值也乱七八糟 
       {
         while((IFG2&UCB0RXIFG)==0);
         if(i)
         {
           Rx_data[i] =UCB0RXBUF;        
           if(i==1)UCB0CTL1 |= UCTXSTP;
         }
        else Rx_data[i] =UCB0RXBUF;
       }
    }

    请大虾指点一下啊,我现在在I2C上挂了3个不同片子,有时运行挺好的,但现在又不行了(单个测试也是),出现的问题也比较类似。应该是硬件MSP430的I2C配置问题,针对我程序我提出了两点疑问,请大神解释下why,多谢!!!