We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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); }
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.