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.

[参考译文] TM4C1292NCPDT:I2C 主器件时钟速率问题

Guru**** 2393095 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1219269/tm4c1292ncpdt-i2c-master-clock-rate-issues

器件型号:TM4C1292NCPDT
主题中讨论的其他器件:TM4C123

我正在为定制 PCB (TM4C1292NCPDTT3R)编写一些 I2C 主驱动程序、以便与 I2C/SMBus 的智能电池通信。 我正在使用 TI 提供的 TivaWare 软件 API

在 I2C1SCL 和 I2C1SDA 上设置主驱动程序时遇到了一些问题。 所需的目标是让主器件在 SCL 最大100kHz (根据 SMBus 协议)下查询电池2个字节。 我在设置正确的总线速度和从电池/从器件读取2个字节的数据时遇到了一些问题。

以下是我的初始化代码:

GPIOPinConfigure(GPIO_PG0_I2C1SCL); // master SCL (battery slave)
GPIOPinConfigure(GPIO_PG1_I2C1SDA); // master SDA (battery slave)
GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0); // configure master SCL line
GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1);    // configure master SDA line

SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C1));

I2CMasterInitExpClk(I2C1_BASE, SysCtlClockGet(), I2C_MASTER_SLOW_MODE); // slow mode = 100kbps transfers
I2CMasterTimeoutSet(I2C1_BASE, 0xDA0);

以下是读取实现:

typedef enum
{
    I2C_MASTER_WRITE = 0,   // specifies that the master will be initiating write transactions
    I2C_MASTER_READ = 1,    // specifies that the master will be initiating read transactions
} boolI2CMasterMode_t;

void configNextMessage(boolI2CMasterMode_t msgMode)
{
    I2CMasterSlaveAddrSet(I2C1_BASE, BATTERY_ADDRESS, msgMode);
}

uint16_t readBatteryData(uint8_t readCommand)
{
    uint8_t highByte = 0u;
    uint8_t lowByte  = 0u;

    configNextMessage(I2C_MASTER_WRITE);
    I2CMasterDataPut(I2C1_BASE, readCommand);
    I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND);
    while(I2CMasterBusy(I2C1_BASE))
    {
        // intentionally blank
    }


    configNextMessage(I2C_MASTER_READ);
//    I2CMasterBurstLengthSet(I2C1_BASE, 2);
    I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
    while(I2CMasterBusy(I2C1_BASE))
    {
        // intentionally blank
    }
    highByte = I2CMasterDataGet(I2C1_BASE);


    I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
    while(I2CMasterBusy(I2C1_BASE))
    {
        // intentionally blank
    }
    lowByte = I2CMasterDataGet(I2C1_BASE);



    return (highByte << 8) + lowByte;
}

以下是带模拟等效电路的数字信号示波器捕获:

在初始化中、我传递  I2CMasterInitExpClk (...)  我超过了 I2C_MASTER_SLOW_MODE、这是错误的。 根据 API 文档、我预计它提供的时钟速度为100kbps;但是、在本例中、看起来它使用的是400kbps 的快速模式。 有什么想法吗? 传递函数  某个操作 与该参数相同、该器件采用1Mbps 的超快模式。 我甚至尝试设置  MCLKOCNT 注册的更多信息  I2CMasterTimeoutSet 但它似乎没有效果。  

从模拟线路的外观来看、这对于从设备(额定速率仅为100kbps)绝对显得太快。 我认为我的数据采集问题的一部分与这个时钟速度有关。 我不知道如何从从器件读回2个字节。  下图是我尝试从从从器件读取序列号时捕获的图像。

我返回的第一个字节0x39是正确的;但是、0xFF 不正确。  是否有关于如何更好地利用 API 轮询2个字节的建议?

谢谢你

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

    尊敬的 Zach:

     我认为首先要做的事情。 下面的行中有错误。 不能 为 TM4C129 MCU 调用 SysCtlClockGet ()。  SysCtlClockGet 仅适用于 TM4C123 MCU。 该错误很可能会破坏 I2C 时钟。  

    I2CMasterInitExpClk (I2C1_base、SysCtlClockGet ()、I2C_MASTER_SLOW_MODE);//慢速模式= 100kbps 传输

     请改为如下内容。  

    g_ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |  //根据您的应用程序要求配置系统时钟。 这是一个示例。
    SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_240)、120000000);

    吸嘴...

    I2CMasterInitExpClk (I2C1_base、g_ui32SysClock 、I2C_MASTER_SLOW_MODE);//慢速模式= 100kbps 传输