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.

[参考译文] TM4C123GH6PZ:i2c 有问题、"I2CMasterIntStatus"当预期返回 true 时返回 false。

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/743632/tm4c123gh6pz-having-problems-with-i2c-i2cmasterintstatus-returns-false-when-expected-to-return-true

器件型号:TM4C123GH6PZ

您好!

我不熟悉 i2c、请多多包涵。

我有一个代码、其中我的处理器(TM4C123GH6PZ)被定义为一个主器件、并通过 i2c 将数据发送到另一个组件。

我使用的代码为:

"

SysCtlPeripheralEnable (SYSCTL_Periph_I2C1);

SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);

ROM_GPIOPinConfigure (GPIO_PA6_I2C1SCL);
ROM_GPIOPinConfigure (GPIO_PA7_I2C1SDA);
I2CMasterEnable (I2C1_MASTER_BASE);
GPIOPinTypeI2C (GPIO_Porta_base、GPIO_PIN_6| GPIO_PIN_7);
GPIOPadConfigSet (GPIO_Porta_base、GPIO_PIN_6、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU);
GPIOPadConfigSet (GPIO_Porta_base、GPIO_PIN_7、GPIO_Strength _2mA、GPIO_PIN_TYPE_OD_WPU);
I2CMasterInitExpClk (I2C1_MASTER_BASE、SysCtlClockGet ()、false);

SysCtlDelay (ROM_SysCtlClockGet ()/20);"

这里是设置代码、

下一部分是有问题的部分、这是尝试发送数据的代码:

"

I2CMasterSlaveAddrSet (I2C1_MASTER_BASE、SLAVE_ADDRESS、false);

I2CMasterDataPut (I2C1_MASTER_BASE、reg);
I2CMasterControl (I2C1_MASTER_BASE、I2C_MASTER_CMD_BURST_SEND_START);
while (I2CMasterIntStatus (I2C1_MASTER_BASE、false)=0)

//
//清除 I2C 中断。
//
I2CMasterIntClear (I2C1_MASTER_BASE);
I2CMasterDataPut (I2C1_MASTER_BASE、(无符号长整型)数据);
I2CMasterControl (I2C1_MASTER_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);
while (I2CMasterIntStatus (I2C1_MASTER_BASE、false)=0)

//
//清除 I2C 中断。
//
I2CMasterIntClear (I2C1_MASTER_BASE);

"

有时工作正常、但有时 我会卡在黄色标记的 while 循环上。 "I2CMasterIntStatus"函数中的以下代码似乎是这样的

"return ((HWREG (ulBase + I2C_O_MRI))? 真:假);"

有时总是返回 false。 我不清楚为什么、也不清楚"打开"该寄存器的责任是什么。

