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.

OPT3001

Other Parts Discussed in Thread: OPT3001

大家好我使用单片机读取OPT3001得数据,一点反应也没有ACK信号也没有,ADDR接地地址是0x44,下面我贴出我的代码请大神指点

void I2CStart( void )
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = E2PROM_SDA;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_SET);
DelayMs(10);
// GPIO_SetBits( GPIOA, E2PROM_SCL );
HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET);
DelayMs(10);
// GPIO_ResetBits( GPIOA, E2PROM_SDA );
HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_RESET);
DelayMs(10);
HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_RESET);
DelayMs(10);
// GPIO_ResetBits( GPIOA, E2PROM_SCL );
}

void I2CStop( void )
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = E2PROM_SDA;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_RESET);
DelayMs(10);
HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_RESET);
DelayMs(10);

HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_SET);
DelayMs(10);

HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_RESET);
DelayMs(10);

}

unsigned char I2c_getAck(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = E2PROM_SDA;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
char ack;
HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET);
DelayMs(10);
ack = HAL_GPIO_ReadPin( GPIOA, E2PROM_SDA );
HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_RESET);
return ack;
}

void I2CWriteByte( unsigned char byte )
{
unsigned char i;

for( i=0; i<8; i++ )
{
if( 0X80 & byte )
{
HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_RESET);
}

byte <<= 1;
DelayMs(10);

HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET);
DelayMs(10);
HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_RESET);
DelayMs(10);
}
// HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET);
// DelayMs(10);
I2c_getAck();
}

unsigned char I2CReadByte( void )
{
unsigned char i;
unsigned char ReadValue = 0;
GPIO_InitTypeDef GPIO_InitStruct;
unsigned char bit;

GPIO_InitStruct.Pin = E2PROM_SDA;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
for( i=0; i<8; i++ )
{
HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET);
DelayMs(10);
if( SET == HAL_GPIO_ReadPin( GPIOA, E2PROM_SDA ) )
bit = 0X01;
else
bit = 0x00;

ReadValue = (ReadValue<<1)|bit;
HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_RESET);
// DelayMs(10);
}
// HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET);
// DelayMs(10);
// GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO_Init( GPIOB, &GPIO_InitStruct );
GPIO_InitStruct.Pin = E2PROM_SDA;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
return ReadValue;
}

void I2c_toDevice(unsigned char deviceAdd,unsigned char datAdd,unsigned char dat)
{
I2CStart();
I2CWriteByte(deviceAdd);
I2CWriteByte(datAdd);
I2CWriteByte(dat);
I2CWriteByte(0x10);
I2CStop();
}
unsigned short I2c_fromDevice(unsigned char deviceAdd,unsigned char datAdd )
{
unsigned short dat;
I2CStart();
I2CWriteByte(deviceAdd);
I2CWriteByte(datAdd);
// I2CStart();
I2CWriteByte(deviceAdd+1);
dat=I2CReadByte();
I2c_getAck();
dat=dat<<8;
dat|=I2CReadByte();
I2CStop();
return dat;
}

  • 根据您的0X44地址可以判断ADDR引脚接的是地是吗?这样的话,7bit从机地址为1000100,左移一位,地址应该为0X88。
    因此把0X44改为0X88,然后看是否能收到ACK信号呢?
  • 您好,现在是写0x88有ack应答,写配置没有应答

    deviceAdd=0x88 datAdd=0x01 dat=0xc2

    void I2c_toDevice(unsigned char deviceAdd,unsigned char datAdd,unsigned char dat)
    {
    I2CStart();
    I2CWriteByte(deviceAdd);//有ack应答
    I2CWriteByte(datAdd);//没有ack应答
    I2CWriteByte(dat);
    I2CWriteByte(0x10);
    I2CStop();
    }
  • 现在是读写配置有ack应答,但是读数据全是FF

    deviceAdd=0x88 datAdd=0x01 dat=0xc2

    void I2c_toDevice(unsigned char deviceAdd,unsigned char datAdd,unsigned char dat)
    {
    I2CStart();
    I2CWriteByte(deviceAdd);//有ack应答
    I2CWriteByte(datAdd);//有ack应答
    I2CWriteByte(dat);//有ack应答
    I2CWriteByte(0x10);//有ack应答
    I2CStop();
    }




    unsigned short I2c_fromDevice(unsigned char deviceAdd,unsigned char datAdd )
    {
    unsigned short dat;
    I2CStart();
    I2CWriteByte(deviceAdd);//有ack应答
    I2CWriteByte(datAdd);//有ack应答
    I2CWriteByte(deviceAdd);//有ack应答
    dat=I2CReadByte();
    I2c_getAck();//有ack应答
    dat=dat<<8;
    dat|=I2CReadByte();
    I2CStop();
    return dat;//dat=0XFFFF
    }
  • 7bit从机地址,第八位是读写方向位,为0 的时候表示发送数据,即“写”。 所以主机向从机发送数据,从机地址为0X88。
    如果读数据的话,第八位为1,即地址为0X81.
  • 不好意思,读数据的话,为10001001,为0X89.
  • 改为0x89也是读出全ff
  • unsigned short I2c_fromDevice(unsigned char deviceAdd,unsigned char datAdd )
    {
    unsigned short dat;
    I2CStart();
    I2CWriteByte(deviceAdd);//0x88
    I2CWriteByte(datAdd);//0
    I2CWriteByte(0x89);//0x89
    dat=I2CReadByte();
    I2c_getAck();
    dat=dat<<8;
    dat|=I2CReadByte();
    I2CStop();
    return dat;//全FF
    }
  • 您好我把我的程序改了一下现在可以读出正确数据,但是只有一个字节是正确,第二个字节还是全FF

    unsigned short I2c_fromDevice(unsigned char deviceAdd,unsigned char datAdd )
    {
    unsigned short dat;
    I2CStart();
    I2CWriteByte(deviceAdd);
    I2CWriteByte(datAdd);
    I2CStop();//必须停止之后在进行读
    I2CStart();//从新进行读
    I2CWriteByte(0x89);
    dat=I2CReadByte();//能读出跟光照变化的数据
    // I2c_getAck();//此处不知道为什么得不到ACK我将此句屏蔽
    dat=dat<<8;

    dat|=I2CReadByte();//得到全FF数据
    I2CStop();
    return dat;
    }