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.

关于msp430g2231控制外部eeprom

Other Parts Discussed in Thread: MSP430G2221我选用的外部eeprom是24c64,之前所用单片机是使用usci模块完成的,但是在g系列只有usi模块,请问只种情况下如何控制外部eeprom,能否提供一些关键代码,谢谢
  • 24C64是I2C接口的,USI接口是支持I2C的,您可以参考USCI的代码进行修改

  • 现在是握手信号ACK总是收不到,您有例程可以让我参考一下么?

  • 我这边倒是没有针对24C64的参考代码。建议您使用示波器抓图,确定是软件问题还是硬件问题。

  • 例程你可以去TI主页上对应该芯片的资料里找到code example。ACK收不到,查看是电路是否正确,上拉电阻是否连上,速率是否一致。

  • 谢谢您的回答,已经用f2112做了,感觉g系列还是不好用

  • 谢谢您的回答,已经用f2112做了,感觉g系列还是不好用

  • G2xxx是性价比极高的系列,楼主还需要耐心啊,可以省钱不少,下面是代码,请查看。

     

    //******************************************************************************
    //  MSP430G2x21/G2x31 Demo - I2C Master Transmitter / Reciever, multiple bytes
    //
    //  Description: I2C Master communicates with I2C Slave using
    //  the USI. Master data should increment from 0x55 with each transmitted byte
    //  and Master determines the number of bytes recieved, set by
    //  the Number_of_Bytes value. LED off for address or data Ack;
    //  LED on for address or data NAck.
    //  ACLK = n/a, MCLK = SMCLK = Calibrated 1MHz
    //
    //
    //  ***THIS IS THE MASTER CODE***
    //
    //                  Slave                      Master
    //     (msp430g2x21_usi_15.c)
    //             MSP430G2x21/G2x31          MSP430G2x21/G2x31
    //             -----------------          -----------------
    //         /|\|              XIN|-    /|\|              XIN|-
    //          | |                 |      | |                 |
    //          --|RST          XOUT|-     --|RST          XOUT|-
    //            |                 |        |                 |
    //      LED <-|P1.0             |        |                 |
    //            |                 |        |             P1.0|-> LED
    //            |         SDA/P1.7|------->|P1.6/SDA         |
    //            |         SCL/P1.6|<-------|P1.7/SCL         |
    //
    //  Note: internal pull-ups are used in this example for SDA & SCL
    //
    //  D. Dang
    //  Texas Instruments Inc.
    //  October 2010
    //  Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
    //******************************************************************************

    #include <msp430g2221.h>


    #define number_of_bytes 5                   // How many bytes?

    void Master_Transmit(void);
    void Master_Recieve(void);

    void Setup_USI_Master_TX(void);
    void Setup_USI_Master_RX(void);

    char MST_Data = 0x55;                       // Variable for transmitted data
    char SLV_Addr = 0x90;                      
    int I2C_State, Bytecount, Transmit = 0;     // State variable
    void Data_TX (void);
    void Data_RX (void);
    void main(void)
    {
      volatile unsigned int i;                  // Use volatile to prevent removal

      WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog
      if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                    
      { 
        while(1);                               // If calibration constants erased
                                                // do not load, trap CPU!!
      }

      BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
      DCOCTL = CALDCO_1MHZ;

      P1OUT = 0xC0;                             // P1.6 & P1.7 Pullups, others to 0
      P1REN |= 0xC0;                            // P1.6 & P1.7 Pullups
      P1DIR = 0xFF;                             // Unused pins as outputs
      P2OUT = 0;
      P2DIR = 0xFF;



      while(1)
      {
        Master_Transmit();
        _NOP();                                 // Used for IAR

        Master_Recieve();
        _NOP();
     }
    }

    /******************************************************
    // USI interrupt service routine
    // Data Transmit : state 0 -> 2 -> 4 -> 10 -> 12 -> 14
    // Data Recieve  : state 0 -> 2 -> 4 -> 6 -> 8 -> 14
    ******************************************************/
    #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
    }


    void Data_TX (void){

                  USISRL = MST_Data++;          // Load data byte
                  USICNT |=  0x08;              // Bit counter = 8, start TX
                  I2C_State = 10;               // next state: receive data (N)Ack
                  Bytecount++;
    }

    void Data_RX (void){
        USICTL0 &= ~USIOE;                  // SDA = input --> redundant
            USICNT |=  0x08;                    // Bit counter = 8, RX data
            I2C_State = 6;                      // Next state: Test data and (N)Ack
            P1OUT &= ~0x01;                     // LED off
            }


    void Setup_USI_Master_TX (void)
    {
      _DINT();
      Bytecount = 0;
      Transmit = 1;
      USICTL0 = USIPE6+USIPE7+USIMST+USISWRST;  // Port & USI mode setup
      USICTL1 = USII2C+USIIE;                   // Enable I2C mode & USI interrupt
      USICKCTL = USIDIV_7+USISSEL_2+USICKPL;    // USI clk: SCL = SMCLK/128
      USICNT |= USIIFGCC;                       // Disable automatic clear control
      USICTL0 &= ~USISWRST;                     // Enable USI
      USICTL1 &= ~USIIFG;                       // Clear pending flag
      _EINT();
    }


    void Setup_USI_Master_RX (void)
    {
      _DINT();
      Bytecount = 0;
      Transmit = 0;
      USICTL0 = USIPE6+USIPE7+USIMST+USISWRST;  // Port & USI mode setup
      USICTL1 = USII2C+USIIE;                   // Enable I2C mode & USI interrupt
      USICKCTL = USIDIV_7+USISSEL_2+USICKPL;    // USI clks: SCL = SMCLK/128
      USICNT |= USIIFGCC;                       // Disable automatic clear control
      USICTL0 &= ~USISWRST;                     // Enable USI
      USICTL1 &= ~USIIFG;                       // Clear pending flag
      _EINT();

    }

    void Master_Transmit(void){
    Setup_USI_Master_TX();
        USICTL1 |= USIIFG;                      // Set flag and start communication
        LPM0;                                   // CPU off, await USI interrupt
        __delay_cycles(10000);                  // Delay between comm cycles
    }
    void Master_Recieve(void){
      Setup_USI_Master_RX();
      USICTL1 |= USIIFG;                        // Set flag and start communication
      LPM0;                                     // CPU off, await USI interrupt
      __delay_cycles(10000);                    // Delay between comm cycles
    }

     

  • USI可以实现IIC接口,但是USI模块较简洁,实现IIC时要注意时序。