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的使用方式

Other Parts Discussed in Thread: MSP430F5436

請問各位

當我下達讀取設備指令後

要如何去判斷從設備有資料回覆?

以下是我下達讀取的方式..

UCB3CTL1 &= ~UCTR;  
UCB3CTL1 |= UCTXSTT;
while( !(UCB3IFG & UCTXIFG));

while( !(UCB3IFG & UCRXIFG));
BUFF[0] = UCB3RXBUF;
while( !(UCB3IFG & UCRXIFG));
BUFF[1] = UCB3RXBUF;
UCB3CTL1 |=UCTXNACK; // 發送停止位和NACK位
UCB3CTL1 |=UCTXSTP;

上面這些代碼 我比較想知道

while( !(UCB3IFG & UCRXIFG)); 這行的用意到底是不是真的能確保讀取資料的完整性?

我看資料文件有提到說當UCBxRXBUF被讀取後UCRXIFG會被自動重置

這樣寫能否確定可以連續讀取兩個從設備的的回傳資料?

感謝回覆

  • Hi, Cpo

    能不能先讓我知道你是用MSP430那一個料號?

    謝謝.

  • 很抱歉 沒說明是使用哪款....

    我使用的是MSP430F5436

    感謝回覆

  • CPO您好,

    1.關於是否能確保資料的完整性:
    當RxBUFFER收到資料時,UCRxIFG會被設為1
    while( !(UCB3IFG & UCRXIFG));  while迴圈才能跳出
    繼續執行下面的程式

    2.關於要接收多個從設備:
    我想你必須使用另外一組I2C,MSP430F5436應該有四組的I2C可以用
    似乎只有在MSP430當MASTER,並且為發送端時才能用同一組的I2C去指定SLAVE ADDRESS
    可參考下面這網址:
    http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/t/105944.aspx

  • Hsiung 您好,

    很感謝您的回覆

    對於資料完整性 我發現我遇到另一種奇怪現象

    以下片段程式碼是指發送讀取指令至設備並且讀回兩byte資料,

    UCB3CTL1 &= ~UCTR;  
    UCB3CTL1 |= UCTXSTT;
    while( !(UCB3IFG & UCTXIFG));

    while( !(UCB3IFG & UCRXIFG));
    BUFF[0] = UCB3RXBUF;     // 讀取第一個byte
    while( !(UCB3IFG & UCRXIFG));
    BUFF[1] = UCB3RXBUF;     // 讀取第二個byte
    UCB3CTL1 |=UCTXNACK; // 發送停止位和NACK位 
    UCB3CTL1 |=UCTXSTP;

    當程式執行完一次後,UCB3RXBUF並沒有被清除掉,導致 第二次執行該命令時

    BUFF[0] 會讀到前一次回圈中的UCB3RXBUF的值

    這個問題讓我很困惑,當我在這個命令前加入UCB3RXBUF=0; 所有動作才看起來正常?

    請問為甚麼會這樣?

    感謝回覆

  • 按照Datasheet上的说法,UCRXIFG位应该在读UCBxRXBUF之后就被reset, 从你上面的描述看BUFF[0] = UCB3RXBUF 这个语句并未reset UCRXIFG. 

    1. BUFF[] 这个数组只有赋值,没有使用,一定优化级别的编译器可能会把BUFF[0] = UCB3RXBUF 这句话给优化掉,你可以打开汇编的代码看下这句话是否有被编译器优化掉.

    2. UCB3RXBUF=0; 这句话按照数据手册上描述应该是非法的,UCB3RXBUF寄存器是RO寄存器,对它赋值应该是不成功的,而且即使你能给UCB3RXBUF赋值0,也不能代表I2C的RXBUF为空,从而触发RESET UCRXIFG。<0值并不是空>。 所以我建议你在UCB3RXBUF=0; 这个语句位置加上一个延时,看一下问题是否依然存在.

    3. UCRXIFG 标志位是WR,即可读写的,为了确保操作正确你可以用软件清零UCRXIFG标志位。

  • 您好:

    1.BUFF[]這個數值在經過取值後, 是有經過運算後將值傳遞出去, 如下 

    heading= (BUFF[0]<< 8) | (BUFF[1]);

    return heading; 

    所以應該會將UCRXIFG清除

    2.我曾經嘗試過延遲一段時間在讀取,依舊無法解決問題

    3.是否將UCRXIFG清零後UCBxRXBUF就會被重置? .因為我有透過示波器去看.動作上都正常就是UCBxRXBU硬是被延遲一個時程((僅第一次執行時正常)

    感謝回覆

  • Dear Cpo,

    應該是當RxBUF滿的時候,UCRXIFG會被設為1,通知CPU去讀RxBUF的資料
    當CPU開始讀RxBUF的資料時,UCRXIFG會自動設為0
    在CPU讀完RxBUF後,RxBUF應該就是空的了

  • 做个测试,把接收到的数据都读到一个数组,不管是否正确。

    然后把你主机发送的数据贴出来对比一下,看能不能找到问题。

    主机发送的数据最好是特定的值,比如,1-10,这样比较容易看是什么问题.

    有的MCU虽然只有一个RXBUF reg, 但是实际上有2级FIFO。先看下实际数据才方便分析