8051 MCU I2C сигналы не отвечают - PullRequest
0 голосов
/ 07 июня 2018

Я застрял на проблеме связи I2C, и мне нужна ваша помощь

В настоящее время я использую микроконтроллер (MCU) C8051F130 .Мне нужно связаться между MCU и датчиком через I2C.

Как я знаю, I2C на этом MCU может быть включен битом ENSMB в регистре SMB0CN ,Но когда я устанавливаю этот бит в 1 и проверяю состояние SMB0CN в режиме отладки IDE, я всегда вижу его SMB0CN = 0x00.Это означает, что I2C все еще не включен.В результате сигналы I2C SDA & SCL на выходе MCU всегда имеют высокий статус .

Я также проверил подтягивающий резистор на портах MCA SDA и SCL, они подключены к резистору 10 кОм .Я думаю, что все должно быть в порядке.

Вот мой код для настройки регистра I2C и отправки / получения / подтверждения.Пожалуйста, дайте мне предложение.

#define  SMB0_PAGE         0x00     /* SMBUS 0  */

void main()
{
    SMBUS_Initial();
}

// I2C SFR setting
    void SMBUS_Initial()
{
    unsigned char SFRPAGE_BUF;  // SFR page of SMB0CN is 0
    SFRPAGE_BUF = SFRPAGE;
    SFRPAGE = SMB0_PAGE;
/*  
    BUSY = 0;

//  AA = 1;
    STA = 1;
    STO = 1;*/
    ENSMB = 1;
    SFRPAGE = SFRPAGE_BUF;
}
sfr SMB0CN   = 0xC0;    /* SMBUS 0 CONTROL */

/* SMB0CN 0xC0 */
sbit BUSY   = SMB0CN ^ 7;           // SMBUS 0 BUSY                   
sbit ENSMB  = SMB0CN ^ 6;           // SMBUS 0 ENABLE                  
sbit STA    = SMB0CN ^ 5;           // SMBUS 0 START FLAG              
sbit STO    = SMB0CN ^ 4;           // SMBUS 0 STOP FLAG               
sbit SI     = SMB0CN ^ 3;           // SMBUS 0 INTERRUPT PENDING FLAG  
sbit AA     = SMB0CN ^ 2;           // SMBUS 0 ASSERT/ACKNOWLEDGE FLAG 
sbit SMBFTE = SMB0CN ^ 1;           // SMBUS 0 FREE TIMER ENABLE       
sbit SMBTOE = SMB0CN ^ 0;

// I2C communication
void I2C_START()
{
    unsigned char SFRPAGE_BUF;
    SFRPAGE_BUF = SFRPAGE;

    SFRPAGE = CONFIG_PAGE;

    Delay2us(6);
    I2C_SDA = 1;
    Delay2us(2);
    I2C_SCL = 1;
    Delay2us(8);
    I2C_SDA = 0;
    Delay2us(5);
    I2C_SCL = 0;
    Delay2us(5);
    SFRPAGE = SFRPAGE_BUF;
}
//=======================================================================================

// I2C_1 Ack by slave
//=======================================================================================
void I2C_ACK(void)
{

    unsigned char SFRPAGE_BUF;
    SFRPAGE_BUF = SFRPAGE;

    SFRPAGE = CONFIG_PAGE;

    Delay2us(3);
    I2C_SDA = 1;
    Delay2us(1);
    I2C_SCL = 1;
    Delay2us(3);
    if(!I2C_SDA)
  //      ACK_f = 1;
    Delay2us(2);
    I2C_SCL = 0;
    Delay2us(1);
    I2C_SDA = 0;
    Delay2us(5);
        SFRPAGE = SFRPAGE_BUF;
}

// I2C_1 Ack by master
//=======================================================================================
void I2C_ACK_master()
{
    unsigned char SFRPAGE_BUF;
    SFRPAGE_BUF = SFRPAGE;

    SFRPAGE = CONFIG_PAGE;

    I2C_SDA = 0;
    I2C_SCL = 1;
    Delay2us(1);
    I2C_SCL = 0;
    I2C_SDA = 1;
    SFRPAGE = SFRPAGE_BUF;
}

void I2C_NAK()
{
    unsigned char SFRPAGE_BUF;
    SFRPAGE_BUF = SFRPAGE;

    SFRPAGE = CONFIG_PAGE;

    I2C_SDA = 1;
    I2C_SCL = 1;
    Delay2us(1);
    I2C_SCL = 0;
    I2C_SDA = 1;
    SFRPAGE = SFRPAGE_BUF;
}

//=======================================================================================
// I2C Start
//=======================================================================================


