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/TM4C123GH6PM:I2C 不工作或 SD1306初始化错误?

Guru**** 2609285 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/753885/ccs-tm4c123gh6pm-i2c-not-working-or-sd1306-init-wrong

器件型号:TM4C123GH6PM

工具/软件:Code Composer Studio

大家好。 我正在使用 Tiva TM4C123GXL 一段时间、现在尝试使用 I2C 模块。 首先、尝试使其写入和读取24C04存储器、这与我在 PIC 上执行的数千次操作完全相同。 但它不起作用:即使在写入相同的地址之后、我读取的所有内容都是0xFF。
我赢得了 SD1306显示屏并尝试了、但它仍然不起作用。 那么、我是否缺少有关 TI I2C 模块的信息? 显示屏连接到电路板、由电路板提供3V3、但当我打开电路时、显示屏上不会出现任何情况、我的绿色 LED 亮起(请参阅代码底部的)、这意味着它已执行所有指令。 以下是我的代码:

#include 
#include 
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/pio.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"





#include "driverlib/pin_map.h"#include "driverlib/rom.idtrl"
//驱动程序库遇到错误时调用的错误例程。
//
#ifdef debug
void
__error__(char *pcFilename、uint32_t ui32Line)
{
while (1);
}
#endif


//*********
// Definiticoes das interfaces da placa Tiva
//*********
#define RED_LED GPIO_PIN_1 //PF1
#define BLE_LED GPIO_PIN_2 //PF2
#define GREEN_LED GPIO_PIN_3 //PF3
#define SW1 GPIO_PIN_4 //PF4
#define SW2 GPIO_PIN_0 //PF0


//*********
//显示定义
//*********
#define SSD1306_LCDWIDTH 128
#define SSD1306_LCDHEIGHT 64
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALN_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_SDMALDISPLLARE0xA6
#define SSD1306_INTSDTRY012_SEARTRY012_SETRF#define 0x06_SETRF#define RSDTRUARTRY012_SETRUARTRY012_SETRUARTRUST#define 0x06_SETRUARTRUARTRUST#define 0x06_SETRUARTRUARTRUST#define 0x06 0x06 0x07_SETRUARTRUST#define

#define 013017017012_SETRUARTSDTRUST#define #define #define #define




#define #define 012_SETPOSTUARTSDTRUARTRY012_SETRUARTRY012_SETRY012_SE















void 1306_memorymode 0x20 #define SSD1306_COLUMNADDR 0x21 #define SSD1306_PAGEADDR 0x22 #define SSD1306_COMSCANDEC 0xC8 #define SSD1306_COMSCANDEC 0xC8 #define SSD1306_SEGREMAP 0xA0 #define SSD1306_CHARGEMP 0xC0 #define SSD1306_COMSCANDECC_CLUSTRD 0x6 #define UCC_CLUSTRUCC_CLUSTRD (#define 0x6 0x6 #define UCC_CLUSTRUCC_CLUSTRUCC_U

if (atraso!= 0)
SysCtlDelay (atricasa*(SysCtlClockGet ()/(3*1000)));// Atro de 1ms
}


void I2C0_Init (void)
{
//
//启用外设时钟
//
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_I2C0);
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);

//
// I2C0 I2C0SCL 的使能引脚 PB2
//
MAP_GPIOPinConfigure (GPIO_PB2_I2C0SCL);
MAP_GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2);

//
// I2C0 I2C0SDA 的使能引脚 PB3
//
MAP_GPIOPinConfigure (GPIO_PB3_I2C0SDA);
MAP_GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3);

MAP_I2CMasterInitExpClk (I2C0_BASE、SysCtlClockGet ()、TRUE);
}

void SSD1306_command (uint8_t c)
{
uint8_t CONTROL = 0x80;//有些使用0x00,其他示例使用0x80。 我尝试了这两种方法
MAP_I2CMasterSlaveAddrSet (I2C0_BASE、0x78、false);
MAP_I2CMasterDataPut (I2C0_BASE、CONTROL);
MAP_I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
while (MAP_I2CMasterBusy (I2C0_BASE));
MAP_I2CMasterDataPut (I2C0_BASE、c);
MAP_I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);
while (map_I2CMasterBusy (I2C0_BASE));
}

