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.

[参考译文] TM4C1230E6PM:I2C 行为有问题

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/991083/tm4c1230e6pm-having-issues-with-i2c-behavior

器件型号:TM4C1230E6PM
主题中讨论的其他器件:PCF8574

大家好、我遇到了 I2C 的 tivaware 命令问题。  我需要向安装在小型 PCA 上的 I2C 从设备(MCP23017 16位 IO 扩展器)发送两个字节的信息。  我已验证 PCA 是否可以与 Arduino 和示例代码一起正常工作。

根据 SPMA073、I2C_MASTER_CMD_BURST_SEND_START 应发送开始位、从器件地址、清除的写入位以及 I2CMDR 中通过 I2CMDataPut 输入的附加字节命令。  然后、可以使用 I2C_MASTER_CMD_BURST_SEND_FINISH 发送数据的第二个字节。  这基本上意味着以这种方式发送起始位、从地址、写入位和两个字节。

我的问题是 I2C_MASTER_CMD_BURST_SEND_START 似乎不发送在 I2CMDR 中输入的字节。  请参阅下面的代码以及随附的 I2C 在总线上发送的示波器截图。  如果我的代码不正确、或者对流程的工作方式有误解、请告知我。  感谢所有回复。

#include <__cross_studio_io.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "driverlib/i2c.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/gpio.h"
#include "driverlib/uart.h"
#include "driverlib/pin_map.h"
#include "driverlib/debug.h"
#include "driverlib/rom.h"

#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif

uint8_t opcode = 0x27; //MCP23017 with A0 through A2 set as High

//initialize I2C module 5
void InitI2C5(void)
{

    //enable I2C module 0
    SysCtlPeripheralDisable(SYSCTL_PERIPH_I2C5);
    SysCtlPeripheralReset(SYSCTL_PERIPH_I2C5);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C5);

    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C5));

    // Enable and initialize the I2C5 master module.  Use the system clock for
    // the I2C5 module.  The last parameter sets the I2C data transfer rate.
    // If false the data rate is set to 100kbps and if true the data rate will
    // be set to 400kbps.
    I2CMasterInitExpClk(I2C5_BASE, SysCtlClockGet(), false);

    //enable GPIO peripheral that contains I2C 5
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
 
    // Configure the pin muxing for I2C5 functions on port B6 and B7.
    GPIOPinConfigure(GPIO_PB6_I2C5SCL);
    GPIOPinConfigure(GPIO_PB7_I2C5SDA);
     
    // Select the I2C function for these pins.
    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_6);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_7);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    SysCtlDelay(1);
    //
    // Configure LED pins as outputs.
    //
    GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE, GPIO_PIN_5 | GPIO_PIN_6);

}

void main(void)
{
    // Set the clocking to run directly from the external crystal/oscillator.
     SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

    //initialize I2C module 5
    InitI2C5();

     //Turn I2C power on.
     GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, GPIO_PIN_5);

    while(1)
    {
     //Turn Red LED on.
     //GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_6, GPIO_PIN_6);

     SysCtlDelay(5000000); 

        // Wait until MCU is done transferring.
        while(I2CMasterBusBusy(I2C5_BASE)) {}

         // Tell the master module what address it will place on the bus when
         // communicating with the slave.
        I2CMasterSlaveAddrSet(I2C5_BASE, opcode, false);

//-------------------------------------------------------------------   
         //Configure MCP23017 IODIRB output pins     
         //put data to be sent into FIFO
         I2CMasterDataPut(I2C5_BASE, 0x13);
       
         //Initiate send of data from the MCU
        I2CMasterControl(I2C5_BASE, I2C_MASTER_CMD_BURST_SEND_START);
       
        // Wait until MCU is done transferring.
        while(I2CMasterBusBusy(I2C5_BASE)) {}

        //Check for errors
        if (I2CMasterErr(I2C5_BASE) != I2C_MASTER_ERR_NONE)
          {
            //Turn Red LED on.
	    GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, GPIO_PIN_5);
          }

         //put data to be sent into FIFO
         I2CMasterDataPut(I2C5_BASE, 0x55);
       
         //Initiate send of data from the MCU
        I2CMasterControl(I2C5_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
       
        // Wait until MCU is done transferring.
        while(I2CMasterBusBusy(I2C5_BASE)) {}

        //Check for errors
        if (I2CMasterErr(I2C5_BASE) != I2C_MASTER_ERR_NONE)
          {
            //Turn Red LED on.
	    GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, GPIO_PIN_5);
          }
