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.

[参考译文] TMS320F28069:I2C 软件实现

Guru**** 2559630 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/951016/tms320f28069-i2c-software-implementation

器件型号:TMS320F28069

您好!

我想在硬件定义的引脚之外的引脚上使用 I2C 访问 EEPROM (24AA128)。 因此、我尝试在软件中实现 I2C 协议。 但我遇到了一些奇怪的问题、请查看下面的实施情况、看看是否有人可以找出问题。

我的软件 I2C 功能:

void i2c_software_gpio_init (void)
{
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO30 = 1;
GpioCtrlRegs.GPAPUD.bit.GPIO31 = 1;

GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 0;
GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 0;

GpioCtrlRegs.GPADIR.bit.GPIO30 = 1;
GpioCtrlRegs.GPADIR.bit.GPIO31 = 1;

EDIS;
}

void i2c_software_start_condition (void)
{
SDA_SET;
SCL_SET;
延迟(40);
SDA_CLEAR;
延迟(40);
SCL_CLEAR;
延迟(40);
}


void i2c_software_stop_condition (void)
{
SDA_CLEAR;
SCL_SET;
延迟(40);
SDA_SET;
延迟(40);
SCL_CLEAR;
延迟(40);
}

uint8 i2c_software_write_byte (uint16字节)
{
uint16 i;
uint8 ACK = 0;
对于(i=0;i<8;i++){
if (byte & 0x80){
SDA_set;
} 否则{
SDA_CLEAR;
}
SCL_SET;
延迟(20);
SCL_CLEAR;
延迟(20);
字节<<= 1;
}
SDA_SET;
SCL_SET;
SDA_DIR = IN_MODE;
ACK = SDA;
延迟(20);
SCL_CLEAR;
SDA_DIR = OUT_MODE;
SDA_CLEAR;
延迟(20);
返回!ACK
;}

uint16 i2c_software_read_Byte (uint16 ack_bit)
{
uint16 i、byte = 0;
SDA_DIR = IN_MODE;
对于(i=0;i<8;i++){
SCL_SET;
字节<<= 1;
延迟(20);
字节=(字节| SDA);
SCL_CLEAR;
延迟(20);
}

SDA_DIR = OUT_MODE;

如果(ACK_BIT = 1)
SDA_CLEAR;
其他
SDA_SET;

延迟(12);
SCL_SET;
延迟(20);
SCL_CLEAR;
延迟(20);

返回字节;
} 
#define SCL_set GpioDataRegs.GPASET.ALY|=0x40000000
#define SCL_Clear GpioDataRegs.GPACLEAR.ALY|=0x40000000
#define SDA_set GpioDataRegs.GPASET.ALY|=0x80000000
#define SDA_Clear GpioRegs.GPADA.1#define GPADA.GPIO1.GPIO1.000#define GPIOREP.GPIO1.GPIO1.GPIO1.000#define G1_GPIOREP.GPIO1.GPIO1.GPIO1.GPIO1.GPIOR.GPIO1.GPIO1.GPIOR.GPIO1.GPIOR.GPIO1.GPIO1.GPIOR.GPIO1.GPIO1.GPIOR.GPIO



调用这些函数以访问 eerprom 的序列(24AA128):

I2C_software_start_condition ();
AC1 = i2c_software_write_byte (EEPROM_address | 0);
AC2 = i2c_software_write_byte (0x00);
AC3 = i2c_software_write_byte (0x00);
AC4 = i2c_software_write_byte (0xc0);
I2C_software_stop_condition ();

Task_sleep (10);


I2C_software_start_condition ();
AC1 = i2c_software_write_byte (EEPROM_address | 0);
AC2 = i2c_software_write_byte (0x00);
AC3 = i2c_software_write_byte (0x00);


Task_sleep (10);

I2C_software_start_condition ();
AC4 = i2c_software_write_byte (EEPROM_address | 1);
EEPROM_DATA_Receive = i2c_software_read_Byte (0);
I2C_software_stop_condition ();

Task_sleep (20); 

逻辑分析仪上生成的信号

逻辑分析仪可以正确解码信号、但第三个字节中的一个零的长度比其他字节长、这可能是问题、但不知道导致问题的原因。 当我将信号连接到 EEPROM 时、我确实会从该信号获得任何响应。

如果我有任何问题、请告诉我。

谢谢、

Najeeb

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

    您好、Najeeb、

    我不确定为什么您的第3个字节中的 SCL 脉冲延迟、看看您的软件。 您的程序中是否还有其他可能延迟生成 SCL 脉冲的并行运行项目?

    有关您提供的逻辑波形的一些注释:

    • SCL 在波形的两侧开始和结束低电平。 I2C 为低电平有效、不使用时应为高电平
    • 您的从器件地址和所有字节都被 NACK。 不确定是否在测试时已连接 EEPROM。 当处于 ACK/NACK 阶段时、SDA 应该是 F2806x 的一个输入以接收来自从器件的响应。

    最棒的

    Kevin

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

    尊敬的 Kevin:

    感谢您的回答。 作为测试、我将软件 i2c 引脚与 Arduino 连接、并使用 i2c 从程序加载 Arduino。 现在我已成功地从控制器接收 Arduino 数据、但 i2c_software_read_Byte 无法正常工作。 I2C 文档指定在读取和应答期间释放 SDA 引脚、但实际上并不知道这意味着什么。

    以下是 Arduino 与控制器之间的通信信号:

    谢谢、

    Najeeb

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

    您好、Najeeb、

    [引用 user="Najeeb Uddin"]i2c 文档指定在读取和应答期间释放 SDA 引脚、但实际上不知道这意味着什么。

    是的、没错。 发送器件应在数据阶段控制 SDA 线、接收器件应在 ACK/NACK 位期间控制 SDA 线。

    从 C2000器件侧、器件引脚应在这些接收部分期间配置为输入、以便发送器件可以控制引脚。 C2000随后将需要读取每个数据和 Nack/ACK 位。

    最棒的

    Kevin

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

    感谢 Kevin、他工作正常、实际上我在从公共汽车上读取代码时没有波纹波和 EDIS。 添加后、它就像一种魅力。

    谢谢、

    Najeeb