如果有任何解释和决议,将不胜感激   

 

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

    您是启用和使用中断、还是只是在 I2C 事务完成时尝试轮询? 如果只是轮询,则应使用 I2CMasterBusy()而不是 I2CMasterIntStatus()。 下面是一些 I2C 轮询例程:

    void MPU6050WriteRegister (uint8_t reg、uint8_t value)
    {
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_START);
    while (I2CMasterBusy (MPU6050_I2C_base));
    I2CMasterDataPut (MPU6050_I2C_base、值);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_FINISH);
    while (I2CMasterBusy (MPU6050_I2C_base));
    
    }
    
    uint8_t MPU6050ReadRegister (uint8_t reg)
    {
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_SINGLE_SEND);
    while (I2CMasterBusy (MPU6050_I2C_base));
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、true);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_SINGLE_Receive);
    while (I2CMasterBusy (MPU6050_I2C_base));
    返回(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    }
    
    void MPU6050BurstRead (uint8_t reg、unsigned int count、uint8_t * p8Data)
    {
    unsigned int i;
    
    if (count < 2)
    {
    返回;
    }
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_SINGLE_SEND);
    while (I2CMasterBusy (MPU6050_I2C_base));
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、true);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_Receive_start);
    while (I2CMasterBusy (MPU6050_I2C_base));
    *p8Data++=(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    对于(I = 0;I <(计数- 2);I++)
    {
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_Receive_contt);
    while (I2CMasterBusy (MPU6050_I2C_base));
    *p8Data++=(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    }
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_Receive_finish);
    while (I2CMasterBusy (MPU6050_I2C_base));
    *p8Data++=(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    }
    
    void MPU6050BurstWrite (uint8_t reg、unsigned int count、uint8_t * p8Data)
    {
    unsigned int i;
    
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_START);
    while (I2CMasterBusy (MPU6050_I2C_base));
    对于(i = 0;i <(count - 1);i++)
    {
    I2CMasterDataPut (MPU6050_I2C_base、* p8Data++);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_CONT);
    while (I2CMasterBusy (MPU6050_I2C_base));
    }
    I2CMasterDataPut (MPU6050_I2C_base、* p8Data);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_FINISH);
    while (I2CMasterBusy (MPU6050_I2C_base));
    
    }
    

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

    [引用 user="Bob Crosby"]

    您是启用和使用中断、还是只是在 I2C 事务完成时尝试轮询? 如果只是轮询,则应使用 I2CMasterBusy()而不是 I2CMasterIntStatus()。 下面是一些 I2C 轮询例程:

    void MPU6050WriteRegister (uint8_t reg、uint8_t value)
    {
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_START);
    while (I2CMasterBusy (MPU6050_I2C_base));
    I2CMasterDataPut (MPU6050_I2C_base、值);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_FINISH);
    while (I2CMasterBusy (MPU6050_I2C_base));
    
    }
    
    uint8_t MPU6050ReadRegister (uint8_t reg)
    {
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_SINGLE_SEND);
    while (I2CMasterBusy (MPU6050_I2C_base));
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、true);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_SINGLE_Receive);
    while (I2CMasterBusy (MPU6050_I2C_base));
    返回(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    }
    
    void MPU6050BurstRead (uint8_t reg、unsigned int count、uint8_t * p8Data)
    {
    unsigned int i;
    
    if (count < 2)
    {
    返回;
    }
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_SINGLE_SEND);
    while (I2CMasterBusy (MPU6050_I2C_base));
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、true);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_Receive_start);
    while (I2CMasterBusy (MPU6050_I2C_base));
    *p8Data++=(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    对于(I = 0;I <(计数- 2);I++)
    {
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_Receive_contt);
    while (I2CMasterBusy (MPU6050_I2C_base));
    *p8Data++=(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    }
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_Receive_finish);
    while (I2CMasterBusy (MPU6050_I2C_base));
    *p8Data++=(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    }
    
    void MPU6050BurstWrite (uint8_t reg、unsigned int count、uint8_t * p8Data)
    {
    unsigned int i;
    
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_START);
    while (I2CMasterBusy (MPU6050_I2C_base));
    对于(i = 0;i <(count - 1);i++)
    {
    I2CMasterDataPut (MPU6050_I2C_base、* p8Data++);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_CONT);
    while (I2CMasterBusy (MPU6050_I2C_base));
    }
    I2CMasterDataPut (MPU6050_I2C_base、* p8Data);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_FINISH);
    while (I2CMasterBusy (MPU6050_I2C_base));
    
    }
    

    [/报价]

    Bob Crosby 说:

    您是启用和使用中断、还是只是在 I2C 事务完成时尝试轮询? 如果只是轮询,则应使用 I2CMasterBusy()而不是 I2CMasterIntStatus()。 下面是一些 I2C 轮询例程:

    void MPU6050WriteRegister (uint8_t reg、uint8_t value)
    {
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_START);
    while (I2CMasterBusy (MPU6050_I2C_base));
    I2CMasterDataPut (MPU6050_I2C_base、值);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_FINISH);
    while (I2CMasterBusy (MPU6050_I2C_base));
    
    }
    
    uint8_t MPU6050ReadRegister (uint8_t reg)
    {
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_SINGLE_SEND);
    while (I2CMasterBusy (MPU6050_I2C_base));
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、true);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_SINGLE_Receive);
    while (I2CMasterBusy (MPU6050_I2C_base));
    返回(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    }
    
    void MPU6050BurstRead (uint8_t reg、unsigned int count、uint8_t * p8Data)
    {
    unsigned int i;
    
    if (count < 2)
    {
    返回;
    }
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_SINGLE_SEND);
    while (I2CMasterBusy (MPU6050_I2C_base));
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、true);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_Receive_start);
    while (I2CMasterBusy (MPU6050_I2C_base));
    *p8Data++=(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    对于(I = 0;I <(计数- 2);I++)
    {
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_Receive_contt);
    while (I2CMasterBusy (MPU6050_I2C_base));
    *p8Data++=(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    }
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_Receive_finish);
    while (I2CMasterBusy (MPU6050_I2C_base));
    *p8Data++=(uint8_t) I2CMasterDataGet (MPU6050_I2C_base);
    }
    
    void MPU6050BurstWrite (uint8_t reg、unsigned int count、uint8_t * p8Data)
    {
    unsigned int i;
    
    I2CMasterSlaveAddrSet (MPU6050_I2C_base、MPU6050_I2C_address、false);
    I2CMasterDataPut (MPU6050_I2C_base、reg);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_START);
    while (I2CMasterBusy (MPU6050_I2C_base));
    对于(i = 0;i <(count - 1);i++)
    {
    I2CMasterDataPut (MPU6050_I2C_base、* p8Data++);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_CONT);
    while (I2CMasterBusy (MPU6050_I2C_base));
    }
    I2CMasterDataPut (MPU6050_I2C_base、* p8Data);
    I2CMasterControl (MPU6050_I2C_base、I2C_MASTER_CMD_BURST_SEND_FINISH);
    while (I2CMasterBusy (MPU6050_I2C_base));
    
    }
    

    [/报价]

    尊敬的 Bob:

    感谢您的回复。

    我有几个问题:

    1) 1)您能否在此处解释轮询和使用中断之间的区别?

    2) 2)如果要使用中断、我假设这是我需要使用的函数:" void I2CMasterIntEnableEx (unsigned long ulBase、unsigned long ulIntFlags)"

    3) 3)随着代码的出现、为什么该函数"I2CMasterIntStatus"有时会起作用?

    此致、

    ROI

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

    [引用 user="ROI Birenshtok"]1)您能否在此处解释轮询和使用中断之间的区别?[/quot]

    通过轮询、您指示像 I2C 模块这样的外设执行函数、然后在循环中等待外设完成状态检查。 使用中断、您可以将外设配置为执行某些操作并生成一个信号(中断请求)、以便在操作完成时通知 CPU。 中断请求导致 CPU 停止执行它正在执行的操作、执行一个新的代码"线程"、然后返回到原始代码。

    [引用 user="ROI Birenshtok"]2)如果要使用中断,我假设这是我需要使用的函数:" void I2CMasterIntEnableEx (unsigned long ulBase、unsigned long ulIntFlags)"

    它比这更复杂。 您必须编写一个中断例程、寄存中断矢量(静态或动态)、在全局范围内启用中断并在外设中启用中断、 也许本技术讲座中的信息会有所帮助: processors.wiki.ti.com/.../Getting_Started_with_the_TIVATm_C_Series_TM4C123G_LaunchPad

    [引用 user="ROI Birenshtok"]3)随着代码的出现、为什么该函数"I2CMasterIntStatus"有时起作用?[/quot]

    我不确定。 起初、我以为您可能有一个清除标志的中断服务例程、而您正尝试清除主代码中的标志。