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.

[参考译文] MSP432P401R:如何使用时钟低电平超时选择功能(UCCTLO.UCBxCTLW1)在 I2C 通信中启用超时窗口?

Guru**** 2606725 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/647798/msp432p401r-how-to-use-the-clock-low-time-out-select-feature-ucctlo-ucbxctlw1-to-enable-a-timeout-window-in-i2c-communication

器件型号:MSP432P401R

您好:

我尝试在 UCBxCTLW1寄存器中找到设置时钟低电平超时选择的方法。

我在 msp432外设驱动程序库中找不到它、只能找到 Clock_low_timeout_interrupt 启用标志。 如何设置它? 谢谢。

-Philip

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

    您好!

    可 通过 MSP432驱动程序库轻松启用中断功能。

    只需通过支持时钟低电平超时中断启用的 void I2C_enableInterrupt () API 来设置中断。

    请参阅驱动程序库 API 指南: 链接: (搜索时钟低电平)

    我将研究如何通过驱动程序库(UCB0CTLW1.UCCLTO 设置)配置实际超时窗口、并将该信息更新到此帖子。

    -Priya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    快速更新、我查看了 I2C API 本身、虽然我们提供了启用中断的方法、但我们不提供设置超时间隔的方法。

    我将在此问题上提交一个错误并与我们的软件团队进行检查。

    同时、您仍可以编写直接寄存器访问代码来实现此目的:

    请参阅 TRM: www.ti.com/.../slau356g.pdf 中的第24.4.2节

    EUSCI_B0->CTLW0 |= EUSCI_B_CTLW1_CLTO_1;//延迟28ms,使用_2或_3进行其他设置


    请告诉我这是否能解决您的问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    从拆分线程:
    "我尝试过、在 EUSCIB0_IRQHandler 中为 EUSCI_B_I2C_CLOCK _LOW_TIMEOUT_INTERRUPT 设置一个断点、但不会发生任何情况。"

    您能否发布代码片段以确保正确启用中断?
    此外、如何强制超时发生?


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

    /*标准包括*/
    #include
    #include

    /*从地址*/
    #define SLAVE_ADDRES_1 0x51

    /*静态*/
    静态易失性 uint8_t RXData[256];
    静态易失性 uint32_t xferIndex;
    静态易失性 uint32_t numOfRecBytes;

    /* I2C 主配置参数*/
    const eUSCI_I2C_MasterConfig i2cConfig =

    EUSCI_B_I2C_CLOCKSOURCE_SMCLK、 // SMCLK 时钟源
    3000000、 // SMCLK = 3MHz
    EUSCI_B_I2C_SET_DATA_RATE 100KBPS、 //所需的400kHz I2C 时钟
    0、 //无字节计数器阈值
    EUSCI_B_I2C_NO_AUTO_STOP //无自动停止
    };

    int main (空)

    uint32_t i;
    /*禁用看门狗*/
    MAP_WDT_A_HOLDTimer();
    xferIndex = 0;

    /*为 I2C 选择端口1 -将引脚6、7设置为输入主模块功能、
    (UCB0SIMO/UCB0SDA、UCB0SOMI/UCB.S.)。
    *
    MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P1、
    GPIO_PIN6 + GPIO_PIN7、GPIO_PRIMARY_MODULE_FUNCTION);

    EUSCI_B0->CTLW0 |= EUSCI_B_CTLW1_CLTO_1;//延迟28ms,使用_2或_3进行其他设置
    /*以100kHz 的频率将 I2C 主设备初始化为 SMCLK,而不进行自动停止*/
    MAP_I2C_initMaster (EUSCI_B0_BASE、&i2cConfig);
    MAP_I2C_setSlaveAddress (EUSCI_B0_BASE、SLAVE_ADDRES_1);

    /*设置为接收模式*/
    MAP_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_mode);

    /*清除 I2C 中断并启用模块*/
    MAP_I2C_enableModule (EUSCI_B0_BASE);
    MAP_I2C_clearInterruptFlag (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_INTERRUPT0);

    MAP_Interrupt_enableInterrupt (INT_EUSCIB0);
    //map_Interrupt_enableSlepOnIsrExit();

    /*启用主中断*/
    MAP_Interrupt_enableMaster();

    /*不使用时睡眠*/
    while (1)

    numOfRecBytes = 4;
    MAP_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_mode);
    如果(numOfRecBytes > 1)

    xferIndex = 0;
    MAP_I2C_masterReceiveStart (EUSCI_B0_BASE);


    否则//仅一个字节
    if (numOfRecBytes ==1)

    xferIndex = 0;
    EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT + EUSCI_B_CTLW0_TXSTP;

    MAP_I2C_enableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_INTERRUPT0 //添加更多中断标志来处理错误条件
    | EUSCI_B_I2C_NAK_INTERRUPT
    | EUSCI_B_I2C_CLOCK LOW_TIMEOUT_INTERRUPT
    | EUSCI_B_I2C_ARBITATIONLOST_INTERRUPT);

    对于(i=0;i<100000;i++);//检查范围的长延迟



    /*********
    * USCI_B0数据 ISR RX 矢量用于移动从 I2C 接收到的数据
    将*主设备连接到 MSP432存储器。
    秘书长的报告 /
    空 EUSCIB0_IRQHandler (空)

    uint_fast16_t status;

    STATUS = MAP_I2C_getEnabledInterruptStatus (EUSCI_B0_BASE);
    MAP_I2C_clearInterruptFlag (EUSCI_B0_BASE、STATUS);

    /* RXIFG */
    IF (STATUS & EUSCI_B_I2C_Receive_INTERRUPT0)

    if (numOfRecBytes =1)

    RXData[xferIndex++]= UCB0RXBUF;
    }否则
    if (xferIndex =(numOfRecBytes - 2))

    MAP_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);
    RXData[xferIndex++]= MAP_I2C_ReceivmasterMultiByteNext (EUSCI_B0_BASE);

    否则、如果(xferIndex =(numOfRecBytes - 1))

    //map_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);// Themis 可能重复
    MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_INTERRUPT0);
    MAP_I2C_enableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_STOP_INTERRUPT);
    RXData[xferIndex++]= MAP_I2C_ReceivmasterMultiByteNext (EUSCI_B0_BASE);
    //RXData[xferIndex++]= MAP_I2C_masterReceiveSingle (EUSCI_B0_BASE);// MAP_I2C_masterReceiveSingleByte (完全启动/停止)与 MAP_I2C_masterReceiveSingle

    其他

    RXData[xferIndex++]= MAP_I2C_ReceivmasterMultiByteNext (EUSCI_B0_BASE);


    否则、如果(STATUS & EUSCI_B_I2C_STOP_INTERRUPT)

    MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_STOP_INTERRUPT);
    }否则、如果(STATUS & EUSCI_B_I2C_ARBITATIONLOST_INTERRUPT)

    MAP_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);
    MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_ARBITATIONLOST_INTERRUPT);
    }否则、如果(STATUS & EUSCI_B_I2C_NAK_INTERRUPT)

    MAP_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);
    MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_NAK_INTERRUPT);
    }否则、如果(status & EUSCI_B_I2C_CLOCK _LOW_TIMEOUT_INTERRUPT)

    MAP_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);
    MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_CLOCK _LOW_TIMEOUT_INTERRUPT);

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

    如何强制时钟低电平超时发生? 从机是否将时钟保持在低电平超过28ms?

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

    我在 I2C 数据转换期间使用跳线将时钟对地短路。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    嗯,看起来有点不科学:)你怎么能用 I2C 交易来安排你的活动时间?


    您是否有任何方法可以强制从器件在系统内将时钟保持在低电平?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    已编辑以添加:让我尝试使用您的示例重新创建此内容。
    -Priya
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    由于缺乏活动、我想关闭此帖子。

    我能够通过所附的示例验证时钟低电平超时功能。

    我使用了以下设置。

    一个 MSP432设置为 I2C 主设备、一个设置为从设备。

    在传输过程中、从机将时钟线保持低电平~30ms (~3MHz 时为90K 延迟周期)

    3.主超时窗口设置为在28ms 时触发。

    主器件的每次读取请求都会导致从器件将时钟线保持在低电平>28ms。 这反过来会触发时钟低电平 ISR 并更新超时计数器。

    5.在主代码的末尾,它会检查超时计数器,如果该数字大于零,则 Launchpad LED (P1.0)闪烁。 用户还可以暂停调试器并查看超时变量、该变量应更新为10 (用于10个数据事务)。

    这个功能目前还没有通过 driverlib 完全可用、所以我已经使用一些直接寄存器访问来实现它。

    已提交错误以添加此功能、您应该能够在 MSP432 SDK 的下一个版本(~March2018)中看到。

    谢谢、

    Priya

    e2e.ti.com/.../i2c_5F00_master_5F00_timeout.c

    e2e.ti.com/.../i2c_5F00_slave_5F00_forcedtimeout.c