//-------------------------------------------------------------------

     //Turn Red LED off.
     //GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_6, 0);

     SysCtlDelay(5000000); 

    }
}

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

    很抱歉、我看一下代码就看不到问题。 它看起来与我的示例非常相似。 我不在办公室、可能需要在周一进一步挖掘。

    //*****************************************************************************
    //
    // Copyright (c) 2012-2020 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    // 
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    // 
    //*****************************************************************************
    
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/i2c.h"
    #include "driverlib/pin_map.h"
    
    void I2CWriteRegister(uint8_t reg, uint8_t value);
    
    int main()
    {
    
        SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
    
        //Enable I2C Module 0
        SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
    
        //enable GPIO peripheral that contains I2C 0
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
        // Configure the pin muxing for I2C0 functions on port B2 and B3.
        GPIOPinConfigure(GPIO_PB2_I2C0SCL);
        GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    
        // Select the I2C function for these pins.
        GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
        GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    
        //Initialize the Master and Slave
        I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);
    
        //Identify Slave Address
        I2CMasterSlaveAddrSet(I2C0_BASE, 0x55, false);
    
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
        //Send Data Bytes to Slave Sub Addresses as described above???? ///
        I2CWriteRegister(0x25u, 0x05u);
        I2CWriteRegister(0x27u, 0x03u);
        I2CWriteRegister(0x29u, 0x08u);
    
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
        
        return 0;
    }
    
    void I2CWriteRegister(uint8_t reg, uint8_t value)
    {
        I2CMasterDataPut(I2C0_BASE, reg);
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
        while(I2CMasterBusy(I2C0_BASE));
        I2CMasterDataPut(I2C0_BASE, value);
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
        while(I2CMasterBusy(I2C0_BASE));
    }
    

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

    大家好,代码对我来说是可以的。 操作码的价值是什么? (由于某种原因、Microchip 将从器件地址称为"操作码"。 奇怪。) 知道这一点后、我们至少可以检查传输的地址阶段是否正确。 尽管它已得到确认、因此扩展器运行良好。  

    在'scope trace 中发送的字节是您在第110行中加载的0x55、而不是第94行中指示的0x13。  就好像第94行中的调用没有被执行一样。 可能在调试器中单步执行它?

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

    Bob 和 Andy、您好、感谢您的回复。  MCP23017的操作码是0100111、所有地址位都被拉高、因此示波器上的第一个字节对我来说是正确的。  作为另一项检查、我调整了代码以使用 TMC1230在 Launchpad 上的 I2C2上运行(原始代码在原型 PCB 上运行)、并获得了相同的结果。  的确是调试器的时候了;不幸的是、我一年只编写一次代码、必须重新了解详细信息。   但确实感谢您确认代码看起来正确。  如果我发现任何奇怪的东西、我会在这里发帖。

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

    我尝试重现您看到的问题。 我有不同的硬件、因此从器件地址和 I2C 端口是不同的。 我无法重现您遇到的问题。

        // Initialize the MPU9150
        MPU9150WriteRegister(0x6B, 0x80);
    

    void MPU9150WriteRegister(uint8_t reg, uint8_t value)
    {
        I2CMasterSlaveAddrSet(MPU9150_I2C_BASE, MPU9150_I2C_ADDRESS, false);
        I2CMasterDataPut(MPU9150_I2C_BASE, reg);
        I2CMasterControl(MPU9150_I2C_BASE, I2C_MASTER_CMD_BURST_SEND_START);
        while(I2CMasterBusy(MPU9150_I2C_BASE));
        if (I2CMasterErr(MPU9150_I2C_BASE) != I2C_MASTER_ERR_NONE)
        {
            //Turn Red LED on.
            GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2, GPIO_PIN_2);
        }
        I2CMasterDataPut(MPU9150_I2C_BASE, value);
        I2CMasterControl(MPU9150_I2C_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
        while(I2CMasterBusy(MPU9150_I2C_BASE));
        if (I2CMasterErr(MPU9150_I2C_BASE) != I2C_MASTER_ERR_NONE)
        {
            //Turn Red LED on.
            GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2, GPIO_PIN_2);
        }
    
    }
    

    如果您有任何其他信息、请告知我们。

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

    再次感谢所有帮助。  我在应用中更成功地改用具有更简单指令要求的不同 I2C 器件(我能够使用新器件 PCF8574确认我获得了双向通信)。  问题仍然存在、但您的所有帮助使我相信编译器(Rowley Crossworks)中最有可能出现这种情况、我只需要跟踪它。  我眼前的主要问题是确保硬件路径正常工作、这似乎是正常的、我可以进行下一次 PCA 运行。  I2C 问题仍然存在、但我可以在硬件经过验证后再将其解决一天。  当我进入 I2C 集成(可能在几个月内)时、一旦发现问题、我就会重新发帖。

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

    感谢您的更新。 如果您不介意、我现在将您的帖子标记为"TI 认为已解决"。 请告诉我们是否可以提供任何其他帮助。