This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

I2C transmit & receive between ALS OPT3006 & 8051

I'd like to ask for solution to let the microcontroller (MCU) get data from ALS (ambient light sensor).I'm wondering why my MCU can't get ACK (acknowledge signal) low? In this program I have 2 functions: ALS_config() is to send command from MCU to modify settings in the ALS. MCU_read() is to let MCU read lux data from ALS.

Currently, ALS_config() can get ACK = 0 after the data byte was sent. It means that it works well. But MCU_read() function get ACK = 1, means no acknowledge signal. I think that my program is in the right form compare with the conventional I2C protocol. www.robot-electronics.co.uk/i2c-tutorial

Please help me point out the wrong part in my code.

void main(void)
{

    MCU_Initial();

    Initial_Variable();

    delay1m(500); //Wait FPGA Ready

    FPGA_TEST();
    delay1m(5);



    while(1)
    {
        RS232Control();

            ALS_to_MCU();
        if(flagstep==1 || flagstep_down==1)
        {
            Main_Pattern();
        }

    }
}

 void I2C_START(void)
{
    delay1m(6);
    ACK_f = 0;
    I2C_SDA = 1;
    delay1m(2);
    I2C_SCL = 1;
    delay1m(8);
    I2C_SDA = 0;
    delay1m(5);
    I2C_SCL = 0;
    delay1m(5);
}

//=======================================================================================
// I2C_1 Ack (EEPROM)
//=======================================================================================
void I2C_ACK(void)
{
    delay1m(3);
    I2C_SDA = 1;
    delay1m(1);
    I2C_SCL = 1;
    delay1m(3);
    if(!I2C_SDA)
        ACK_f = 1;
    delay1m(2);
    I2C_SCL = 0;
    delay1m(1);
    I2C_SDA = 0;
    delay1m(5);
}

void I2C_NAK()
{
    I2C_SDA = 1;
    I2C_SCL = 1;
    delay1m(1);
    I2C_SCL = 0;
    I2C_SDA = 1;
}

//=======================================================================================
// I2C_1 Stop (EEPROM)
//=======================================================================================
void I2C_STOP(void)
{
    I2C_SCL = 0;
    I2C_SDA = 0;
    delay1m(8);
    I2C_SCL = 1;
    delay1m(2);
    I2C_SDA = 1;
}

void I2C_RESET(void)
{
    unsigned char x;

    I2C_START();
    for(x=0x00;x<=0x09;x++) //EEPROM restart 9 times is avoided unexpected state
        {
            I2C_SDA = 1;
            I2C_SCL = 0;
            delay1m(2);
            I2C_SCL = 1;
            delay1m(2);
        }
    I2C_START();
    I2C_STOP();
    delay1m(2);
}

//=======================================================================================
void I2C_TX(unsigned char Tx_data)
{
    unsigned char x;
    for(x=0;x<8;x++)
    {
        I2C_SCL = 0;
        delay1m(1);
        if(Tx_data & 0x80)
            I2C_SDA = 1;
        else
            I2C_SDA = 0;
        Tx_data <<= 1;
        delay1m(1);
        I2C_SCL = 1;
        delay1m(2);
    }
    I2C_SCL = 0;
}


//=======================================================================================
unsigned char I2C_RX(void)
{
        unsigned char x;
    I2C_SDA = 1;
    delay1m(2);
    for(x=0;x<8;x++)
    {
        I2C_rx_buf <<= 1;
        I2C_SCL = 1;
        delay1m(1);
        if(I2C_SDA)
            I2C_rx_buf |= 0x01;
        else
            I2C_rx_buf &= 0xfe;
        delay1m(2);
        I2C_SCL = 0;
        delay1m(3);
    }
        return I2C_rx_buf;
    delay1m(2);

}

/////        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();
}

void MCU_read(unsigned char slave_write,unsigned char slave_read)
{
    unsigned char i, ALS_MSB, ALS_LSB;
    unsigned int ALS_lux;

    //////                      Partial write   ////////
        I2C_START();
        I2C_TX(slave_write);
        I2C_ACK();
        I2C_TX(0x00);
        I2C_ACK();
//      I2C_STOP();

////////////////    Read from ALS       /////////////////////////////

        I2C_START();
        I2C_TX(slave_read);
        I2C_ACK();
    I2C_RX();
        ALS_LSB = I2C_rx_buf;
        ALS_MSB = I2C_rx_buf<<8;
        I2C_ACK();

/*  This part doesn't work. So I marked it.
        I2C_SDA = 0;
        delay1m(1);
        I2C_SCL = 1;
        delay1m(1);
        I2C_SCL = 0;
        delay1m(1);
        I2C_SDA = 0;
*/
        delay1m(1);

        I2C_RX();
        ALS_MSB = I2C_rx_buf;
    I2C_ACK();
        //      I2C_NAK();
        I2C_STOP();

        ALS_lux = ALS_MSB | ALS_LSB;

}

//                  MCU read data from ALS
//////////////////////////////////

//void ALS_to_MCU(unsigned char slave_write,unsigned char slave_read,unsigned char dataA,unsigned char dataB)
void ALS_to_MCU(void)
{
    ALS_config(0x88,0xC4,0x10);
    MCU_read(0x88,0x89);
}

Parents
  • A mass.
    You tried to start another transaction while current in process.
    Also I don't know why you generate a NACK... to whom? You wanna ALS to ACK your NACK?

    And I suggest you to combine ACK/NACK in each TX()/RX() function.

Reply
  • A mass.
    You tried to start another transaction while current in process.
    Also I don't know why you generate a NACK... to whom? You wanna ALS to ACK your NACK?

    And I suggest you to combine ACK/NACK in each TX()/RX() function.

Children
No data