//=======================================================================================
// I2C Stop
//=======================================================================================
void I2C_STOP(void)
{
    unsigned char SFRPAGE_BUF;
    SFRPAGE_BUF = SFRPAGE;

    SFRPAGE = CONFIG_PAGE;

    I2C_SCL = 0;
    I2C_SDA = 0;
    Delay2us(8);
    I2C_SCL = 1;
    Delay2us(5);
    I2C_SDA = 1;
    SFRPAGE = SFRPAGE_BUF;
}

// I2C Tx
//=======================================================================================
void I2C_TX(unsigned char Tx_data)
{
    unsigned char x;
    unsigned char SFRPAGE_BUF;
    SFRPAGE_BUF = SFRPAGE;

    SFRPAGE = CONFIG_PAGE;


    for(x=0;x<8;x++)
    {
        I2C_SCL = 0;
        Delay2us(1);
        if(Tx_data & 0x80)
                I2C_SDA = 1;
        else
                I2C_SDA = 0;
        Tx_data <<= 1;
        Delay2us(1);
        I2C_SCL = 1;
        Delay2us(2);
    }
    I2C_SCL = 0;

    SFRPAGE = SFRPAGE_BUF;
}

//=======================================================================================
// I2C Rx
//=======================================================================================
unsigned char I2C_RX(unsigned char I2C_ACK)
{
    unsigned char x;
    unsigned char Rx_Data, I2C_rx_buf;

    unsigned char SFRPAGE_BUF;
    SFRPAGE_BUF = SFRPAGE;

    SFRPAGE = CONFIG_PAGE;

    I2C_SDA = 1;
//  Delay2us(10);
    Delay2us(2);

        for(x=0;x<8;x++)
    {
        I2C_rx_buf <<= 1;
        do{
            I2C_SCL = 1;
        }while(I2C_SCL == 0);
        Delay2us(1);
        if(I2C_SDA)
                I2C_rx_buf |= 1;
        I2C_SCL = 0;
    }
        if(I2C_ACK)
            I2C_SDA = 0;
        else
            I2C_SDA = 1;
        Delay2us(2);
        I2C_SCL = 0;
        I2C_SDA = 1;

    return I2C_ACK;

        SFRPAGE = SFRPAGE_BUF;
}

/////        Configuration register     ///////////
void ALS_config(unsigned char slave_write,unsigned char dataA,unsigned char dataB)   
{   
        I2C_START();
    I2C_TX(slave_write);
        I2C_ACK();  
    I2C_TX(0x01);
        I2C_ACK();
        I2C_TX(dataA);
//  I2C_RX();
        I2C_ACK();
        I2C_TX(dataB);
//  I2C_RX();
        I2C_ACK();  
    I2C_STOP();
}

unsigned int MCU_read(unsigned char slave_write,unsigned char slave_read)    
{   
    unsigned char i, ALS_MSB, ALS_LSB, DSI_val[52];
    unsigned int ALS_lux;

// High-speed I2C ////  
        I2C_START();
        I2C_TX(0x08);
        I2C_NAK();
/////////////////
    //////                      Partial write   ////////
        I2C_START();
        I2C_TX(slave_write);
        I2C_ACK();
        I2C_TX(0x00);
        I2C_ACK();
        I2C_STOP();
        delay1m(1);
////////////////    Read from ALS       /////////////////////////////

        I2C_START();
        I2C_TX(slave_read);
        I2C_ACK();
    I2C_RX(I2C_ACK);
        I2C_ACK_master();
        ALS_MSB = I2C_rx_buf;
//      ALS_MSB = ALS_MSB&0x0F;
//      ALS_MSB = I2C_rx_buf<<8;
        delay1m(3);
        I2C_RX(I2C_ACK);
        I2C_ACK_master();
        I2C_NAK();
        ALS_LSB = I2C_rx_buf;
        I2C_STOP(); 

        ALS_lux = ALS_MSB | ALS_LSB;

        return ALS_lux; 
}

void low_limit_ALS(unsigned char slave_write,unsigned char low_limit_MSB,unsigned char low_limit_LSB)   
{
        I2C_START();
    I2C_TX(slave_write);
        I2C_ACK();  
    I2C_TX(0x02);
        I2C_ACK();
        I2C_TX(low_limit_MSB);
//  I2C_RX();
        I2C_ACK();
        I2C_TX(low_limit_LSB);
//  I2C_RX();
        I2C_ACK();  
    I2C_STOP();
}

void high_limit_ALS(unsigned char slave_write,unsigned char high_limit_MSB,unsigned char high_limit_LSB)    
{
        I2C_START();
    I2C_TX(slave_write);
        I2C_ACK();  
    I2C_TX(0x03);
        I2C_ACK();
        I2C_TX(high_limit_MSB);
//  I2C_RX();
        I2C_ACK();
        I2C_TX(high_limit_LSB);
//  I2C_RX();
        I2C_ACK();  
    I2C_STOP();
}
...