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.

MSP430F2012官网例程上的USI_VECTOR触发条件

Other Parts Discussed in Thread: MSP430F2012

官网提供的MSP430F2012的例程关于USI_VECTOR触发条件该如何理解,

个人理解是:收发数据赋值给USISRL,然后通过USISRL的移位来值接收或发出去,

但现在的疑问是:每一次的移位是否引起一次中断,因为每一个case都是break,中断结束,那如何触发的中断完成一整个发送或接收数据的过程的?

  • #pragma vector = USI_VECTOR
    __interrupt void USI_TXRX (void)
    switch(__even_in_range(I2C_State,14))
    {
    case 0: // Generate Start Condition & send address to slave
    P1OUT |= 0x01; // LED on: sequence start
    Bytecount = 0;
    USISRL = 0x00; // Generate Start Condition...
    USICTL0 |= USIGE+USIOE;
    USICTL0 &= ~USIGE;
    if (Transmit == 1){
    USISRL = 0x90; // Address is 0x48 << 1 bit + 0 (rw)
    }
    if (Transmit == 0){
    USISRL = 0x91; // 0x91 Address is 0x48 << 1 bit
    // + 1 for Read
    }
    USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, TX Address
    I2C_State = 2; // next state: rcv address (N)Ack
    break;

    case 2: // Receive Address Ack/Nack bit
    USICTL0 &= ~USIOE; // SDA = input
    USICNT |= 0x01; // Bit counter=1, receive (N)Ack bit
    I2C_State = 4; // Go to next state: check (N)Ack
    break;

    case 4: // Process Address Ack/Nack & handle data TX

    if(Transmit == 1){
    USICTL0 |= USIOE; // SDA = output
    if (USISRL & 0x01) // If Nack received...
    { // Send stop...
    USISRL = 0x00;
    USICNT |= 0x01; // Bit counter=1, SCL high, SDA low
    I2C_State = 14; // Go to next state: generate Stop
    P1OUT |= 0x01; // Turn on LED: error
    }
    else
    { // Ack received, TX data to slave...
    USISRL = MST_Data++; // Load data byte
    USICNT |= 0x08; // Bit counter = 8, start TX
    I2C_State = 10; // next state: receive data (N)Ack
    Bytecount++;
    P1OUT &= ~0x01; // Turn off LED
    break;
    }
    } if(Transmit == 0){

    if (USISRL & 0x01) // If Nack received
    { // Prep Stop Condition
    USICTL0 |= USIOE;
    USISRL = 0x00;
    USICNT |= 0x01; // Bit counter= 1, SCL high, SDA low
    I2C_State = 8; // Go to next state: generate Stop
    P1OUT |= 0x01; // Turn on LED: error
    }
    else{ Data_RX();} // Ack received


    }
    break;

    case 6: // Send Data Ack/Nack bit
    USICTL0 |= USIOE; // SDA = output
    if (Bytecount <= number_of_bytes-2)
    { // If this is not the last byte
    USISRL = 0x00; // Send Ack
    P1OUT &= ~0x01; // LED off
    I2C_State = 4; // Go to next state: data/rcv again
    Bytecount++;
    }

    else //last byte: send NACK
    {
    USISRL = 0xFF; // Send NAck
    P1OUT |= 0x01; // LED on: end of comm
    I2C_State = 8; // stop condition
    }
    USICNT |= 0x01; // Bit counter = 1, send (N)Ack bit
    break;

    case 8: // Prep Stop Condition
    USICTL0 |= USIOE; // SDA = output
    USISRL = 0x00;
    USICNT |= 0x01; // Bit counter= 1, SCL high, SDA low
    I2C_State = 14; // Go to next state: generate Stop
    break;

    case 10: // Receive Data Ack/Nack bit
    USICTL0 &= ~USIOE; // SDA = input
    USICNT |= 0x01; // Bit counter = 1, receive (N)Ack bit
    I2C_State = 12; // Go to next state: check (N)Ack
    break;

    case 12: // Process Data Ack/Nack & send Stop
    USICTL0 |= USIOE;
    if (Bytecount == number_of_bytes){// If last byte
    USISRL = 0x00;

    I2C_State = 14; // Go to next state: generate Stop
    P1OUT |= 0x01;
    USICNT |= 0x01; } // set count=1 to trigger next state
    else{
    P1OUT &= ~0x01; // Turn off LED
    Data_TX(); // TX byte
    }
    break;

    case 14:// Generate Stop Condition
    USISRL = 0x0FF; // USISRL = 1 to release SDA
    USICTL0 |= USIGE; // Transparent latch enabled
    USICTL0 &= ~(USIGE+USIOE); // Latch/SDA output disabled
    I2C_State = 0; // Reset state machine for next xmt
    LPM0_EXIT; // Exit active for next transfer
    break;
    }

    USICTL1 &= ~USIIFG; // Clear pending flag
    }
  • 这些case一起来完成通讯过程的收发数据的。

    每个case处都有英文说明,就是该case在通讯过程中的功能和作用

  • 可以参考中断处理程序上面的说明,如

    /******************************************************
    // USI interrupt service routine
    // Data Transmit : state 0 -> 2 -> 4 -> 10 -> 12 -> 14
    // Data Recieve : state 0 -> 2 -> 4 -> 6 -> 8 -> 14
    ******************************************************/

    给出了相关的case顺序,如灰小子所说,这些case一起来完成通讯过程的收发数据的。
  • 中断例程好像有些问题,烧录到芯片里再用示波器观察没有信号,后面在线调试,发现根本无法实现整个流程,因为每个case完后就不会再触发下一个中断了,一直在等待,因为每个case结束都有一个break,跳出了中断,没有触发的中断条件,就不会再进中断了,麻烦审核下例程,谢谢
  • 很抱歉,我手边没有对应的板子,所以不太方便进行实际测试。我去找一下有没有相似芯片的板子测试一下
  • 请问您现在测试的是哪个程序呢?能否给出相关的路径?您现在使用的硬件是怎样的呢?
  • 我测试那个程序是MSP430f20x2系列下的USI-IIC通讯的第12个例程,我又查看了其他的例程,发现那个触发条件是根据main下的循环来触发中断的;那现在有个问题是,我用示波器测量信号时,对于改变的数据都无对应的波形出来;USISRL这个寄存器目前理解是数据传输的寄存器,是否正确
  • 输入/输出数据的16位串行寄存器(USISR):在I2C模式下,仅使用8位宽(USISRL)的USISR

    您的理解是正确的

    processors.wiki.ti.com/.../I2C_Communication_with_USI_Module
  • 现在出现的问题是:示波器捕获的信号跟设置传输的数据不一样,不清楚哪里出了问题
  • 对于msp430f2012的芯片,JTAG下载口跟IIC通讯口复用,有什么工具可以检测到收发的数据是否正确呢,除了示波器
  • 这样现象的话,感觉有可能是时序的问题
  • I2C中断中使用串口打印的话也是有可能影响时序的,所以示波器会更准确
  • 用逻辑分析仪可能比示波器更方便。