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:在 I2C 主设备中、如何通过中断方法 quot;向从设备发送一个字节、重复 START 并读取一个字节&quot?

Guru**** 2606405 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/650134/msp432p401r-in-i2c-master-how-to-send-one-byte-to-slave-repeat-start-and-read-one-byte-by-interrupt-method

器件型号:MSP432P401R

我尝试了 MAP_I2C_masterSendSingleByte ()和 MAP_I2C_masterReceiveSingleByte (),但两者之间有一个停止位置,我更喜欢使用中断例程,该例程可以捕获 NACK 状态。

我想监控 SCL 和 SDA 线路卡在低电平状态、在哪里可以从寄存器中找到线路状态?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    澄清-这是否是您尝试实施的顺序?

    1:主器件 I2C TX 1字节
    2.主机发送重启
    3.主 I2C RX 1个字节

    如果是、您将使用以下 API 序列:

    MAP_I2C_masterSendMultiByteStart -此 API 将发送第一个启动条件、后跟一个字节而不发送停止。
    传输结束时、TX 中断被使能

    2.使用发送中断服务例程发送重新启动条件并使用以下 API 设置状态机以接收单字节

    API 调用:map_I2C_masterReceiveSingleByte()

    要轮询 SCL 线路、您可以直接使用 UCBxSTAT 寄存器中的位- UCSCLLOW 或 UCBBUSY 位。 请参阅技术参考手册中的第24.4.4节: www.ti.com/.../slau356g.pdf

    作为一个选项、您可以使用该函数
    uint8_t I2C_isBusBusy ()

    希望这对您有所帮助。

    -Priya
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Priya:
    我遵循了您的建议、并对其进行了测试。
    根据我的示波器和 I2C 监听器、它看起来像:
    [开始]、写入一个字节、[停止];[开始]、读取两个字节、 [停止];
    我的代码中是否有任何建议?
    谢谢。
    -Philip

    /* DriverLib 包括*/
    #include

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

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

    /*静态*/
    静态易失性 uint8_t RXData[256];
    静态易失性 uint32_t xferIndex、txIndex;
    静态易失性 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、 //所需的100kHz I2C 时钟
    0、 //无字节计数器阈值
    EUSCI_B_I2C_NO_AUTO_STOP //无自动停止
    };

    int main (空)

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

    MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P1、GPIO_PIN6 + GPIO_PIN7、GPIO_PRIMARY_MODULE_Function);

    MAP_I2C_initMaster (EUSCI_B0_BASE、&i2cConfig);
    MAP_I2C_setSlaveAddress (EUSCI_B0_BASE、SLAVE_ADDRES_1);

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

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

    while (1)

    MAP_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_Transmit 模式);
    MAP_I2C_enableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Transmit INTERRUPT0|EUSCI_B_I2C_NAK_INTERRUPT);
    MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE、0x55);//其中无中断。 I2C_masterSendSingleByteWithTimeout
    对于(i=0;i<100;i++);
    对于(i=0;i< 500000;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)

    RXData[xferIndex++]= UCB0RXBUF;
    EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTP;
    MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_INTERRUPT0);
    }否则
    /* TXIFG */
    IF (STATUS & EUSCI_B_I2C_Transmit _INTERRUPT0)//

    MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Transmit INTERRUPT0);
    MAP_I2C_enableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_Receive_INTERRUPT0);
    MAP_I2C_PmasterReceiveSingleByte (EUSCI_B0_BASE);//
    } else /* NACK */
    IF (STATUS & EUSCI_B_I2C_NAK_INTERRUPT)

    EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTP;
    MAP_I2C_DisableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_NAK_INTERRUPT);

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

    您好!

    我对这种情况进行了一些测试、并发现了一些注意事项。

    尝试的事务是主机 TX 1字节、重新启动、主机 RX 1字节。

    首先、就主器件 TX 而言、您有两个可用的标志、一个是发送开始+地址、另一个是 TXIFG。

    关于 TXIFG 需要注意的一点是、当字节在总线上传输时、它不会被置位。

    相反、当数据字节从 TXBUF 移动到发送移位寄存器准备发出时、TXIFG 被置位。

    这意味着在 TXIFG 被置位后、在实际数据字节被发送前、我们仍然有9个 I2C 时钟。

    如果 I2C 以100KHz 运行并且 CPU 以3MHz (默认值)运行,则这大约是300个 CPU 周期。

    应用程序需要在发送重新启动前延迟这300个周期、否则事务可能会停止或导致停止。

    为了保持这个时序紧张、在我的示例中、我使用了一个没有中断的内联延迟。

    但是、也可以启用 TXIFG、在 ISR 中延迟300个周期、然后发送重启。

    我认为这不可取、因为 ISR 可能会被阻止。

    其次、当涉及一个字节的 RX 时、API "Masterreceivesinglebyte"似乎存在时序问题。

    我也无法使用此 API 创建成功的一个字节读取。

    但是、我通过使用直接寄存器访问代码并更改序列来实现此目的。

    我猜是因为 I2C 事务/状态机速度慢于 MCLK 会导致这种情况。

    由于我的示例可以正常工作、成功传输、然后接收一个字节、因此我已将其附加到该帖子。

    我还针对 API 提交了一个错误、如果有进一步的更新、我将返回此处发布。

    我将此主题标记为已解决、如果您有其他问题、请随时告知我。

    PS:测试设置为2个 MSP432 LP,一个作为主设备,另一个作为从设备。

    此致、

    Priya

    e2e.ti.com/.../master_5F00_onebyte.c

    e2e.ti.com/.../slave_5F00_onebyte.c.c

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