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.

[参考译文] TMS320F28035:通过 I2C 使用 EEPROM 进行读写操作

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/710594/tms320f28035-read-and-write-operation-using-eeprom-through-i2c

器件型号:TMS320F28035
主题中讨论的其他器件: C2000WARE

您好!

我正在使用 TMS320F28035作为微控制 器和组合 bq7694000DBT + BQ78350DBTR-R1开发电池管理系统。 我们已经开发出采用 MSP430的 BMS 版本、由于所有示例和专家都回答了我们的所有问题、它运行良好。

在测试 CAN 总线网络后、在项目的这个阶段、下一步是开发一个 I2C 接口。 对于此任务、我将"Example_2803xI2C_EEPROM.c"和该主题中的一些信息(https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/303750?tisearch=e2e-quicksearch&keymatch=i2c%20read#pi316717=3)作为信息资源。

我们将测试分为三个步骤:

1) 1)将操作写入 Microchip 的 EEPROM 24LC32AT-I/SN (下图)。 它似乎工作正常、因为我可以多次写入。

2) 2)对同一 EEPROM 存储器执行读取操作。 它似乎也正常工作。 检索到的数据是不同的、因为它是一个计数器。

3)写入后的写入和读取操作。 此时会出现问题。 我无法进行写入和读取、因为程序似乎卡在读取函数上。 我已经阅读了上面提到的 I2C 寄存器文档和示例,但我无法找到问题。 我似乎没有清楚一些旗帜或类似的东西。

我随附了该代码。 请、有人能帮您解决这个问题吗?

提前感谢您。

