TI论坛
直播中

风来吴山

9年用户 1537经验值
擅长:电源/新能源
私信 关注
[问答]

使用单片机读取OPT3001得数据,一点反应也没有ACK信号也没有,为什么?


  • 大家好我使用单片机读取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;
    }

回帖(3)

赵晨

2024-12-5 10:03:12
 建议您通过示波器观察下I2C时序是否符合datasheet Figure1 I2C Detailed Timing Diagram。
举报

孙勳努

2024-12-5 10:03:21
 一点反应也没有ACK信号也没有,   就这个情况, 我觉得还不是测软件的时候, 先检查硬件吧,  比如供电, 焊接, 连接等
举报

study875

2024-12-5 10:36:07
根据您的描述和代码片段,您正在尝试使用单片机读取OPT3001传感器的数据,但是没有收到任何响应,包括ACK信号。以下是一些建议和可能的原因:

1. 检查硬件连接:确保OPT3001传感器的VCC、GND、SDA和SCL引脚正确连接到单片机相应的引脚上。同时,确保SDA和SCL引脚之间有一个上拉电阻(通常为4.7kΩ)。

2. 检查I2C地址:您提到ADDR接地,地址是0x44。请确保您的OPT3001传感器的I2C地址确实是0x44。如果地址不正确,单片机将无法正确识别传感器。

3. 检查I2C通信协议:请确保您的代码遵循I2C通信协议,包括正确的起始条件、设备地址、读写位、数据传输和停止条件。您提供的代码片段不完整,因此无法判断是否正确实现了I2C协议。

4. 检查GPIO初始化:您的代码片段中提到了GPIO初始化,但是没有看到具体的初始化代码。请确保您已经正确初始化了GPIOA的SDA和SCL引脚,并设置了正确的模式(例如,输出开漏、上拉等)。

5. 检查时钟和速度:请确保您的单片机时钟配置正确,以便I2C通信能够正常工作。同时,检查您设置的GPIO速度是否与OPT3001传感器支持的速度相匹配。

6. 使用调试工具:如果可能的话,使用逻辑分析仪或示波器检查I2C总线上的信号,以确定是否有任何通信发生。这可以帮助您确定问题是否出在硬件连接、GPIO初始化还是I2C通信协议上。

7. 检查OPT3001传感器:如果以上步骤都无法解决问题,可能是OPT3001传感器本身存在问题。您可以尝试更换一个传感器,看看问题是否得到解决。

希望这些建议能帮助您找到问题所在并解决问题。如果您需要更详细的代码示例或进一步的帮助,请提供更多信息。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分