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.

[参考译文] BQ76920:未使用 AVR ATTiny24A 建立 I2C 连接

Guru**** 2338160 points
Other Parts Discussed in Thread: BQ76920, ADC3424
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/607574/bq76920-i2c-connection-not-establishing-with-avr-attiny24a

器件型号:BQ76920
主题中讨论的其他器件: ADC3424

我使用 Microchip Attiny24A 控制器作为主控制器、并与 BQ76920建立通信以保护3节串联电池。

尝试通过发送器件地址为0x08来与其通信、如器件 BQ7692000PWR 的 d/s 中所指定。

每次在发送器件地址后接收到 NACK 时。  对于其余数据、SDA 和 SCL 处于高电平状态。 无法理解原因。

至于启动、我将 SYS_STAT 寄存器复位为0xFF、然后将 CELLBAL1设置为0x13 (对于3s 配置)、 将 SYS_CTRL1设置为0x10以启用 ADC、在 SYS_CTRL2设置0x13中、首次禁用保护以验证 CHG 和 DSG 状态是否正常工作。

有人可以建议吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    如果器件通电正常、则应确认其地址并进行通信。  请记住地址08是一个7位地址、它在总线上看起来像10、如下所示。  检查用于 MCU 或外设的工具是否正确进行了转换。 还要检查电平和边缘是否正常。  来自 MCU 的信令可能比下面所示快得多。  如果 MCU 未接收到 ACK、则可能会停止、从而使总线信号保持高电平。

    对于寄存器、一旦建立通信:  

    • 清除状态寄存器是一个好主意
    • CELLBAL1不应设置为0x13、因为这将尝试同时平衡所有3节电池、并且可能超过绝对最大值  请参阅数据表第7.3.1.3.3节中的注释。  该寄存器将默认为00、这对于正常(非平衡)操作很好、将寄存器写入00进行初始化应该是可以的。
    • SYS_CTRL1正常
    • SYS_CTRL2位 4被保留且不应被置位。 保护功能不能被禁用(尽管如果 ADC 被关闭、电压保护将不会获得电压更新)。  如果没有故障、值0x03将启用 DSG 和 CHG 进行测试。   将 DELAY_DIS 位 的值设置为0x83可以更快地响应测试故障。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    位 4 在上面的答复中被混淆了、它已经被纠正。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你(们)好

    感谢您的回复、

    我将总线上的0x10用作从器件地址。 现在、SDA 为低电平、SCL 为高电平、并且无论总线是否释放、都保持这些状态

    我使用的脉冲高电平时间和低电平时间如下所示、如 D/S 中所述
    #define I2C_Tlow4.7
    #define I2C_THIGH4.0


    unsigned char I2CAddress = 0x08;//器件地址

    /**此处的所有函数声明*/
    --------
    --------
    --------

    字符读取寄存器(无符号字符地址)

    unsigned char i2c_Add =(I2CAddress << 1)| 0x01;//在 LSB 处附加读取位、将 I2C 地址1位向左移位
    unsigned char ReadData;
    器件(I2CAddress);
    I2C_WRITE (地址);
    器件(I2CAddress);
    ReadData = I2C_Read();
    I2C_STP();
    返回 ReadData;


    空 writeRegister (无符号字符地址、无符号字符数据)

    unsigned char i2c_Add = I2CAddress << 1;//将 I2C 地址1位左移、从而在 LSB 附加 Write 位
    I2C_start();
    器件(i2c_Add);
    I2C_WRITE (地址);
    I2C_WRITE (DATA);
    I2C_STP();




    char USI_I2C_Master_Transfer (char USISR_temp)

    USISR = USISR_temp;//根据调用函数的请求设置 USISR

    //移位数据
    操作

    USI_I2C_WAIT_LOW ();
    USI_CLOCK_STROBE ();//SCL 正边沿
    while (!(PIN_USI&(1< USI_I2C_WAIT_HIGH ();
    USI_CLOCK_STROBE ();//SCL 负边沿
    } while (!(USISR&(1<
    USI_I2C_WAIT_LOW ();

    返回 USIDR;



    void I2C_start()

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //生成启动条件 //
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    USI_SET_SCL_HIGH ();//设置输入使线路上拉为高电平

    while (!(PIN_USI &(1<
    #ifdef I2C_FAST_MODE
    USI_I2C_WAIT_HIGH ();
    其他
    USI_I2C_WAIT_LOW ();
    #endif
    USI_SET_SDA_OUTPUT ();
    USI_SET_SCL_OUTPUT ();
    USI_SET_SDA_LOW ();
    USI_I2C_WAIT_HIGH ();
    USI_SET_SCL_LOW ();
    USI_I2C_WAIT_LOW ();
    USI_SET_SDA_HIGH ();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    char 器件(unsigned char msg)

    USI_SET_SCL_LOW ();
    USIDR = msg;//加载数据

    USI_I2C_Master_Transfer (USISR_TRANSFS_8_BIT);
    USI_SET_SDA_INPUT ();
    IF (USI_I2C_Master_Transfer (USISR_TRANSIT_1_BIT)& 0x01)

    USI_SET_SCL_HIGH ();
    USI_SET_SDA_HIGH ();
    返回0;


    USI_SET_SDA_OUTPUT ();



    char I2C_write (unsigned char * msg)

    USI_SET_SCL_LOW ();

    USIDR =*msg;//加载数据

    USI_I2C_Master_Transfer (USISR_TRANSFS_8_BIT);

    USI_SET_SDA_INPUT ();

    if (USI_I2C_Master_Transfer (USISR_TRANSIT_1_BIT)& 0x01)// NACK 位

    I2C_STP();
    返回0;


    USI_SET_SDA_OUTPUT ();
    返回*msg;


    char I2C_read ()

    unsigned char *msg;
    USI_SET_SDA_INPUT ();
    *(msg)= USI_I2C_Master_Transfer (USISR_TRANSIT_8_BIT);
    USI_SET_SDA_OUTPUT ();

    //if (msg_size = 1)

    USIDR = 0xFF;//加载 NACK 以结束传输

    //else

    USIDR = 0x00;//加载 ACK


    USI_I2C_Master_Transfer (USISR_TRANSFS_1_BIT);

    返回*msg;


    void I2C_STP()

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //发送停止条件 //
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    USI_SET_SDA_LOW ();//将 SDA 拉至低电平。
    USI_I2C_WAIT_HIGH ();
    USI_SET_SCL_HIGH ();
    while (!(PIN_USI &(1< USI_I2C_WAIT_HIGH ();
    USI_SET_SDA_HIGH ();//释放 SDA。

    while (!(PIN_USI &(1< USI_I2C_WAIT_LOW ();



    int main (空)


    //主设备初始化
    DDR_USI ||(1 << PORT_USI_SDA)|(1 << PORT_USI_SCL);//将 PA4 (SCL)和 PA6 (SDA)设置为 o/p 引脚
    PORT_USI |=(1 << PORT_USI_SCL);//释放 SCL 和 SDA
    PORT_USI |=(1 << PORT_USI_SDA);
    USIDR = 0xFF;
    USICR =(0 << USISIE)|(0 << USIOIE)|(1 << USIWM1)|(0 << USIWM0)|(1 << USICS1)|(0 << USICS0)|(1 << USICLK)|(0 << USITC);
    USISR =(1 << USISIF)|(1 << USIOIF)|(1 << USIPF)|(1 << USIDC)|(0x00 << USICNT0);//在 Attiny 初始化 I2C

    while (1)

    writeRegister (0x00、0xFF);//清除 SYS_STAT //此处我被卡住了。 当总线 I 发送0x10时、SDA 为低电平、SCL 为恒定高电平。 如果是0x08、我将得到 NACK。
    ///代码的其余部分




    有什么建议? 我出了什么问题?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    除上述内容外。 我已验证 Attiny24A 与 ADC3424的 I2C 通信。 并验证了 BQ76920与 Arduino Mega 2560的工作情况。 两者都是单独工作的。 但 ATTiny24A 和 BQ76920之间存在通信问题。

    我错过了什么??
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Bilal、
    遗憾的是、我无法提供编码支持。 AVR 社区可能会提供有关设置外设、处理器编码特性的好建议、或有关使用该处理器进行 I2C 调试的具体建议。
    通常、您可能需要查看总线以查看谁在驱动它。 如果 bq76920将总线保持在低电平、它可能已将 ACK 置位并将其保持等待一个时钟、或者可能已经开始输出一个读取的数据。 I2C 中的标准总线释放机制是发送(最多9个?) 直到从器件释放总线。 如果主机保留 SDA 线路、则可能是外设设置问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好
    我检查了"连接"、发现我没有将设备重新启动到正常模式、也没有将数据直接发送到线路、而是要与 Attiny 通信。 我使用了 Buffer 变量以线性方式正确地发送数据。 它现在能够与 BQ76920通信

    有关代码帮助、我参考了 Arduino 库函数。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这里的另一个建议是使用 ATTINY 84A 而不是24A、这是内存问题。 使用24A 时、必须在一定程度上折衷保护。