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.

msp430f2013 硬件从机iic

从机程序如下(官方domon):

#include  <msp430x20x2.h>

char SLV_Data = 0;                     // Variable for transmitted data
char SLV_Addr = 0x90;                  // Address is 0x48<<1 for R/W
int I2C_State = 0;                     // State variable

void main(void)
{
  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
  P1REN |= 0xC0;                       // P1.6 & P1.7 Pullups
  P1DIR = 0xFF;                        // Unused pins as outputs
  P2OUT = 0;
  P2DIR = 0xFF;

  USICTL0 = USIPE6+USIPE7+USISWRST;    // Port & USI mode setup
  USICTL1 = USII2C+USIIE+USISTTIE;     // Enable I2C mode & USI interrupts
  USICKCTL = USICKPL;                  // Setup clock polarity
  USICNT |= USIIFGCC;                  // Disable automatic clear control
  USICTL0 &= ~USISWRST;                // Enable USI
  USICTL1 &= ~USIIFG;                  // Clear pending flag
  _EINT();

  while(1)
  {
    LPM0;                              // CPU off, await USI interrupt
    _NOP();                            // Used for IAR
  }
}

//******************************************************
// USI interrupt service routine
//******************************************************
#pragma vector = USI_VECTOR
__interrupt void USI_TXRX (void)
{
  if (USICTL1 & USISTTIFG)             // Start entry?
  {
    P1OUT |= 0x01;                     // LED on: Sequence start
    I2C_State = 2;                     // Enter 1st state on start
  }

  switch(I2C_State)
    {
      case 0: //Idle, should not get here
              break;

      case 2: //RX Address
              USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, RX Address
              USICTL1 &= ~USISTTIFG;   // Clear start flag
              I2C_State = 4;           // Go to next state: check address
              break;

      case 4: // Process Address and send (N)Ack
              if (USISRL & 0x01)       // If read...
                SLV_Addr++;            // Save R/W bit
              USICTL0 |= USIOE;        // SDA = output
              if (USISRL == SLV_Addr)  // Address match?
              {
                USISRL = 0x00;         // Send Ack
                P1OUT &= ~0x01;        // LED off
                I2C_State = 8;         // Go to next state: TX data
              }
              else
              {
                USISRL = 0xFF;         // Send NAck
                P1OUT |= 0x01;         // LED on: error
                I2C_State = 6;         // Go to next state: prep for next Start
              }
              USICNT |= 0x01;          // Bit counter = 1, send (N)Ack bit
              break;

      case 6: // Prep for Start condition
              USICTL0 &= ~USIOE;       // SDA = input
              SLV_Addr = 0x90;         // Reset slave address
              I2C_State = 0;           // Reset state machine
              break;

      case 8: // Send Data byte
              USICTL0 |= USIOE;        // SDA = output
              USISRL = SLV_Data;       // Send data byte
              USICNT |=  0x08;         // Bit counter = 8, TX data
              I2C_State = 10;          // Go to next state: receive (N)Ack
              break;

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

      case 12:// Process Data Ack/NAck
              if (USISRL & 0x01)       // If Nack received...
              {
                P1OUT |= 0x01;         // LED on: error
              }
              else                     // Ack received
              {
                P1OUT &= ~0x01;        // LED off
                SLV_Data++;            // Increment Slave data
              }
              // Prep for Start condition
              USICTL0 &= ~USIOE;       // SDA = input
              SLV_Addr = 0x90;         // Reset slave address
              I2C_State = 0;           // Reset state machine
              break;
    }

  USICTL1 &= ~USIIFG;                  // Clear pending flags
}

主机是f5438用的模拟口:

uint8 Get_SDA_1_Status(void)  //读sda io口值
{
    Set_Data_In();
    if(SDA_PIN) //if(P1_0)
    {
       return 1;
    }
    else
    {
       return 0;
    }       
}

void iic_init() // icc
{
     Set_SDA_1_High(); 
     Set_SCLK_1_High();
}
void Start_I2c()  //start
{
  Set_SCLK_1_High();
  delay_us(5);
   Set_SDA_1_Low();
    delay_us(5);
  
  Set_SCLK_1_Low(); 
   delay_us(5);
 
}
void Stop_I2c()  // stop
{
  Set_SDA_1_Low();  /*发送结束条件的数据信号*/
   More_Delay_Test();
  Set_SCLK_1_High();  /*结束条件建立时间大于4μs*/
   More_Delay_Test();
  Set_SDA_1_High();  /*发送I2C总线结束信号*/
   More_Delay_Test();
}

void Ack_I2c(uchar a)  //ack
{
 
  Set_SCLK_1_Low();
  More_Delay_Test();
  if(a==0)
    Set_SDA_1_Low();     //*在此发出应答或非应答信号
  else
    Set_SDA_1_High();
  More_Delay_Test();  
 
  Set_SCLK_1_High();
  More_Delay_Test();
 
  Set_SCLK_1_Low();                //*清时钟线,钳住I2C总线以便继续接收
  More_Delay_Test(); 

}
void  Simulate_SendByte(uchar c)
{
 uchar BitCnt;
  Set_SCLK_1_Low();
 for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
 {
  
     if((c<<BitCnt)&0x80)
          Set_SDA_1_High();   /*判断发送位*/   //Set_Data_In();
     else  Set_SDA_1_Low(); 
       delay_us(5);  delay_us(5);
   
     Set_SCLK_1_High();               /*置时钟线为高,通知被控器开始接收数据位*/
     delay_us(5);  delay_us(5);
     Set_SCLK_1_Low();
      delay_us(5);  delay_us(5);
 }

      Set_SDA_1_High(); 
  delay_us(5);
    Set_Data_In();
  
    Set_SCLK_1_High();

   delay_us(5);
   
    if(Get_SDA_1_Status()==1)
          ack=0;    
    else
          ack=1;        /*判断是否接收到应答信号*/
    Set_SCLK_1_Low();  //20130911
    delay_us(5);
   // More_Delay_Test();
    //Set_SCLK_1_Low();
}

uchar Simulate_RcvByte()
{
  uchar retc;
  uchar BitCnt;
  retc=0;
  Set_Data_In();
  for(BitCnt=0;BitCnt<8;BitCnt++)
  {
    retc=retc<<1;
    Set_SCLK_1_Low();         //*置时钟线为低,准备接收数据位
    More_Delay_Test();
    Set_SCLK_1_High();        //*置时钟线为高使数据线上数据有效
    More_Delay_Test();
    if(Get_SDA_1_Status()==1)
    retc = retc+1;            //*读数据位,接收的数据位放入retc中
    More_Delay_Test();
  } 
  return(retc);
}
uint8 read_data()
{
    Start_I2c();
    Simulate_SendByte(0x90);
    if(ack==0)return(0);
    More_Delay_Test();  More_Delay_Test();
   
    Simulate_SendByte(0xa1);
    if(ack==0)return(0);
    More_Delay_Test();  More_Delay_Test();
   
    data=Simulate_RcvByte();
    Ack_I2c(1);
    Stop_I2c();
    return (data);
}

一直都收不到从机响应怎么回事啊?这段模拟的iic程序是我读取其他传感器所用的程序,直接摘抄过来的《求大神帮忙~~