//根据 SSD1306数据表和 Web 上的许多位置初
始化 void Initialize_SSD1306 ()
{
// 128x64 OLED 模块的初始化序列
SSD1306_COMMAND (SSD1306_DISPLAYOFF); // 0xAE
SSD1306_COMMAND (SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
SSD1306_COMMAND (0x80); //建议的比率0x80
SSD1306_COMMAND (SSD1306_SETMULTIPLEX); // 0xA8
SSD1306_COMMAND (0x3F);
SSD1306_COMMAND (SSD1306_SETDISPLAYOFFSET); // 0xD3
SSD1306_COMMAND (0x0); //无偏移
SSD1306_COMMAND (SSD1306_SETSTARTLINE);//| 0x0); //行#0
SSD1306_COMMAND (SSD1306_CHARGEPUMP); // 0x8D
SSD1306_COMMAND (0x14); //使用内部 VCC
SSD1306_COMMAND (SSD1306_memorymode); // 0x20
SSD1306_COMMAND (0x00); // 0x00水平寻址
SSD1306_COMMAND (SSD1306_SEGREMAP | 0x1); //旋转屏幕180
SSD1306_COMMAND (SSD1306_COMSCANDEC); //旋转屏幕180
SSD1306_COMMAND (SSD1306_SETCOMPINS); // 0xDA
SSD1306_COMMAND (0x12);
SSD1306_COMMAND (SSD1306_SETCONTRAST); // 0x81
SSD1306_COMMAND (0xCF);
SSD1306_COMMAND (SSD1306_SETPRECHARGE); // 0xd9
SSD1306_COMMAND (0xF1);
SSD1306_COMMAND (SSD1306_SETVCOMDETECT); // 0xDB
SSD1306_COMMAND (0x40);
SSD1306_COMMAND (SSD1306_DISPLAYALLON_RESUME); // 0xA4
SSD1306_COMMAND (SSD1306_NORMALDISPLAY); // 0xA6
SSD1306_COMMAND (SSD1306_DISPLAYON); //打开 OLED
}

//*********
//主
页//*********
int main (void)
{
MAP_SysCtlClockSet (SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHz|SYSCTL_OSC_MAIN);

MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
while (!map_SysCtlPeripheralReady (SYSCTL_Periph_GPIOF));

MAP_GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、RED_LED|blue_LED|GREEN_LED);

I2C0_Init();
Initialize_SSD1306 ();

SSD1306_COMMAND (SSD1306_DISPLAYALLON);

GPIOPinWrite (GPIO_PORTF_BASE、GREEN_LED、GREEN_LED);

ROM_SysCtlSleep ();
}

我需要一些帮助。 我无法使用此类微控制器、也无法了解如何使用它的 I2C 模块。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我不熟悉 SD1306。 您需要检查几件事。

    SD1306似乎可以从不同的 MCU 接口中进行选择、I2C 是其中之一、而 SPI 等其他接口。 请检查您是否正在选择 I2C 接口。
    2.您确定 SD1306能够以400kps 的速率运行吗? 为什么不首先从100kps 标准 I2C 波特率开始? 应将 I2CMasterInitExpClk (I2C0_BASE、SysCtlClockGet ()、false)设置为 true、而不是 true。
    3.使用示波器或逻辑分析仪监视总线事务。 主器件是否驱动总线、从器件是否使用 ACK 进行回复?
    4. SCL 和 SCA 总线上是否有适当的上拉电阻器?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    1) 1)我无法选择、一旦电路板只能访问 I2C 接口;

    2) 2)即使在100kbps 时也无法正常工作;

    3)我没有:(

    4) 4)它具有已焊接到电路板上的上拉电阻器。

    使用我的 PIC18F2550,它运行良好。 我刚刚将上面的代码移到了 XC8、它可以正常工作、因此不会出现代码或连接问题。 由于24C04内存无法与 TivaWare + Tiva Launchpad 配合使用、我想这是问题所在。

    我应该尝试直接寄存器访问、而不是 TivaWare 库吗?

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

    尝试添加下面的行、看看它会有什么不同。

    发件人:

        MAP_I2CMasterSlaveAddrSet(I2C0_BASE, 0x78, false);
        MAP_I2CMasterDataPut(I2C0_BASE, control);
        MAP_I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
        while(MAP_I2CMasterBusy(I2C0_BASE));
        MAP_I2CMasterDataPut(I2C0_BASE, c);
        MAP_I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
        while(MAP_I2CMasterBusy(I2C0_BASE));
    至:
        MAP_I2CMasterSlaveAddrSet(I2C0_BASE, 0x78, false);
        MAP_I2CMasterDataPut(I2C0_BASE, control);
        MAP_I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
        while(!MAP_I2CMasterBusy(I2C0_BASE)); // Add this line
        while(MAP_I2CMasterBusy(I2C0_BASE));
        MAP_I2CMasterDataPut(I2C0_BASE, c);
        MAP_I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
        while(!MAP_I2CMasterBusy(I2C0_BASE)); // Add this line
        while(MAP_I2CMasterBusy(I2C0_BASE));
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    没有发生任何情况(我还将总线速度设置为100kbps)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果您甚至没有示波器、我真的无法为您提供帮助。 它是任何工程类型工作的重要工具。 看看你是否可以借用一个。 是否确定从地址是0x80而不是0x3C? 从器件地址是不带 R/W 位的地址。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我付不起一个。 对于巴西的一名学生来说、这是非常昂贵的。 我不确定是否可以在假期使用大学的实验室。 这是机会!
    是的、我确信这是地址、因为它使用该地址与 PIC 一起工作。

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

    查看下面的 API。 从机地址是一个7位地址。 它正在向左移位一位。 根据 SD1306数据表、从器件地址为0x3C。 不同 MCU 的工作方式不同。 您不能只将您的 PIC 代码直接移植到 Tiva 器件。  

    无效

    I2CMasterSlaveAddrSet (uint32_t ui32Base、uint8_t ui8SlaveAddr、

               bool bReceive)

      //

      //检查参数。

      //

      assert (_I2CBaseValid (ui32Base));

      assert (!(ui8SlaveAddr & 0x80));

      //

      //设置主设备将与之通信的从设备的地址。

      //

      HWREG (ui32Base + I2C_O_MSA)=(ui8SlaveAddr << 1)| bReceive

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

    哦、人! 它解决了我的问题。 我假设 TivaWare 会执行(地址| R/W 位)、而是执行(地址<< 1)| R/W 位)、那么、我的故障、伙计们。
    只需将>>1添加到所有地址(我的显示屏和 EEPROM 存储器)即可解决问题、一切工作正常! 谢谢大家。