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.

[参考译文] CCS:无法初始化 I2C (EK-TM4C 123GXL)

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/593847/ccs-failed-to-initialize-i2c-ek-tm4c-123gxl

工具/软件:Code Composer Studio

您好!

我正在使用 Tiva EK-TM4C 123GXL Launch Pad、并希望通过 I2C 连接一些传感器。
但我不明白为什么它不起作用。

代码下方的值。

/*
 * main.c
 *
#include
#include
#include
#include
#include
#include
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_ints.h"
//#include "inc/hw_i2c.h"          //未使用?
//#include "inc/hw_sysctl.h"       //未使用?
//#include "inc/hw_types.h"        //未使用?
#include "driverlib/gpio.h"
//#include "driverlib/interrupt.h"   //未使用?
#include "driverlib/sysctl.h"
#include "driverlib/pwm.h"
#include "driverlib/pin_map.h"
#include "driverlib/uart.h"
#include "driverlib/i2c.h"
#include "utils/uartstdio.h"
#include "elmarlib/common.h"
#include "elmarlib/EEPROM.h"
#include "elmarlib/misc.h"
#include "elmarlib/tof .h"
#include "elmarlib/lcd.h"
#include "sensorlib/hw_mpu9150.h"

void main (void){
   uint32_t slave_addr = 0x69;
/*端口初始化*/
   //将16MHz 晶体设置为主振荡器、使用400MHz PLL 除以12.5= 16MHz 系统时钟
   SysCtlClockSet (SYSCTL_SYSDIV_12_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHz|SYSCTL_OSC_MAIN);

   //让所有外部组件有一段时间启动
   SysCtlDelay (SLEEP_1ms * 20);

   SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);                       //启用用于 I2C 总线的 GPIO 端口
   while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOA)){}
   SysCtlPeripheralEnable (SYSCTL_Periph_I2C1);                        //在 PD0 = SCL、PD1 = SDA 上为 MPU 传感器启用 I2C 外设
   while (!SysCtlPeripheralReady (SYSCTL_Periph_I2C1)){}

   GPIOPinConfigure (GPIO_PA6_I2C1SCL);                                //为 I2C3功能配置引脚复用
   GPIOPinConfigure (GPIO_PA7_I2C1SDA);A
   GPIOPinTypeI2CSCL (GPIO_Porta_base、GPIO_PIN_6);                    //为这些引脚选择 I2C 功能。
   GPIOPinTypeI2C (GPIO_Porta_base、GPIO_PIN_7);
              //检查是否启用了外设访问
                 //等待 I2C 模块准备就绪
   I2CMasterInitExpClk (SYSCTL_Periph_I2C1、SysCtlClockGet ()、false); //初始化主控和受控
                                                                  //可以使用快速模式

   I2CMasterSlaveAddrSet (I2C1_base、slave_addr、false);              //reg = I2CMDR;
                                                                 //读取从器件上的指定寄存器
                                                                      //指定我们要向写入(寄存器地址)
                                                                      //从器件
/*I2C 初始化*/
   //uint8_t 测试= 1;

   I2CMasterDataPut (slave_addr、0x75);                               //指定要读取的寄存器
                                                      //Annahme:reg=i2cmdr、HWREG (ui32Base + I2C_O_MDR)= ui8Data;

   I2CMasterControl (I2C1_base、I2C_MASTER_CMD_SINGLE_SEND);          //向从器件发送控制字节和寄存器地址字节

   while (I2CMasterBusy (I2C1_base));                                  //等待 MCU 完成事务
                                                                      //如果 I2C 总线忙则返回 true;否则返回 false。

   I2CMasterErr (I2C1_base);                                          //返回错误状态、作为 I2C_MASTER_ERR_NONE 之一、
                                                                      ///I2C_MASTER_ERR_ADDR_ACK、I2C_MASTER_ERR_DATA_ACK 或
                                                                      //I2C_MASTER_ERR_ARB_Lost。


   //I2CMasterSlaveAddrSet (I2C3_base、slave_addr、true);             //指定我们将从从从器件读取

   //I2CMasterControl (I2C3_base、I2C_MASTER_CMD_SINGLE_Receive);     //发送控制字节并从指定的寄存器中读取

   //while (I2CMasterBusy (I2C3_base));                                //等待 MCU 完成事务

   I2CMasterDataGet (I2C1_base);                                      //返回从指定寄存器中提取的数据
                                                                      //evtl so schreiben:return I2CMasterDataGet (I2C3_base);


   }


谢谢、致以诚挚的问候。

