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.

[参考译文] RTOS/TM4C123GH6ZRB:在 BIOS 调用之前 I2C 访问外部 EEPROM

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/669381/rtos-tm4c123gh6zrb-i2c-acces-to-external-eeprom-before-bios-call

器件型号:TM4C123GH6ZRB

工具/软件:TI-RTOS

您好!

在 BIOS_start()之前,我需要通过 I2C0主器件对外部 EEPROM 进行读写。 下面是我用于读取和写入操作的代码片段。 外部 EEPROM 的位置0x0000中的值为0x03。 但读取的值始终为零。  

如何在 BIOS_start()之前执行 EEPROM 读取和写入?

#define EPPROM_DEVICE_ADDRESS 0xAE
#define EEPROM_ADDRESS (EPPROM_DEVICE_ADDRESS >> 1)

void EepromRead (uint16_t address_u16、uint8_t * rxdata、uint8_t rxdataLen)

uint8_t ret = 0;
uint8_t address_u8;

I2CMasterSlaveAddrSet (I2C0_BASE、EPPROM_DEVICE_ADDRESS、false);
while (I2CMasterBusy (I2C0_BASE)){}

SysCtlDelay (1000);

I2CMasterDataPut (I2C0_BASE、0x00);//读取
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
while (I2CMasterBusy (I2C0_BASE)){}

SysCtlDelay (1000);

address_u8 =(uint8_t)(address_U16 >> 8);
I2CMasterDataPut (I2C0_BASE、ADDRESS_u8);//第一个字地址
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_CONT);
while (I2CMasterBusy (I2C0_BASE)){}

SysCtlDelay (1000);


address_u8 =(uint8_t)(address_U16);
I2CMasterDataPut (I2C0_BASE、ADDRESS_u8);//第二个字地址
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);
while (I2CMasterBusy (I2C0_BASE)){}

SysCtlDelay (1000);

I2CMasterSlaveAddrSet (I2C0_BASE、EPPROM_DEVICE_ADDRESS、TRUE);
while (I2CMasterBusy (I2C0_BASE)){}

SysCtlDelay (1000);

I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);
while (I2CMasterBusy (I2C0_BASE)){}

SysCtlDelay (1000);

RET = I2CMasterDataGet (I2C0_BASE)& 0xFF;
rxdata[0]= ret;

void main()

 uint8_t rxBuff[1];

 EepromRead (0x0000、rxBuff、1);

 System_printf ("数据读取%x\n"、rxBuff[0]);

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

    我不知道您连接的是哪个 EEPROM 器件。 查看您的代码、我看到函数中有三个 I2CMasterDataPut。 我可以理解放置 EEPROM 字地址的最后两个 I2CMasterDataPut。 但我不确定您为什么需要 I2CMasterDataPut (I2C0_BASE、0x00)。 您的 EEPROM 器件是否需要这样做? 另一个需要检查的问题是、您是否在 SDA 和 SCL 总线上具有适当的上拉电阻器。 我建议您使用逻辑分析仪或示波器来捕获总线活动。 调试您的问题会更容易。 另外一件事是、如果您可以首先执行非基于 TI-RTOS 的 I2C 项目来连接您的器件。 我在您的代码中看不到您是如何初始化 I2C 和引脚多路复用等的 请参阅 TivaWare I2C 示例、了解您是否可以在没有 RTOS 的情况下首先连接到 EEPROM 器件。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    感谢您的回复。

    我正在使用 AT24C64D 外部 EEPROM。

    正如您所说的、不需要第一个 I2CMasterDataPut "I2CMasterDataPut (I2C0_BASE、0x00)"。

    下面是我的 I2C0主器件初始化代码。

    //使用前必须启用 I2C0外设。
    SysCtlPeripheralEnable (SYSCTL_Periph_I2C0);

    //为端口 B2和 B3上的 I2C0功能配置引脚复用。
    GPIOPinConfigure (GPIO_PB2_I2C0SCL);
    GPIOPinConfigure (GPIO_PB3_I2C0SDA);

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

    GPIOPadConfigSet (GPIO_PORTB_BASE、GPIO_PIN_3、GPIO_Strength _8mA_SC、GPIO_DIR_MODE_HW | GPIO_PIN_TYPE_OD);

    //启用 I2C0主机模块
    I2CMasterEnable (I2C0_BASE);

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

    您好!

     您未启用 GPIOB。 您 也需要 SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB)。 您无需调用 GPIOPadConfigSet(...)。  GPIOPinTypeI2C 将负责管脚配置。 请查看下面的 GPIOPintypeI2C 函数。

    void
    GPIOPinTypeI2C (uint32_t ui32port、uint8_t ui8pins)
    {
    //
    //检查参数。
    //
    assert (_GPIOBaseValid (ui32Port));
    
    //
    //使引脚被外设控制。
    //
    GPIODirModeSet (ui32端口、ui8引脚、GPIO_DIR_MODE_HW);
    
    //
    //使用弱上拉设置用于开漏操作的焊盘。
    //
    GPIOPadConfigSet (ui32Port、ui8引脚、GPIO_Strength _2mA、GPIO_PIN_TYPE_OD);
    } 

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

    虽然从未承认(此处)-您已经充分利用了众所周知的"kiss"的强大功能-它始终提供最快、最简单的-推动成功。

    从等式中删除 RTOS 会大大简化-我认为在进入"RTOS Jungle (RTOS Jungle)"之前、应该考虑(部分)"确认所有函数都以"API Only (裸机)"形式成功。

    如此处所示-即使是最基本的"I2C 事务处理小型外部 EEPROM"、也需要"高度关注细节"。 加上(许多)因过早引入 RTOS 而引起的复杂问题似乎"低于最佳程度"。