e2e.ti.com/.../Desktop.rar

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

    您好、Felipe、

    对于您看到的问题、您说它卡在读取函数中、因此它永远不会返回? 您能看到调试时它在哪里卡住了吗? 您可能需要在读取功能中使用 I2CMDR 寄存器关闭自由模式才能成功进行调试。 在写入函数之后、您在示波器上没有看到任何内容吗? 可能有助于在写入函数之后的 CCS 表达式窗口中以及在读取函数的不同点调试 I2CSTR (状态寄存器)。

    对于写入然后读取测试、您是否执行了以下操作?

    错误= I2CA_WriteData (&I2cMsgOut1);
    
    错误= I2CA_ReadData (&I2cMsgIn1); 

    最棒的

    Kevin

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

    尊敬的 Kevin:

    感谢您的回复。

    是的、我正在执行上述过程以进行写入和读取。

    Watchig I2C 寄存器、当尝试读取时、I2C 状态寄存器内容为0x0410。 根据数据表、该寄存器值意味着未检测到下溢、同时数据已从 I2CDXR 复制到 I2CXSR。 假设 I2C 不处于复位状态、这是否意味着它正在等待 I2CDXR 寄存器的另一个负载?

    此致、

    Felipe。

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

    您好、Felipe、

    唯一的区别是 NACK SENT 位。 本应该在前面提到过、但在两种情况下(即写入之后和仅读取时)、在读取前后检查 I2CMDR 寄存器的值会很有用。 也许总线很忙?

    I2caRegs.I2CSTR.bit.BB = 1. 

    在代码中、读/写函数返回错误、但在主循环中没有错误检查。 读取/写入函数中是否出现任何错误? 在写入后执行读取时、您是否可以看到任何波形? 我可能需要再次运行示例程序并查看生成的波形、但我相信您必须尝试多次读取 EEPROM 地址、然后才能成功、而您只有一次尝试。

    最棒的

    Kevin

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

    尊敬的 Kevin:

    经过一些测试后、总线很可能会像您一样忙。 我对代码进行了一些更改、并在 main 函数中放置了一些断点(在写入函数之后和读取函数之后)、我能够准确地看到这两个波形、这完全符合预期。 但是、如果我删除断点、代码就像以前一样直接写入。 似乎有一些标志或状态会阻止正确的总线功能。

    因此、我在结束写入和读取函数之前执行了一个延迟函数、该函数需要进行一些调整。 这 不是一种优雅的方法、但正在发挥作用。 我不确定在最终项目中是否需要此任务(按顺序写入和读取)、但至少我有此选项。

    您是否需要更好的方法?

    我还附加了新代码。

    您好!

    Felipe。

    e2e.ti.com/.../BMS_5F00_v3.rar

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

    您好、Felipe、

    是的、初始写入通信可能尚未完成、I2C 外设也会被混淆。 我建议查看 C2000Ware 中的 Example_2803xI2C_EEPROM 示例程序如何使用 CurrentMsgPtr -> MsgStatus 处理其通信。

    您的读取函数可能会在其中的某个位置产生错误。 您可能应该实施某种错误检查/处理代码。 我可以看到以下两项检查中的一项触发:

    //
    //等待 STP 位从任何之前的主设备通信中清零。
    //模块清除该位的操作被延迟到 SCD 位之后
    //设置。 如果在启动新消息之前未选中此位
    // I2C 可能会被混淆。
    //
    IF (I2caRegs.I2CMDR.bit.STP==1)
    {
    返回 I2C_STP_NOT _READY_ERROR;
    }
    
    //
    //检查总线是否占线
    //
    IF (I2cRegs.I2CSTR.bit.BB = 1)
    {
    返回 I2C_BUS_BUS_BUSY_ERROR;
    } 

    希望这对您有所帮助、

    Kevin

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

    尊敬的 Kevin:

    我遵循了您的建议、我得到了下面的波形。 为了验证写入时间是否正确(最小值、幅度顺序相同)、我读取存储器数据表、发现最大写入时间周期为5ms、这与波形一致。 您认为这种支持是正确的吗?


    我们可以看到、控制器写入数据、并尝试读回数据。 它在返回前多次尝试。 之后、它会验证恢复的数据是否等于发送的数据。 如果是,它将使用 pass()函数停止程序。 我阅读了固件并查找了一些文档、但我不确定它是否符合预期。 您是否知道这是正确的固件功能?

    如果正确、下一步是将其用于其他器件。

    感谢您的所有支持。

     

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

    您好、Felipe、

    是的、这一切听起来不错。 我相信我会先引导您指出错误方向、因为您的读取函数中可能会发生错误。

    无法立即从 EEPROM 读取存储器的原因是地址设置部分未成功完成(即 EEPROM 未准备好发送请求的数据)。 正如您提到的、EEPROM 规范具有5ms 的最大写入周期时间、因此 epprom 最多需要5s 的时间来准备好将数据发送到 F2803x 主器件。

    如果您查看 i2c_EEPROM 程序示例、I2CA_ReadData 函数会等待从存储器中读取、直到 I2C_MSGSTAT_RESTART 状态建立:

    否则 if (msg->MsgStatus =I2C_MSGSTAT_RESTART)
    {
    I2caRegs.I2CCNT = msg->NumOfBytes;//设置预期的字节数
    I2caRegs.I2CMDR.ALL = 0x2C20; //将重新启动作为主接收器发送
    }
    返回 I2C_Success; 

    一旦 I2C_ARDY_ISRC (寄存器准备好访问)中断源代码被检测到、这个状态在 i2c_int1a_ISR 内建立:

    //
    //中断源=寄存器访问就绪
    //此中断用于确定何时设置 EEPROM 地址
    //读取数据通信的部分已完成。 因为没有停止位
    //命令,此标志告诉我们何时发送了消息而不是消息
    // SCD 标志。 如果接收到 NACK、清除 NACK 位并执行命令 A
    //停止。 否则、请转到通信的读取数据部分。
    //
    否则、IF (IntSource = I2C_ARDY_ISRC)
    {
    if (I2caRegs.I2CSTR.bit.nack = 1)
    {
    I2caRegs.I2CMDR.bit.STP= 1;
    I2caRegs.I2CSTR.All = I2C_CLR_Nack_bit;
    }
    否则(CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY)
    {
    CurrentMsgPtr ->MsgStatus = I2C_MSGSTAT_RESTART;
    }
    } 

    否则、每次执行 ReadData 时都会检测到停止条件、并保持 I2C_MSGSTAT_SEND_NOSTOP 状态、这会导致 ReadData 函数内的 EEPROM 设置部分每次都保持运行:

    //
    //中断源=检测到停止条件
    //
    if (IntSource = I2C_SCD_ISRC)
    {
    (笑声)
    //
    //如果在地址设置部分收到 NACK 消息
    //读取 EEPROM 时、下面的代码包含在中
    //寄存器访问就绪中断源代码将生成停止
    //条件。 在接收到停止条件后(此处)、设置
    //要重试的消息状态。 用户可能希望限制该数字
    //在生成错误之前重试次数。
    //
    if (CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY)
    {
    CurrentMsgPtr ->MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;
    }
    } 

    希望这对您有所帮助、

    Kevin

    编辑:是的,您对成功读取后使用 pass()函数暂停程序的理解是正确的。 该示例旨在仅从 EEPROM 读取2个字节、然后停止。

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

    感谢您的所有支持。 这解决了我的问题。

    此致、

    Felipe。