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.

TM4C1231 I2C0使用问题

原来使用LM3S5K31,使用I2C0(PB2 , PB3),外设器件初始化时,需要先把I2C配置成GPIO口,然后利用GPIO模拟I2C发送指令(HELLO),之后重新配置为标准I2C与器件进行通讯。

代码在LM3S5K31上使用无误。现在MCU更换为TM4C1231,代码部分基本不变,系统无法正常运行。

看Datasheet,M4增加了一个GPIO口的“确认控制”。

现在在把PB2和PB3配置成普通GPIO的时候,先进行确认设置更改,当完成HELLO指令后,重新配置成为I2C,但是器件仍然不能正常工作。亲帮忙看看还有什么原因:

/* 解锁IO口 */
HWREG(GPIO_PORTB_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTB_BASE + GPIO_O_CR) |= (GPIO_PIN_2 | GPIO_PIN_3); /* bits can be written */
HWREG(GPIO_PORTB_BASE + GPIO_O_LOCK) = 0x0;

/* 将SDA SCL初始化成IO */
GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_2);
GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_3);

/* 调用IO 模拟I2C发送 */
BSP_I2C_GPIO_Start();
BSP_I2C_GPIO_WriteByte(1, &ucData);
BSP_I2C_GPIO_Stop();

/* 重新配置为I2C接口 */
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
/* 解锁IO口 */
HWREG(GPIO_PORTB_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTB_BASE + GPIO_O_CR) |= (GPIO_PIN_2 | GPIO_PIN_3); /* bits can be written */
HWREG(GPIO_PORTB_BASE + GPIO_O_LOCK) = 0x0;

/*将PB3 (65),PB2(72)分别配置给I2C0SDA,I2C0SCL*/
GPIOPinConfigure(GPIO_PB2_I2C0SCL);
GPIOPinConfigure(GPIO_PB3_I2C0SDA);
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_2); //MCU BUG
I2CMasterEnable(I2C0_BASE);


/*配置I2C的时钟周期为100kbps*/
/*false默认选择为100k,true默认选择为400k*/
I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);

  • 配置I2C端口时,使用如下语句:

    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);

    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);

    详细可以参考TivaWare中的例程:

    C:\ti\TivaWare_C_Series-2.1.0.12573\examples\peripherals\i2c

  • 谢谢你的回答,问题的原因找到了,是我配置IO口模拟I2C的时候,时钟和数据的管脚设置反了。

    但是还有问题就是有关管脚解锁的问题。芯片手册中说PB2和PB3默认配置为I2C0,如果需要作为普通的IO口使用,需要“解锁”

    下面是手册中的相关介绍(DS-TM4C1231E6PZ-15842.2741 第620页)

    t: The table below shows special consideration GPIO pins. Most GPIO pins are configured
    as GPIOs and tri-stated by default (GPIOAFSEL=0, GPIODEN=0, GPIOPDR=0, GPIOPUR=0, and GPIOPCTL=0).
    Special consideration pins may be programed to a non-GPIO function or may have special commit
    controls out of reset. In addition, a Power-On-Reset (POR) or asserting RST returns these GPIO to
    their original special consideration state.

    a. This pin is configured as a GPIO by default but is locked and can only be reprogrammed by
    unlocking the pin in the GPIOLOCK register and uncommitting it by setting the GPIOCR register.

    The GPIO commit control registers provide a layer of protection against accidental programming of
    critical hardware signals including the GPIO pins that can function as JTAG/SWD signals and the NMI
    signal. The commit control process must be followed for these pins, even if they are programmed as
    alternate functions other than JTAG/SWD
    e “Commit Control” on page 627.
    e “Commit Control” on page 627.

    但是后来发现,这两个IO口,即便不执行所谓的“解锁”操作,也可以配置成普通IO口,那么这个

    “解锁”操作到底是怎么使用的?什么时候需要使用呢?谢谢!

  • 只有JTAG相关的四个脚和NMI复用的2个脚需要解锁。其他脚在功能切换时不需要考虑解锁。

    具体方法是在Lock寄存器写入KEY,然后再操作commit寄存器就好了。具体方法如下:

    10.2.4 Commit Control
    The GPIO commit control registers provide a layer of protection against accidental programming of
    critical hardware peripherals. Protection is provided for the GPIO pins that can be used as the four
    JTAG/SWD pins and the NMI pin (see “Signal Tables” on page 1330 for pin numbers). Writes to
    protected bits of the GPIO Alternate Function Select (GPIOAFSEL) register (see page 671), GPIO
    Pull Up Select (GPIOPUR) register (see page 677), GPIO Pull-Down Select (GPIOPDR) register
    (see page 679), and GPIO Digital Enable (GPIODEN) register (see page 682) are not committed to
    storage unless the GPIO Lock (GPIOLOCK) register (see page 684) has been unlocked and the
    appropriate bits of the GPIO Commit (GPIOCR) register (see page 685) have been set.

  • 好的,非常感谢!!

  • 你好,能否将你的I2C源文件给我参考下,我用的I2C做外设AD用,数据总是读出来都为0.

  • /* 配置为I2C接口 */

    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

    /*将PB3 (65),PB2(72)分别配置给I2C0SDA,I2C0SCL*/
    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_2); //MCU BUG
    I2CMasterEnable(I2C0_BASE);


    /*配置I2C的时钟周期为100kbps*/
    /*false默认选择为100k,true默认选择为400k*/
    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);

  • 确实如此。不这样配置波形都出不来。