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.

[参考译文] MSP430I2041:具有 EMDC 和 CCS 的 MSP430i2041、可通过 I2C 读取结果

Guru**** 2434370 points
Other Parts Discussed in Thread: TIDM-3OUTSMTSTRP, MSP430I2041, MSP-ISO, UNIFLASH, MSP430F67791, MSP430G2553

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c

器件型号:MSP430I2041
主题中讨论的其他器件:TIDM-3OUTSMTSTRPMSP-ISOUNIFLASHMSP430F67791MSP430G2553

你(们)好

我叫 Dung。

我有 MSP430i2041 EVM 1电压(990K-2.4K - 220VAC 最大250V)、3电流(CT 1000.1、R = 6.8R 最大80A)的项目、我的设计采用相同 的 TIDM-3OUTSMTSTRP 并使用 CT、不包括继电器。

我有一些问题。 创建项目时 EMDC 上的电流、为什么 TI 计算 器的电流值约为实际值。

当我通过 EMDC 为 MSP430i2041使用套件 MSP430F5529LP 进行校准时、如果仅将3个 CT 连接到 EVM、则可以将结果读取到 EMDC、当 我将1V 3C 连接到 EVM 时、它无法连接到 EMDC。 我不知道为什么(我 不使用 MSP-ISO)。

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

    Dung、

    您是否查看了我对上一个主题中问题的反馈?

    MSP430I2041:当我在 Uniflash 加载映像文件上使用时出错

    此致、

    James

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

    你(们)好 James。 我已查看您的反馈。 我将回放线程。 使用 Uniflash 加载映像时出现该错误。 我认为它已经完成了。 如果在 Uniflash 加载映像文件上使用时连续线程 MSP430I2041:错误 ,则此线程关闭。

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

    尊敬的 Dung:

    如果您尚未将另一个线程标记为已解决、请执行此操作。 您可以将您的 EMDC 相关问题和我的答案复制到本主题中、然后我们可以在此处继续。

    此致、

    James

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

    你(们)好 James。

    我没有疑问的其他主题。 将 HID 连接 到套件 MSP430i2041 (EVM)上的校准值时、该线程出现错误。  

    EVM 1电压(990K-2.4K - 220VAC 最大250V)、3电流(CT 1000.1、Rshunt = 6.8R 最大80A)、我的设计采用相同 的 TIDM-3OUTSMTSTRP 并使用 CT、不包括继电器。

    当我通过 EMDC 使用套件 MSP430F5529LP 校准 MSP430i2041时、如果仅将3个 CT (具有当前认为的 CT)连接到 EVM、则可以读取结果到 EMDC (具有数据结果) 并向 EVM 添加电压、它无法连接到 EMDC ( EMDC 上无接收器数据结果)。 我不知道为什么它无法读取数据。 我 不使用 MSP-ISO。

    此致。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="466056" URL"~/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3637745 #3637745"]当我通过 EMDC 使用套件 MSP430F5529LP 对 MSP430i2041进行校准时、如果仅将3个 CT (具有当前的 CT 值)连接到 EVM、则可以将结果读取到 EMDC (具有数据结果) 并向 EVM 添加电压、但无法连接到 EMDC ( EMDC 上无接收器数据结果)。 我不知道为什么它无法读取数据。 我 不使用 MSP-ISO。

    请注意不要使用 MSP-ISO。 如果 AC 线路被接至电路板接地而不是 AC 中性点、并且您没有使用 MSP-ISO、那么您的 PC 可能会被损坏、并且您可能会感到震惊。

    您说的是、当您将交流电压连接到电路板时、通信会停止? 这可能是电源问题。 电路板是如何供电的? 电池? 交流/直流电源? F5529 LPTM 确保没有电源冲突。

    确保在对任何引脚施加电压之前或期间为电路板供电(例如、连接传感器、连接 UART 引脚)。

    [引用 userid="466056" URL"~/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3637745 #3637745"] EVM 1电压(990K-2.4k - 220VAC 最大250V)、3电流(CT 1000.1、Rshun=6.8R 最大80A)、我的设计采用相同 的 TIDM-3OUTSMTSTRP 并使用 CT、不包括继电器。[/quot]

    我在 EMDC 中创建了同一个项目、并且连接到 i20xx 以查看结果或校准电路板时没有遇到任何问题。

    • 使用1V 和3C 传感器创建了新的 EMDC 项目
    • 基于 TIDM-3OUTSMTSTRP 配置的库
    • 保存的 EMDC 项目
    • 生成的代码
    • 将代码导入到 CCS 中
    • 已编程 i20xx
    • 关闭 CCS
    • 将 i20xx 连接到 F5529 LP (HID 桥)
    • 在 EMDC 中打开 MCU
    • 单击"连接"
    • 显示了未经校准的结果
    • 已启动校准模式、没有任何问题

    下面是我这边的一些屏幕截图。

    此致、

    James

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

    您的项目与我的项目相同运行。  

    [引用 userid="216616" URL"~/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3638273 #3638273)]您说过、将交流电压连接到电路板时、通信会停止? 这可能是电源问题。 电路板是如何供电的? 电池? 交流/直流电源? F5529 LPTM 确保没有电源冲突。[/报价]

    我已经使用5529LP 和交流/直流电源、交流/直流模块以及相同的 TIDM-3OUTSMTSTRP 进行了电源测试。  我已小心地将 Neutral 连接到 EVM 的0V。   您能否在 TIDM-3OUTSMTSTRP 上测试校准帮助。 您的连接是什么?

    当我校准时、我将 TX、RX、GND 连接到5529LP 板的 P3.4、P3.3和 GND。 不施加电压时的数据结果。

    如果我向 EVM 施加电压、 我等待5分钟、数据不更新。

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

    我要把这一问题分治。 我不认为这是 EMDC 问题、而是电源问题。 在不连接任何交流电源的情况下、使用 F5529 LP 或工作台电源为您的电路板供电。 EMDC 通信应该工作、并且您应该能够进入校准模式。 如果可以、则表明您的电源在连接交流电源时导致器件停止通信、您可以开始调试、而不是进行通信。

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

    现在、我无法为我的项目处理 i2041、因为我不理解为什么它无法校准。 我切换到另一个用于 EVM 的 IC、因为 我没有时间进行测试。 如果将来我有时间、也许 我可以测试和使用它。 MSP430i2401和 msp430F67791很抱歉、它不适用于我的项目。 我有更多的时间去做,但没有预期的好。

    非常感谢、James。

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

    你(们)好 James。

    TI 为客户提供了设计 EVM 的解决方案。 为什么 TI 不 在 客户设计的代码流值中集成示例校准值计算器。

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

    尊敬的 Dung:

    手动校准过程很复杂、需要一个精确的测试源来对电路板施加精确的电压、电流和相位角。 EMDC GUI 仍需要测试源、但可轻松执行校准过程。 然后、您可以在最终设计中使用应用的校准因数、方法是在 CCS 工程中更新这些因数、或通过 UART 从系统中的主机 MCU 或处理器发送这些因数。

    有关校准计算的更多详细信息、请参阅以下主题。

    MSP430i2041:需要 EMDC 校准因子计算详细信息

    此致、

    James

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

    你好、Jame。

    当读取完整结果电压模式通用(1V 3 CT)时、EMDC MCU 中的电压大于80%、但当施加电压时为实际值 I MCU 过载=> 我无法读取结果并对其进行校准。  然后、我读取 Vrms、IRMS、V Peak、I Peak、有功功率 有功电能。 我可以对其进行校准。

    现在、通过 I2C 读取结果、但它不读取数据。 我在 Arduino 上使用 ESP8266。

    启动 I write 55 AA 06 04 01 01 07 00、读取 I write 55 AA 06 04 80 00 01 0D 00 (VRMS PHASE A)。 结果为0189040E、当我更改读取 IRMS PhaseA 和 V 时、另一相的 I 得到相同的结果。

    我不明白。 写入 I2C 可能有误?  I READ 模式器件0x0A 在 EVM_START ()中为"0"=> IDLE

    byte evm_config(uint8_t device,uint8_t cmdRW, uint8_t cmdValue)
    { // 55 AA 06 04 CMD_CONFIG_MODE cmdRW cmdValue crcl crch
      byte byte_in,error;
      prepare_evm_write(CMD_CONFIG_MODE,cmdRW,cmdValue,6);
    
      Wire.beginTransmission(device);
      Serial.print(" Device: "); Serial.print(device,HEX); Serial.print(" "); 
      for(byte i=0;i<9;i++) {
        Wire.write(evm_write_message[i]);  
        if(cmdRW==CMD_WRITE)Serial.print(evm_write_message[i],HEX);
      }
      error = Wire.endTransmission();//Wire.endTransmission();
      if(cmdRW==CMD_READ){
        Wire.requestFrom(device, 1);
        byte_in = Wire.read();
        Serial.print(byte_in,HEX);
      }
      Serial.println(" ");
      return error;
    }
    void evm_start(){
      if(evm_config(i2041a,CMD_WRITE,CMD_MODE_ACTIVE)==0) Serial.println("Start Phase A - Ok. ");
      else Serial.println("Start Phase A - error. ");
      if(evm_config(i2041b,CMD_WRITE,CMD_MODE_ACTIVE)==0) Serial.println("Start Phase B - Ok. ");
      else Serial.println("Start Phase B - error. ");
      if(evm_config(i2041c,CMD_WRITE,CMD_MODE_ACTIVE)==0) Serial.println("Start Phase C - Ok. ");
      else Serial.println("Start Phase C - error. ");
       Serial.print("Read mode Device A");  evm_config(i2041a,CMD_READ,CMD_READ);
       Serial.print("Read mode Device B");  evm_config(i2041b,CMD_READ,CMD_READ);
       Serial.print("Read mode Device C");  evm_config(i2041c,CMD_READ,CMD_READ);
    }

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

    尊敬的 Dung:

    [引用 userid="466056" URL"~/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3666456 #3666456]EMDC MCU 中的电压模式通用(1V 3 CT)大于80%、但实际应用电压 I Ming MCU 过载=> 我无法读取结果并对其进行校准。  然后、我读取 Vrms、IRMS、V Peak、I Peak、有功功率 有功电能。 我可以对其进行校准。

    很抱歉、但我不理解这一点。 您是否说您可以在未施加电压时读取这些值、但在施加电压时无法读取这些值? 除非存在电源冲突、否则这一点无关紧要。 如果您使用的是 MSP-ISO、如果您的电路板已经具有交流/直流至3V3电源、请确保您没有为3V3使用隔离式电源。

    [引用 userid="466056" URL"~/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3666456 #3666456]Start I write 55 AA 06 04 01 01 07 00、读取时 I write 55 AA 06 04 80 00 01 0D 00 (VRMS Phase A)。 结果为0189040E、当我更改读取 IRMS PhaseA 和 V 时、另一相的 I 的结果相同。[/引用]

    对于这些命令、您可以在最新的 EMDC 技术指南(v1.40、截至目前)中查看协议。 确保您在命令中更改相位 ID 字节。

    [引用 userid="466056" URL"~/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3666456 #3666456)]我不理解。 写入 I2C 可能有误?  我的读取模式器件0x0A 为"0"=>在 EVM_START ()中空闲

    我不确定 Arduino 代码。 也许您可以将其发布在 Arduino 论坛上。 我还建议在 i20xx 上仅使用 TI Resource Explorer 中提供的 I2C 代码示例中的一个示例以及虚拟数据、以使 I2C 通信与 EMDC 项目分开工作。 然后、您可以在 EMDC 项目工作时将 I2C 代码集成到该项目中。

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

    你(们)好 James。

    [引用 userid="216616" URL"~/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3666989 #3666989"]我很抱歉,但我不理解这一点。

    当 我在模式1V 3 CT 中使用所有参数(0x80-0x8B)创建新的项目 EVM 时、数据结果可以在交流电压未连接时与 EMDC 连接。 当我将交流电压连接到 EVM =>无法读取由 EMDC 校准的结果。

    如果我使用 VRMS、IRMS、Vpeak、IPEAK、有功功率 能量功率模式1V 3 CT、我可以通过 EMDC 校准 EVM。

    [引用 userid="216616" URL"~/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3666989 #3666989">我不确定 Arduino 代码。 也许您可以将其发布在 Arduino 论坛上。 我还建议在 i20xx 上仅使用 TI Resource Explorer 中提供的 I2C 代码示例中的一个示例以及虚拟数据、以使 I2C 通信与 EMDC 项目分开工作。 然后、您可以在 EMDC 项目工作时将 I2C 代码集成到该项目中。

    您能否向我发送示例项目:MSP430F5529LP 与 EVM MSP430i2041之间的 I2C 通信。 通过 I2C 5529LP 读取结果后  、通过 UART 将数据调试发送到 PC。 我希望测试 I2C 读取数据在 MSP430Fxx 中正常。 请帮帮我。

    我的项目需要通过 Wifi 互联网将数据发送到服务器。  

      

    非常感谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="466056" URL"~/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3670712 #3670712"]

    当 我在模式1V 3 CT 中使用所有参数(0x80-0x8B)创建新的项目 EVM 时、数据结果可以在交流电压未连接时与 EMDC 连接。 当我将交流电压连接到 EVM =>无法读取由 EMDC 校准的结果。

    如果我使用 VRMS、IRMS、Vpeak、IPEAK、有功功率 能量功率模式1V 3 CT、我可以通过 EMDC 校准 EVM。

    [/报价]

    EVM 上编程的 EMDC 代码必须与 EMDC 项目匹配。 否则通信可能无法正常工作。

    [引用 userid="466056" URL"~/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3670712 #3670712"]您能否向我发送示例项目:MSP430F5529LP 与 EVM MSP430i2041之间的 I2C 通信。 通过 I2C 5529LP 读取结果后  、通过 UART 将数据调试发送到 PC。 我希望测试 I2C 读取数据在 MSP430Fxx 中正常。 请帮我。

    查看我之前的评论。 我建议从 TI Resource Explorer 中的 I2C 代码示例开始(在 CCS 中或在 dev.ti.com 上)。 正如我之前提到的、您需要将这项工作拆分并取得递增的进展。

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

    您在测量中使用 i2041进行了 I2C 通信。 使用 i2041写入读取数据的示例。 您能否编写示例代码来初始化 i2041以运行并读取测量的电压或电流数据?

    在此应用中、您能否向我发送示例代码以从 i2041读取数据?

    当我需要读取时、VRMS、IRMS 和其他数据的地址是什么?

    通常情况 下、我会以待写入的形式(SlaveAdd、Address & read 或 write、data write 或 data to read)读取和写入 EEPROM。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="466056" URL"~/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3697380 #3697380"]您使用 i2041进行了 I2C 通信测量。

    我不确定你的意思。

    [引用 userid="466056" URL"~/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3697380 #3697380"]您能否向我发送示例代码,以便在此应用程序中从 i2041读取数据。

    您可以在 CCS 内的 TI Resource Explorer 中或在 dev.ti.com 中找到 i20xx I2C 示例代码。

    [引用 userid="466056" URL"~/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/983896/msp430i2041-msp430i2041-with-emdc-and-ccs-and-read-result-over-i2c/3697380 #3697380"]当我想阅读时,VRMS、IRMS 和其他数据的地址是什么?

    这些只是存储在 RAM 中的变量、您可以将这些变量与 I2C 一起用于向主机发送数据。

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

    您好、James Evans。

    我使用 I2C 从 i2041读取结果 EVM。 我在 MSP430G2553上写入。 MSP430G2553是更成熟的 I2C 将读取多器件 i2041的数据 EVM (添加0x0A)。 但我的代码只读取结果00 FF FF FF FF FF FF FF FF FF FF FF FF 请检查我的状态、我已发送 I2C_Master_Write (SLAVE_ADDR、MasterType0、TYPE_0_LENGTH); //{0x55、0xAA、0x06、0x04、0x01、0x01、0x07、0x00};  在读取数据  {0x55、0xAA、0x04、0x80、0x00、0x4、0x00、0x4、0x4、0x4、0x00、0x4、0x4、0x4、0x00};

    //******************************************************************************
    //   MSP430G2xx3 Demo - USCI_B0, I2C Master multiple byte TX/RX
    //
    //   Description: I2C master communicates to I2C slave sending and receiving
    //   3 different messages of different length. I2C master will enter LPM0 mode
    //   while waiting for the messages to be sent/receiving using I2C interrupt.
    //   ACLK = NA, MCLK = SMCLK = DCO 16MHz.
    //
    //
    //                   MSP430G2553
    //                 -----------------
    //            /|\ |             P2.6|--- XIN
    //             |  |                 |   |
    //             ---|RST              |   32kHz
    //                |                 |   |
    //                |             P2.7|--- XOUT
    //                |             P1.1|<------- Receive Data (UCA0RXD)
    //                |             P1.2|-------> Transmit Data (UCA0TXD)
    //                |             P1.6|<------- Receive Data (UCB0SCL)
    //                |             P1.7|-------> Transmit Data (UCB0SDA)
    //
    //   Nima Eskandari
    //   Texas Instruments Inc.
    //   April 2017
    //   Built with CCS V7.0
    //******************************************************************************
    
    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    
    //******************************************************************************
    // UART Initialization *********************************************************
    //******************************************************************************
    
    #define SMCLK_11500     0
    #define SMCLK_9600      1
    #define ACLK_9600       2
    
    #define UART_MODE       SMCLK_11500
    
    //******************************************************************************
    // I2C Initialization **********************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR  0x0A
    
    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
     * The slave will send example SlaveTypeX buffers in response.
     *
     * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
     * The slave will initialize itself to receive MasterTypeX example buffers.
     * */
    
    #define SLAVE_ADDR  0x0A
    
    #define TYPE_0_LENGTH   9
    #define TYPE_1_LENGTH   10
    #define TYPE_2_LENGTH   10
    
    #define MAX_BUFFER_SIZE     20
    // 00010100 0 0 01010101 10101010
    uint8_t MasterType0 [TYPE_0_LENGTH] = {0x55,0xAA,0x06,0x04,0x01,0x01,0x01,0x07,0x00};
    uint8_t MasterType1 [TYPE_1_LENGTH] = {0x55,0xAA,0x07,0x04,0x80,0x00,0x00,0x00,0x84,0x00};
    uint8_t MasterType2 [TYPE_2_LENGTH] = {0x55,0xAA,0x07,0x04,0x80,0x00,0x01,0x00,0x85,0x00};
    
    #define SLAVE_READ0   11
    #define SLAVE_READ1   15
    
    uint8_t SlaveRead0 [SLAVE_READ0] = {0};
    
    //******************************************************************************
    // General I2C State Machine ***************************************************
    //******************************************************************************
    
    
    typedef enum I2C_ModeEnum{
        IDLE_MODE,
        NACK_MODE,
        TX_REG_ADDRESS_MODE,
        RX_REG_ADDRESS_MODE,
        TX_DATA_MODE,
        RX_DATA_MODE,
        SWITCH_TO_RX_MODE,
        SWITCH_TO_TX_MODE,
        TIMEOUT_MODE
    } I2C_Mode;
    
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    
    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;
    
    /* ReceiveBuffer: Buffer used to receive data in the ISR
     * RXByteCtr: Number of bytes left to receive
     * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
     * TransmitBuffer: Buffer used to transmit data in the ISR
     * TXByteCtr: Number of bytes left to transfer
     * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
     * */
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    
    /* I2C Write and Read Functions */
    
    /* For slave device with dev_addr, writes the data specified in *reg_data
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_MASTER
     * *reg_data: The buffer to write
     *           Example: MasterType0
     * count: The length of *reg_data
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
    
    /* For slave device with dev_addr, read the data specified in slaves reg_addr.
     * The received data is available in ReceiveBuffer
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_SLAVE
     * count: The length of data to read
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    
    I2C_Mode I2C_Master_Read(uint8_t dev_addr, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = RX_DATA_MODE;
    //    TransmitRegAddr = reg_addr;
        RXByteCtr = count;
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB0I2CSA = dev_addr;
        IE2 |= UCB0RXIE;              // Enable RX interrupt
        IE2 &= ~UCB0TXIE;             // Disable TX interrupt
        UCB0CTL1 &= ~UCTR;            // Switch to receiver
        MasterMode = RX_DATA_MODE;    // State state is to receive data
        UCB0CTL1 |= UCTXSTT;          // Send repeated start
    
    //    IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);       // Clear any pending interrupts
    //    IE2 &= ~UCB0RXIE;                       // Disable RX interrupt
    //    IE2 |= UCB0TXIE;                        // Enable TX interrupt
    
    //    UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
    //    __bis_SR_register(CPUOFF + GIE);              // Enter LPM0 w/ interrupts
        __bis_SR_register( GIE);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    
    I2C_Mode I2C_Master_Write(uint8_t dev_addr, uint8_t *reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_DATA_MODE;
    //    TransmitRegAddr = reg_addr;
    
        //Copy register data to TransmitBuffer
        CopyArray(reg_data, TransmitBuffer, count);
    
        TXByteCtr = count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB0I2CSA = dev_addr;
        IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);       // Clear any pending interrupts
        IE2 &= ~UCB0RXIE;                       // Disable RX interrupt
        IE2 |= UCB0TXIE;                        // Enable TX interrupt
    
        UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(GIE);              // Enter LPM0 w/ interrupts
    //    __bis_SR_register(CPUOFF + GIE);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = reg_addr;
        RXByteCtr = count;
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB0I2CSA = dev_addr;
        IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);       // Clear any pending interrupts
        IE2 &= ~UCB0RXIE;                       // Disable RX interrupt
        IE2 |= UCB0TXIE;                        // Enable TX interrupt
    
        UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(CPUOFF + GIE);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    
    }
    
    
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = reg_addr;
    
        //Copy register data to TransmitBuffer
        CopyArray(reg_data, TransmitBuffer, count);
    
        TXByteCtr = count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB0I2CSA = dev_addr;
        IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);       // Clear any pending interrupts
        IE2 &= ~UCB0RXIE;                       // Disable RX interrupt
        IE2 |= UCB0TXIE;                        // Enable TX interrupt
    
        UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(CPUOFF + GIE);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
        }
    }
    
    //******************************************************************************
    // UART Configtion *************************************************************
    //******************************************************************************
    
    void putcUART(uint8_t data)
    {
        while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
        UCA0TXBUF = data;
    }
    
    void putsUART(uint8_t *data)
    {
        while (*data)
        {
            putcUART(*data);
            data++;
        }
    }
    void initUART()
    {
    #if UART_MODE == SMCLK_11500
        UCA0CTL1 |= UCSSEL_2;                     // SMCLK
        UCA0BR0 = 138;                            // 16MHz 115200
        UCA0BR1 = 0;                              // 16MHz 115200
        UCA0MCTL = UCBRS_7;                       // Modulation UCBRSx = 7
        UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
        IFG2 &= ~(UCA0RXIFG);
        IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt
    #elif UART_MODE == SMCLK_9600
        UCA0CTL1 |= UCSSEL_2;                     // SMCLK
        UCA0BR0 = 104;                            // 16MHz 9600
        UCA0BR1 = 0;                              // 16MHz 9600
        UCA0MCTL = UCBRS_0 + UCOS16 + UCBRF_3;    // Modulation UCBRSx = 0
        UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
        IFG2 &= ~(UCA0RXIFG);
        IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt
    #elif UART_MODE == ACLK_9600
        UCA0CTL1 |= UCSSEL_1;                     // ACLK
        UCA0BR0 = 3;                              // 32768Hz 9600
        UCA0BR1 = 0;                              // 32768Hz 9600
        UCA0MCTL = UCBRS_3;                       // Modulation UCBRSx = 3
        UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
        IFG2 &= ~(UCA0RXIFG);
        IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt
    #else
        #error "Select UART Baud Rate of 115200 or 9600"
    #endif
    }
    
    //******************************************************************************
    // Device Initialization *******************************************************
    //******************************************************************************
    
    void initClockTo16MHz()
    {
        if (CALBC1_16MHZ==0xFF)                  // If calibration constant erased
        {
            while(1);                               // do not load, trap CPU!!
        }
        DCOCTL = 0;                               // Select lowest DCOx and MODx settings
        BCSCTL1 = CALBC1_16MHZ;                    // Set DCO
        DCOCTL = CALDCO_16MHZ;
    }
    
    void initGPIO()
    {
    //    P1DIR |= BIT0 + BIT1 + BIT2 + BIT3 + BIT4;
    //    P1OUT &= ~(BIT0 + BIT1 + BIT2 + BIT3 + BIT4);
    //
    //    P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
    //    P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
    
        P1DIR |= BIT0;// + BIT3 + BIT4;
        P1OUT &= ~(BIT0);// + BIT3 + BIT4);
    
        // P1.1 = RXD, P1.2=TXD, P1.6 = SCL, P1.7 = SDA;
        P1SEL |= BIT1 + BIT2 + BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
        P1SEL2|= BIT1 + BIT2 + BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
    }
    
    void initI2C()
    {
        UCB0CTL1 |= UCSWRST;                      // Enable SW reset
        UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
        UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
        UCB0BR0 = 40;                            // fSCL = SMCLK/40 = ~400kHz
        UCB0BR1 = 0;
        UCB0I2CSA = SLAVE_ADDR;                   // Slave Address
        UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
        UCB0I2CIE |= UCNACKIE;
    }
    
    
    //******************************************************************************
    // Main ************************************************************************
    // Send and receive three messages containing the example commands *************
    //******************************************************************************
    
    int main(void) {
        long i;
        WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
    
        initClockTo16MHz();
        initGPIO();
        initUART();
        initI2C();
        //putcUART('A');
        //putsUART("Hello A");
        I2C_Master_Write(SLAVE_ADDR, MasterType0, TYPE_0_LENGTH);
        I2C_Master_Write(SLAVE_ADDR, MasterType0, TYPE_0_LENGTH);
        I2C_Master_Write(SLAVE_ADDR, MasterType0, TYPE_0_LENGTH);
        //putsUART(" 1 ");
        I2C_Master_Write(SLAVE_ADDR, MasterType2, TYPE_1_LENGTH);
       // putsUART(" 2 ");
        I2C_Master_Read(SLAVE_ADDR, SLAVE_READ0);
        CopyArray(ReceiveBuffer, SlaveRead0, SLAVE_READ0); //uint8_t SlaveRead0 [SALVE_READ0] = {0};
        //putsUART("\n Send Data:");
        for(i=0;i<11;i++){
            putcUART(ReceiveBuffer[i]);
        }
    //    I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_0_MASTER, MasterType0, TYPE_0_LENGTH);
    //    I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_1_MASTER, MasterType1, TYPE_1_LENGTH);
    //    I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_2_MASTER, MasterType2, TYPE_2_LENGTH);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_0_SLAVE, TYPE_0_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_1_SLAVE, TYPE_1_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType1, TYPE_1_LENGTH);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_2_SLAVE, TYPE_2_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType2, TYPE_2_LENGTH);
    
        //__bis_SR_register(LPM0_bits + GIE);
        while(1)
        {
               //putsUART(" 1 ");
               I2C_Master_Write(SLAVE_ADDR, MasterType1, TYPE_1_LENGTH);
              // putsUART(" 2 ");
               I2C_Master_Read(SLAVE_ADDR, SLAVE_READ0);
               CopyArray(ReceiveBuffer, SlaveRead0, SLAVE_READ0); //uint8_t SlaveRead0 [SALVE_READ0] = {0};
               //putsUART("\n Send Data:");
               for(i=0;i<11;i++){
                   putcUART(ReceiveBuffer[i]);
               }
    //           for(i=0;i<100000;i++){
    //
    //                      }
    
        }
    }
    
    //******************************************************************************
    // I2C Interrupt For Received and Transmitted Data******************************
    //******************************************************************************
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCIAB0TX_VECTOR
    __interrupt void USCIAB0TX_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      if (IFG2 & UCB0RXIFG)                 // Receive Data Interrupt
      {
          //Must read from UCB0RXBUF
          uint8_t rx_val = UCB0RXBUF;
    
          if (RXByteCtr)
          {
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;
          }
    
          if (RXByteCtr == 1)
          {
              UCB0CTL1 |= UCTXSTP+UCTXNACK;
    
          }
          else if (RXByteCtr == 0)
          {
              IE2 &= ~UCB0RXIE;
              MasterMode = IDLE_MODE;
              __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
          }
      }
      else if (IFG2 & UCB0TXIFG)            // Transmit Data Interrupt
      {
          switch (MasterMode)
          {
              case TX_REG_ADDRESS_MODE:
                  UCB0TXBUF = TransmitRegAddr;
                  if (RXByteCtr)
                      MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                  else
                      MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
                  break;
    
              case SWITCH_TO_RX_MODE:
                  IE2 |= UCB0RXIE;              // Enable RX interrupt
                  IE2 &= ~UCB0TXIE;             // Disable TX interrupt
                  UCB0CTL1 &= ~UCTR;            // Switch to receiver
                  MasterMode = RX_DATA_MODE;    // State state is to receive data
                  UCB0CTL1 |= UCTXSTT;          // Send repeated start
                  if (RXByteCtr == 1)
                  {
                      //Must send stop since this is the N-1 byte
                      while((UCB0CTL1 & UCTXSTT));
                      UCB0CTL1 |= UCTXSTP;      // Send stop condition
                  }
                  break;
    
              case TX_DATA_MODE:
                  if (TXByteCtr)
                  {
                      UCB0TXBUF = TransmitBuffer[TransmitIndex++];
                      TXByteCtr--;
                  }
                  else
                  {
                      //Done with transmission
                      UCB0CTL1 |= UCTXSTP;     // Send stop condition
                      MasterMode = IDLE_MODE;
                      IE2 &= ~UCB0TXIE;                       // disable TX interrupt
                      //__bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
                  }
                  break;
    
              default:
                  __no_operation();
                  break;
          }
      }
    }
    
    
    //******************************************************************************
    // I2C Interrupt For Start, Restart, Nack, Stop ********************************
    //******************************************************************************
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCIAB0RX_VECTOR  // USCIAB0TX_VECTOR
    __interrupt void USCIAB0RX_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCIAB0RX_VECTOR))) USCIAB0RX_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        if (IFG2 & UCA0RXIFG)
        {
            uint8_t rx_val = UCA0RXBUF; //Must read UCxxRXBUF to clear the flag
            putcUART(rx_val);
        }
        if (UCB0STAT & UCNACKIFG)
        {
            UCB0STAT &= ~UCNACKIFG;             // Clear NACK Flags
        }
        if (UCB0STAT & UCSTPIFG)                        //Stop or NACK Interrupt
        {
            UCB0STAT &=
                ~(UCSTTIFG + UCSTPIFG + UCNACKIFG);     //Clear START/STOP/NACK Flags
        }
        if (UCB0STAT & UCSTTIFG)
        {
            UCB0STAT &= ~(UCSTTIFG);                    //Clear START Flags
        }
    }
    
     

      我已阅读您在 e2e.ti.com/.../3121142 请将项目发送给我、您可以通过 i2c ok 写入读取数据。

    非常感谢。

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

    此线程应包含有关使用 I2C 进行更改的详细信息。

    MSP430I2040:连接 I2C 上的 MSP430i2040S 分项计量 EVM

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

    你(们)好 James。  

    我用 f5529编写代码。  我的项目 通过 I2C 读取 evmi2041 (多器件)并通过 UART 发送到 PC、现在我连接了一个器件 EVM、但数据结果不正确。 请与我联系

    //******************************************************************************
    //   MSP430F552x Demo - USCI_B0, I2C Master multiple byte TX/RX
    //
    //   Description: I2C master communicates to I2C slave sending and receiving
    //   messages of different length. I2C master will enter LPM0 mode
    //   while waiting for the messages to be sent/receiving using I2C interrupt.
    //   ACLK = NA, MCLK = SMCLK = DCO 16MHz.
    //
    //                                     /|\ /|\
    //                   MSP430F5529       4.7k |
    //                 -----------------    |  4.7k
    //            /|\ |             P3.1|---+---|-- I2C Clock (UCB0SCL)
    //             |  |                 |       |
    //             ---|RST          P3.0|-------+-- I2C Data (UCB0SDA)
    //                |                 |
    //                |             P3.3|-------+-- UART TX (UCA0 TXD)
    //                |                 |
    //                |             P3.4|-------+-- UART RX (UCA0 RXD)
    //                |                 |
    //                |                 |
    //
    //   Texas Instruments Inc.
    //   June 2019
    //   Built with CCS V9.x
    //******************************************************************************
    
    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    char update;
    
    //******************************************************************************
    // UART Initialization *********************************************************
    //******************************************************************************
    
    #define SMCLK_11500     0
    #define SMCLK_9600      1
    #define ACLK_9600       2
    
    #define UART_MODE       SMCLK_115200
    const char hex_digits[] = "0123456789ABCDEF";
    void initUART()
    {
        // Configure USCI_A0 for UART mode
        UCA0CTLW0 = UCSWRST;                      // Put eUSCI in reset
    #if UART_MODE == SMCLK_115200
    
        UCA0CTLW0 |= UCSSEL__SMCLK;               // CLK = SMCLK
        // Baud Rate calculation
        // 16000000/(16*115200) = 8.6805
        // Fractional portion = 0.6805
        // Use Table 24-5 in Family User Guide
        UCA0BR0 = 8;                               // 16000000/16/9600
        UCA0BR1 = 0x00;
        UCA0MCTL |= UCOS16 | UCBRF_11 | UCBRS_0;
    
    #elif UART_MODE == SMCLK_9600
    
        UCA0CTLW0 |= UCSSEL__SMCLK;               // CLK = SMCLK
        // Baud Rate calculation
        // 16000000/(16*9600) = 104.1667
        // Fractional portion = 0.1667
        // Use Table 24-5 in Family User Guide
        UCA0BR0 = 104;                            // 16000000/16/9600
        UCA0BR1 = 0x00;
        UCA0MCTL |= UCOS16 | UCBRF_3 | UCBRS_0;
    
    #elif UART_MODE == ACLK_9600
    
        UCA0CTLW0 |= UCSSEL__ACLK;               // CLK = ACLK
        // Baud Rate calculation
        // 32768/(9600) = 3.4133
        // Fractional portion = 0.4133
        // Use Table 24-5 in Family User Guide
        UCA0BR0 = 3;                             // 32768/9600
        UCA0BR1 = 0x00;
        UCA0MCTL |= UCBRS_3;    //0x0300 is UCBRSx = 0x03
    
    #else
        # error "Please specify baud rate to 115200 or 9600"
    #endif
    
        UCA0CTLW0 &= ~UCSWRST;                    // Initialize eUSCI
        UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
    }
    
    //******************************************************************************
    // Device Initialization *******************************************************
    //******************************************************************************
    
    void putcUART(uint8_t data)
    {
        while (!(UCA0IFG & UCTXIFG));             // USCI_A0 TX buffer ready?
            UCA0TXBUF = data;                  // TX -> RXed character
    }
    void putsUART(uint8_t *data)
    {
        while (*data)
        {
            putcUART(*data);
            data++;
        }
    }
    
    void putHexUART(uint8_t c)
    {   //uint8_t c;
        putcUART(hex_digits[c >> 4]);
        putcUART(hex_digits[c & 15]);
    }
    void putsHexPC(uint8_t *buff, uint8_t len)
    {
        uint8_t i;
        for(i=0;i<len;i++)   {
            putHexUART(buff[i]);
            putcUART(' ');
        }
    }
    
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR  0x0A
    
    #define MAX_BUFFER_SIZE     50
    
    
    // CMD 0x01 = Configure Mode
    #define CMD_01_MASTER      0x01
    // send 2 bytes of payload
    #define CMD_01_LENGTH   2
    // Payload[0] = 0x01: Write, [1] = 0x01: Active
    uint8_t MasterCMD01Payload [CMD_01_LENGTH] = { 0x01, 0x01};
    
    #define RESPONSE_SLAVE_LENGTH  15
    
    //******************************************************************************
    // General I2C State Machine ***************************************************
    //******************************************************************************
    
    typedef enum I2C_ModeEnum{
        IDLE_MODE,
        NACK_MODE,
        TX_DATA_MODE,
        RX_DATA_MODE,
        TIMEOUT_MODE,
        ERROR_MODE
    } I2C_Mode;
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    
    /* ReceiveBuffer: Buffer used to receive data in the ISR
     * RXByteCtr: Number of bytes left to receive
     * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
     * TransmitBuffer: Buffer used to transmit data in the ISR
     * TXByteCtr: Number of bytes left to transfer
     * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
     * */
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    
    /* I2C Write and Read Functions */
    
    I2C_Mode I2C_Master_ReadDataBlocking(uint8_t dev_addr, uint8_t count);
    void CopyArray_wCRC(uint8_t *source, uint8_t *dest, uint8_t count, uint16_t *CRC);
    I2C_Mode I2C_Master_WriteCmdBlocking(uint8_t dev_addr, uint8_t cmd, uint8_t *payload, uint8_t count);
    
    
    I2C_Mode I2C_Master_ReadDataBlocking(uint8_t dev_addr, uint8_t count)
    {
    
        if (count > MAX_BUFFER_SIZE)
        {
            return ERROR_MODE;
        }
    
        /* Initialize state machine */
        RXByteCtr = count;
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB0I2CSA = dev_addr;
        UCB0IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB0IE |= UCRXIE;                       // Enable RX interrupt
        UCB0IE &= ~UCTXIE;                      // Disable TX interrupt
    
        __disable_interrupt();
        MasterMode = RX_DATA_MODE;
        UCB0CTL1 &= ~UCTR;
        UCB0CTL1 |= UCTXSTT;             // I2C RX, start condition
        while (MasterMode == RX_DATA_MODE)
        {
            __bis_SR_register(LPM0_bits + GIE);              // Enter LPM0 w/ interrupts
            __disable_interrupt();
        }
    
        return MasterMode;
    
    }
    I2C_Mode I2C_Master_Write_cmd(uint8_t dev_addr,uint8_t command)
    {
        uint16_t total_count=10;
        uint8_t CRC_Calc = command+4;
    
        // If size is OK, fill buffer
        TransmitBuffer[0] = 0x55;   // header
        TransmitBuffer[1] = 0xAA;   // header
        TransmitBuffer[2] = 0x07;   // packet length (ID, CMD, payload, checksum)
        TransmitBuffer[3] = 0x04;    // Design Center ID
        TransmitBuffer[4] = command;    // command
        TransmitBuffer[5] = 0x00;    //
        TransmitBuffer[6] = 0x00;    //
        TransmitBuffer[7] = 0x00;    //
        TransmitBuffer[8] = CRC_Calc;    // CRC
        TransmitBuffer[9] = 0x00;    // CRC
    
        putsHexPC(TransmitBuffer,total_count);
        TXByteCtr = total_count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB0I2CSA = dev_addr;
        UCB0IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB0IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB0IE |= UCTXIE;                        // Enable TX interrupt
    
        __disable_interrupt();
        /* Initialize state machine */
        MasterMode = TX_DATA_MODE;
        UCB0CTL1 |=  UCTR | UCTXSTT;             // I2C RX, start condition
        while(MasterMode == TX_DATA_MODE)
        {
            __bis_SR_register(LPM0_bits + GIE);              // Enter LPM0 w/ interrupts
            __disable_interrupt();
        }
    
        return MasterMode;
    }
    
    I2C_Mode I2C_Master_Write_Config(uint8_t dev_addr)
    {
        uint16_t total_count=9;
    
        // If size is OK, fill buffer
        TransmitBuffer[0] = 0x55;   // header
        TransmitBuffer[1] = 0xAA;   // header
        TransmitBuffer[2] = 0x06;   // packet length (ID, CMD, payload, checksum)
        TransmitBuffer[3] = 0x04;   // Design Center ID
        TransmitBuffer[4] = 0x01;   // command
        TransmitBuffer[5] = 0x01;   // Write
        TransmitBuffer[6] = 0x01;   // Active
        TransmitBuffer[7] = 0x07;   // CRC
        TransmitBuffer[8] = 0x00;   // CRC
    
        putsHexPC(TransmitBuffer,total_count);
        TXByteCtr = total_count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB0I2CSA = dev_addr;
        UCB0IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB0IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB0IE |= UCTXIE;                        // Enable TX interrupt
    
        __disable_interrupt();
        /* Initialize state machine */
        MasterMode = TX_DATA_MODE;
        UCB0CTL1 |=  UCTR | UCTXSTT;             // I2C RX, start condition
        while(MasterMode == TX_DATA_MODE)
        {
            __bis_SR_register(LPM0_bits + GIE);              // Enter LPM0 w/ interrupts
            __disable_interrupt();
        }
    
        return MasterMode;
    }
    
    I2C_Mode I2C_Master_WriteCmdBlocking(uint8_t dev_addr, uint8_t cmd, uint8_t *payload, uint8_t count)
    {
        uint16_t total_count;
        uint16_t CRC_Calc = 0x00;
    
    
        //Total count is header (2 bytes) + length (1 byte) + DC ID (1 Byte) + CMD (1 byte) + payload (count) + checksum (2 bytes)
        total_count = 7 + count;
    
        if (total_count > MAX_BUFFER_SIZE)
        {
            return ERROR_MODE;
        }
    
        // If size is OK, fill buffer
        TransmitBuffer[0] = 0x55;   // header
        TransmitBuffer[1] = 0xAA;   // header
        TransmitBuffer[2] = count+4;   // packet length (ID, CMD, payload, checksum)
        TransmitBuffer[3] = 0x04;    // Design Center ID
        TransmitBuffer[4] = cmd;    // command
    
        CRC_Calc = TransmitBuffer[3] + TransmitBuffer[4];
    
        //Copy register data to TransmitBuffer
        CopyArray_wCRC(payload, &TransmitBuffer[5], count, &CRC_Calc);
    
        putsHexPC(TransmitBuffer,total_count);
        TXByteCtr = total_count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB0I2CSA = dev_addr;
        UCB0IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB0IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB0IE |= UCTXIE;                        // Enable TX interrupt
    
        __disable_interrupt();
        /* Initialize state machine */
        MasterMode = TX_DATA_MODE;
        UCB0CTL1 |=  UCTR | UCTXSTT;             // I2C RX, start condition
        while(MasterMode == TX_DATA_MODE)
        {
            __bis_SR_register(LPM0_bits + GIE);              // Enter LPM0 w/ interrupts
            __disable_interrupt();
        }
    
        return MasterMode;
    }
    void CopyArray_wCRC(uint8_t *source, uint8_t *dest, uint8_t count, uint16_t *CRC)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
            *CRC += source[copyIndex];
        }
    
        dest[copyIndex++] = (*CRC & 0xFF);   // Store LSB CRC
        dest[copyIndex] = (*CRC >> 8);   // Store MSB CRC
    }
    
    //******************************************************************************
    // Device Initialization *******************************************************
    //******************************************************************************
    
    void initClockTo16MHz()
    {
        UCSCTL3 |= SELREF_2;                      // Set DCO FLL reference = REFO
        UCSCTL4 |= SELA_2;                        // Set ACLK = REFO
        __bis_SR_register(SCG0);                  // Disable the FLL control loop
        UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
        UCSCTL1 = DCORSEL_5;                      // Select DCO range 16MHz operation
        UCSCTL2 = FLLD_0 + 487;                   // Set DCO Multiplier for 16MHz
                                                  // (N + 1) * FLLRef = Fdco
                                                  // (487 + 1) * 32768 = 16MHz
                                                  // Set FLL Div = fDCOCLK
        __bic_SR_register(SCG0);                  // Enable the FLL control loop
    
        // Worst-case settling time for the DCO when the DCO range bits have been
        // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
        // UG for optimization.
        // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
        __delay_cycles(500000);//
        // Loop until XT1,XT2 & DCO fault flag is cleared
        do
        {
            UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
            SFRIFG1 &= ~OFIFG;                          // Clear fault flags
        }while (SFRIFG1&OFIFG);                         // Test oscillator fault flag
    }
    
    uint16_t setVCoreUp(uint8_t level){
        uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
    
        //The code flow for increasing the Vcore has been altered to work around
        //the erratum FLASH37.
        //Please refer to the Errata sheet to know if a specific device is affected
        //DO NOT ALTER THIS FUNCTION
    
        //Open PMM registers for write access
        PMMCTL0_H = 0xA5;
    
        //Disable dedicated Interrupts
        //Backup all registers
        PMMRIE_backup = PMMRIE;
        PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE |
                    SVSLPE | SVMHVLRIE | SVMHIE |
                    SVSMHDLYIE | SVMLVLRIE | SVMLIE |
                    SVSMLDLYIE
                    );
        SVSMHCTL_backup = SVSMHCTL;
        SVSMLCTL_backup = SVSMLCTL;
    
        //Clear flags
        PMMIFG = 0;
    
        //Set SVM highside to new level and check if a VCore increase is possible
        SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
    
        //Wait until SVM highside is settled
        while((PMMIFG & SVSMHDLYIFG) == 0)
        {
            ;
        }
    
        //Clear flag
        PMMIFG &= ~SVSMHDLYIFG;
    
        //Check if a VCore increase is possible
        if((PMMIFG & SVMHIFG) == SVMHIFG)
        {
            //-> Vcc is too low for a Vcore increase
            //recover the previous settings
            PMMIFG &= ~SVSMHDLYIFG;
            SVSMHCTL = SVSMHCTL_backup;
    
            //Wait until SVM highside is settled
            while((PMMIFG & SVSMHDLYIFG) == 0)
            {
                ;
            }
    
            //Clear all Flags
            PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
                         SVMLVLRIFG | SVMLIFG |
                         SVSMLDLYIFG
                         );
    
            //Restore PMM interrupt enable register
            PMMRIE = PMMRIE_backup;
            //Lock PMM registers for write access
            PMMCTL0_H = 0x00;
            //return: voltage not set
            return false;
        }
    
        //Set also SVS highside to new level
        //Vcc is high enough for a Vcore increase
        SVSMHCTL |= (SVSHRVL0 * level);
    
        //Wait until SVM highside is settled
        while((PMMIFG & SVSMHDLYIFG) == 0)
        {
            ;
        }
    
        //Clear flag
        PMMIFG &= ~SVSMHDLYIFG;
    
        //Set VCore to new level
        PMMCTL0_L = PMMCOREV0 * level;
    
        //Set SVM, SVS low side to new level
        SVSMLCTL = SVMLE | (SVSMLRRL0 * level) |
                   SVSLE | (SVSLRVL0 * level);
    
        //Wait until SVM, SVS low side is settled
        while((PMMIFG & SVSMLDLYIFG) == 0)
        {
            ;
        }
    
        //Clear flag
        PMMIFG &= ~SVSMLDLYIFG;
        //SVS, SVM core and high side are now set to protect for the new core level
    
        //Restore Low side settings
        //Clear all other bits _except_ level settings
        SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 +
                     SVSMLRRL1 + SVSMLRRL2
                     );
    
        //Clear level settings in the backup register,keep all other bits
        SVSMLCTL_backup &=
            ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
    
        //Restore low-side SVS monitor settings
        SVSMLCTL |= SVSMLCTL_backup;
    
        //Restore High side settings
        //Clear all other bits except level settings
        SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 +
                     SVSMHRRL0 + SVSMHRRL1 +
                     SVSMHRRL2
                     );
    
        //Clear level settings in the backup register,keep all other bits
        SVSMHCTL_backup &=
            ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
    
        //Restore backup
        SVSMHCTL |= SVSMHCTL_backup;
    
        //Wait until high side, low side settled
        while(((PMMIFG & SVSMLDLYIFG) == 0) &&
              ((PMMIFG & SVSMHDLYIFG) == 0))
        {
            ;
        }
    
        //Clear all Flags
        PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
                    SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG
                    );
    
        //Restore PMM interrupt enable register
        PMMRIE = PMMRIE_backup;
    
        //Lock PMM registers for write access
        PMMCTL0_H = 0x00;
    
        return true;
    }
    
    bool increaseVCoreToLevel2()
    {
        uint8_t level = 2;
        uint8_t actlevel;
        bool status = true;
    
        //Set Mask for Max. level
        level &= PMMCOREV_3;
    
        //Get actual VCore
        actlevel = PMMCTL0 & PMMCOREV_3;
    
        //step by step increase or decrease
        while((level != actlevel) && (status == true))
        {
            if(level > actlevel)
            {
                status = setVCoreUp(++actlevel);
            }
            else
            {
                status = false;
            }
        }
    
        return (status);
    }
    
    void initGPIO()
    {
        //LEDs
        P1OUT = 0x00;                             // P1 setup for LED & reset output
        P1DIR |= BIT0;
    
        P4DIR |= BIT7;
        P4OUT &= ~(BIT7);
    
        //I2C Pins
        P3SEL |= BIT0 + BIT1 + BIT3 + BIT4;                     // P3.0,1 option select
        // P3.4,5 = USCI_A0 TXD/RXD
    
    }
    
    void initGPIO_UART()
    {
    //    P3SEL = BIT3 + BIT4;                        // P3.4,5 = USCI_A0 TXD/RXD
    //    P5SEL |= BIT4+BIT5;                         // Select XT1
    }
    
    void initI2C()
    {
        UCB0CTL1 |= UCSWRST;                      // Enable SW reset
        UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
        UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
        UCB0BR0 = 160;                            // fSCL = SMCLK/160 = ~100kHz
        UCB0BR1 = 0;
        UCB0I2CSA = SLAVE_ADDR;                   // Slave Address is 048h
        UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
        UCB0IE |= UCNACKIE;
    }
    
    //******************************************************************************
    // Main ************************************************************************
    // Send and receive three messages containing the example commands *************
    //******************************************************************************
    
    int main(void) {
        uint8_t i,cnt;
        WDTCTL = WDTPW | WDTHOLD;                 // Stop watchdog timer
    
        increaseVCoreToLevel2();
        initClockTo16MHz();
        initGPIO();initGPIO_UART();
        initI2C();
        initUART();
    
        putsUART("Hello ");
        putsUART("\nConfig: ");
    //    __bis_SR_register(LPM0_bits + GIE);       // Since SMCLK is source, enter LPM0, interrupts enabled
    //    I2C_Master_WriteCmdBlocking(SLAVE_ADDR, CMD_01_MASTER, MasterCMD01Payload, CMD_01_LENGTH);
        I2C_Master_Write_Config(SLAVE_ADDR);
    
        while (1)
        {
            cnt++;
            if(cnt>4)cnt=0;
            putsUART("\nCmd  Read: ");
            I2C_Master_Write_cmd(SLAVE_ADDR,0x80+cnt);
            __delay_cycles(1000000);
            I2C_Master_ReadDataBlocking(SLAVE_ADDR, RESPONSE_SLAVE_LENGTH);
            putsUART("\nData Read: ");
            for(i=0;i<15;i++)   {
                putHexUART(ReceiveBuffer[i]);
                putcUART(' ');
            }
            // Check response in Receive buffer
        }
    }
    
    //******************************************************************************
    // I2C Interrupt ***************************************************************
    //******************************************************************************
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_B0_VECTOR
    __interrupt void USCI_B0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      //Must read from UCB0RXBUF
      uint8_t rx_val = 0;
    
      switch(__even_in_range(UCB0IV,0xC))
      {
        case USCI_NONE:break;                             // Vector 0 - no interrupt
        case USCI_I2C_UCALIFG:break;                      // Interrupt Vector: I2C Mode: UCALIFG
        case USCI_I2C_UCNACKIFG:break;                    // Interrupt Vector: I2C Mode: UCNACKIFG
        case USCI_I2C_UCSTTIFG:break;                     // Interrupt Vector: I2C Mode: UCSTTIFG
        case USCI_I2C_UCSTPIFG:break;                     // Interrupt Vector: I2C Mode: UCSTPIFG
        case USCI_I2C_UCRXIFG:
            rx_val = UCB0RXBUF;
            if (RXByteCtr)
            {
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;
            }
    
            if (RXByteCtr == 1)
            {
              UCB0CTL1 |= UCTXSTP;
            }
            else if (RXByteCtr == 0)
            {
              UCB0IE &= ~UCRXIE;
              MasterMode = IDLE_MODE;
              update=1;
              __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
            }
            break;                      // Interrupt Vector: I2C Mode: UCRXIFG
        case USCI_I2C_UCTXIFG:
              if (TXByteCtr)
              {
                  UCB0TXBUF = TransmitBuffer[TransmitIndex++];
                  TXByteCtr--;
              }
              else
              {
                  //Done with transmission
                  UCB0CTL1 |= UCTXSTP;     // Send stop condition
                  MasterMode = IDLE_MODE;
                  UCB0IE &= ~UCTXIE;                       // disable TX interrupt
                  __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
              }
            break;                      // Interrupt Vector: I2C Mode: UCTXIFG
        default: break;
      }
    }
    
    //******************************************************************************
    // UART RX Interrupt ***********************************************************
    //******************************************************************************
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      switch(__even_in_range(UCA0IV,4))
      {
      case 0:break;                             // Vector 0 - no interrupt
      case 2:                                   // Vector 2 - RXIFG
        while (!(UCA0IFG & UCTXIFG));             // USCI_A0 TX buffer ready?
        UCA0TXBUF = UCA0RXBUF;                  // TX -> RXed character
        break;
      case 4:break;                             // Vector 4 - TXIFG
      default: break;
      }
    }
    

    数据读取结果。

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

    您是否已连接到交流电压? 否则、结果可能为零。 此外、检查'emDCCommandHandlers.c'中的函数。 对于 VRMS、它应该与此类似。 您的数据读取数据包似乎比必要的时间长。

    void CommandHandler_transmitVRMS (Packet_t *数据包,
    uint8_t 相位 ID、
    uint8_t * Vrms)
    {
    packet->length = 8;
    packet->payload[0]= COMMAND_ERTER_EM_GUI_ID_byte;
    packet->payload[1]= COMMAND_ERTER_VRMS_ID;
    packet->PAYLOAD[2]= COMMAND_ERTER_WRITE_CMD;
    packet->payload[3]= phaseID;
    packet->payload[4]= Vrm[0];
    packet->payload[5]= Vrm[1];
    packet->payload[6]= Vrm[2];
    packet->payload[7]= Vrm[3];
    
    Com_writePacket (packet);
    } 
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我需要读取 VRMS 结果、我已发送到 VRMS 的器件命令、但结果我不读取 VRMS。 IN 命令读取为0x89。 您可以查看我发送到器件更改的命令值0x80 - 0x84、但读取结果反向具有命令0x89。

    我遇到的问题是代码或连接。 我已连接 F5529LP 4线(3.3V SDA、SCL、GND)。 您能帮我在我编写的2021年5月20日的文章中检查我的代码吗?

    在向从器件写入命令后的多长时间内 、我可以读取数据结果。 在项目中、EVM 需要使用申请 PIN? 您是否有代码示例通过 I2C 从 i204x 读取数据结果? 您能否通过回复向我发送邮件或发送电子邮件 至 dungnv@lctech.vn

    非常感谢。

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

    我建议深入了解代码并了解返回命令为何错误。 也许 F5529发出的命令不正确。