Me gustaría pedir una solución para que el microcontrolador (MCU) obtenga datos del ALS (sensor de luz ambiental). Me pregunto por qué mi MCU no puede tener un ACK (señal de reconocimiento) bajo En este programa tengo 2 funciones: ALS_config () es enviar un comando desde MCU para modificar las configuraciones en el ALS. MCU_read () es permitir que MCU lea datos de lux de ALS.
Actualmente, ALS_config () puede obtener ACK = 0 después de que se envió el byte de datos. Significa que funciona bien. Pero la función MCU_read () obtiene ACK = 1, significa que no hay señal de reconocimiento. Creo que mi programa está en la forma correcta en comparación con el protocolo I2C convencional. enlace
Por favor, ayúdame a señalar la parte incorrecta en mi código.
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);
}