Thomas

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在软件中没有看到任何明显的东西。 您检查了硬件吗? 您是否在 SCL 和 SDA 上有上拉电阻器? 您与什么从设备通信? 0x69是正确的地址吗? 在使用示波器查看 SDA 和 SCL 时、您是否看到正确的 I2C 信号? 您是否从从器件获得确认?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    现在它起作用了。 似乎有多个错误。
    除了使用"模拟"上拉电阻外、我还更改了代码 A 位。
    -->使用逻辑解串器等示波器获得正确的信号。
    /*
    * main.c
    *
    #include
    #include
    #include
    #include
    #include
    #include
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    #include "inc/hw_ints.h"
    //#include "inc/hw_i2c.h" //未使用?
    //#include "inc/hw_sysctl.h" //未使用?
    //#include "inc/hw_types.h" //未使用?
    #include "driverlib/gpio.h"
    //#include "driverlib/interrupt.h"//未使用?
    #include "driverlib/sysctl.h"
    #include "driverlib/pwm.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/uart.h"
    #include "driverlib/i2c.h"
    #include "utils/uartstdio.h"
    #include "elmarlib/common.h"
    #include "elmarlib/EEPROM.h"
    #include "elmarlib/misc.h"
    #include "elmarlib/tof .h"
    #include "elmarlib/lcd.h"
    #include "sensorlib/hw_mpu9150.h"


    uint32_t I2CReceive (uint32_t SLAVE_addr、uint8_t reg)

    I2CMasterSlaveAddrSet (I2C2_base、slave_addr、false); //reg = I2CMDR;
    //读取从器件上的指定寄存器
    //指定我们要向写入(寄存器地址)
    //从器件


    I2CMasterDataPut (slave_addr、reg); //指定要读取的寄存器
    //Annahme:reg=i2cmdr、HWREG (ui32Base + I2C_O_MDR)= ui8Data;

    I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_SEND_START); //将控制字节和寄存器地址字节发送到从器件

    while (I2CMasterBusy (I2C2_base)); //等待 MCU 完成事务
    I2CMasterErr (I2C2_base); //返回错误状态、作为 I2C_MASTER_ERR_NONE 之一、
    ///I2C_MASTER_ERR_ADDR_ACK、I2C_MASTER_ERR_DATA_ACK 或
    //I2C_MASTER_ERR_ARB_Lost。


    I2CMasterSlaveAddrSet (I2C2_base、slave_addr、true); //指定我们将从从从器件读取

    I2CMasterControl (I2C2_base、I2C_MASTER_CMD_SINGLE_Receive); //发送控制字节并从我们指定的寄存器中读取
    while (I2CMasterBusy (I2C2_base)); //等待 MCU 完成事务

    返回 I2CMasterDataGet (I2C2_base); //如果 I2C 总线忙则返回 true;否则返回 false。


    //uint8_t ReadAccel (uint8_t reg)
    //{
    //uint8_t accelData = I2CReceive (ACCEL_SLAVE_ADDR、reg);

    //返回 accelData;
    //}

    void main (void){
    uint32_t slave_addr = 0x69;
    uint32_t data_unser;
    /*端口初始化*/
    //将16MHz 晶体设置为主振荡器、使用400MHz PLL 除以12.5= 16MHz 系统时钟
    SysCtlClockSet (SYSCTL_SYSDIV_12_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHz|SYSCTL_OSC_MAIN);

    //SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    //sysctl_XTAL_16MHz);
    //让所有外部组件有一段时间启动
    //SysCtlDelay (SLEEP_1ms * 20);


    SysCtlPeripheralEnable (SYSCTL_Periph_I2C2); //在 PD0 = SCL、PD1 = SDA 上为 MPU 传感器启用 I2C 外设
    while (!SysCtlPeripheralReady (SYSCTL_Periph_I2C2)){}
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE); //启用用于 I2C 总线的 GPIO 端口
    while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOE)){}

    GPIOPinConfigure (GPIO_PE4_I2C2SCL); //为 I2C3功能配置引脚复用
    GPIOPinConfigure (GPIO_PE5_I2C2SDA);
    GPIOPinTypeI2CSCL (GPIO_Porte _BASE、GPIO_PIN_4); //为这些引脚选择 I2C 功能。
    GPIOPinTypeI2C (GPIO_Porte _BASE、GPIO_PIN_5);
    //检查是否启用了外设访问
    //等待 I2C 模块准备就绪
    I2CMasterInitExpClk (I2C2_base、SysCtlClockGet ()、false);//初始化主控和受控
    //可以使用快速模式
    while (1){
    I2CReceive (SLAVE_ADDR、0x75);
    DATA_UNSER = I2CReceive (SLAVE_ADDR、0x75);





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

    [引用 user="Thomas Metzger85"]现在它可以正常工作。

    请注意、您已"从"I2C1切换到 I2C2 -如果它在(所有)候选端口上成功、则"适当"的修复更令人满意。   您是否可以详细说明切换到另一个 I2C 通道的情况?

    I2C1 -如果存储器可用-"默认"进入 I2C 模式-这通常会帮助用户成功。   您的发帖和我们的客户之一最近的联系都注意到 I2C1的"困难"、这证明了他们的好奇心。

    您写下的"模拟"上拉电阻器-您是指"外部电阻器"-还是一个独立的电流源(用于该角色)。   您的 MCU 和 I2C 从器件的下拉能力有限- I2C1可能会损坏-需要您"切换到另一个 I2C 通道..."

    很高兴您说:"正在运行/运行"。