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.

[参考译文] MSP430FR5994:具有 MSP430FR5994的 I2C EEPROM

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1199746/msp430fr5994-i2c-eeprom-with-msp430fr5994

器件型号:MSP430FR5994
主题中讨论的其他器件: MSP430F5529

你好。

我正在使用 MSP430FR5994和 I2C EEPROM。 我在迁移部分工作的 I2Croutines.c 时遇到一些困难。

写入 EEPROM 后、电池消耗过多、读取 EEPROM 时不会发生这种情况。

使用另一个 MSP430F5529、写入和读取工作正常、而不会改变电池消耗。

是否有人可以指导我、或者他们是否知道 MSP430FR5994寄存器以更正所附的代码?

我感谢每个人的冷气!

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
MSP430FR5994 I2C Pin Configuration
////////////////////////////////////////////////////////////////////////////////
// Definição da Porta P5 como Serial I2C das Memórias EEPROMS //
////////////////////////////////////////////////////////////////////////////////
P5OUT = 0; // Reseta Todos os Pinos da Porta P5
P5DIR = 0xFF; // Define Todos os Pinos da Porta P5 como Saídas
P5OUT &=~ 0xFF; // Inicializa Todos os Pinos da Porta P5 com Nível Lógico "0" Baixo
P5SEL0 |= BIT0 | BIT1; // Seleciona o Pino da Porta P5.0 UCB1SDA e P5.1 UCB1SCL como Barramento I2C
P5SEL1 &= ~(BIT0 | BIT1); // Seleciona Módulo Primário Conforme Tabela I/O Function Selection
// Configuração do Barramento I2C das Memórias EEPROMs
UCB1CTLW0 = UCSWRST; // Enable SW reset
UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK; // I2C Master, synchronous mode
UCB1BRW = 160; // fSCL = SMCLK/160 = 100 kHz
UCB1CTLW1 |= 0x40; // Use SMCLK, TX mode, keep SW reset
UCB1CTLW1 |= UCASTP_2;
UCB1CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation
//UCB1IE |= UCNACKIE + UCALIE + UCSTPIE + UCSTTIE + UCTXIE0 + UCRXIE0 | UCBCNTIE | USCI_I2C_UCCLTOIFG; // Interrupts Enable
UCB1IE |= UCNACKIE + UCTXIE0 + UCRXIE0; // Interrupts Enable
I2Croutines.h
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Anderson Portela。

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

    > if (!(UCNACKIFG & UCB1STAT))//如果收到 ACK 则中断

    这看起来有点奇怪、因为 UCNACKIFG 位于 UCB1IFG 中。 UCB1STAT (USCI 和 EUSCI)中的位5是 UCGC、(我想)一直为0。 (对于应答轮询、该测试看起来也是向后的。)

    由于延迟为5ms (EEPROM 的标准 Twrite)、这可能会意外发生。

    此代码是否与您用于 F5529 (USCI)的代码相同?

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

    你好 Bruce。

    是的、此代码与我在 F5529中使用的代码相同。

    奇怪的是、它的写入和读取正常、但在 FR5994中、写入后会产生大约600uA 的电池过多电流消耗。 如果我不写入、我消耗大约10uA。

    在 F5529中、写入和读取大约14uA 后的功耗。

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

    高电流条件是否在第一次写入后一直持续、还是暂时的?  

    > UCB1CTLW1 |= UCASTP_2;

    您正在设置 UCASTP=2、但 TBCNT 始终为0。 我从未尝试过这种组合、可能会有一些与之相关的异常(UG 模糊)。 由于您不使用此功能、我建议您不要申请它。 (这与 F5529不同。)

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

    我想我在这里找到了您代码的早期版本:

    /cfs-file/__key/communityserver-discussions-components-files/166/I2Croutines.c
    从注释中可以看到、这适用于 F2系列器件、其中 UCNACKIFG 位于 UCBxSTAT [参考 F2用户指南(SLAU144K)表17-7]。 F5 NOR FR5系列则不是这样。
    该测试看起来仍然不正确、因为它假定 NACK 在开始后立即出现、此时它不能早于(1+8+1) I2C 时钟(100kHz 时为100us)。
    [编辑:这似乎是原始版本:
    该代码通过 PDF 中的链接提供。]
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好 Bruce。

    回答您之前的问题:

    写入后功耗仍然过大、仅在 F5994复位后才会恢复正常。

    是的、我将此代码用于 F5529、效果很好。

    我对 F5994进行了一些修改、在写入内存后发现问题。

    P.S. 我可能不知道如何配置正确的 F5994寄存器。 这可能是个问题!

    有趣的是、在调试时、我没有发现任何代码崩溃、尤其是在 NACK 部分。

    以下是一些修改、我注意到改进、不确定配置是否正确:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    ////////////////////////////////////////////////////////////////////////////////
    // Definição da Porta P5 como Serial I2C das Memórias EEPROMS //
    ////////////////////////////////////////////////////////////////////////////////
    P5OUT = 0; // Reseta Todos os Pinos da Porta P5
    P5DIR = 0xFF; // Define Todos os Pinos da Porta P5 como Saídas
    P5OUT &=~ 0xFF; // Inicializa Todos os Pinos da Porta P5 com Nível Lógico "0" Baixo
    P5SEL0 |= BIT0 | BIT1; // Seleciona o Pino da Porta P5.0 UCB1SDA e P5.1 UCB1SCL como Barramento I2C
    P5SEL1 &= ~(BIT0 | BIT1); // Seleciona Módulo Primário Conforme Tabela I/O Function Selection
    // Configuração do Barramento I2C das Memórias EEPROMs
    UCB1CTLW0 = UCSWRST; // Enable SW reset
    UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK; // I2C Master, synchronous mode
    UCB1BRW = 160; // fSCL = SMCLK/160 = 100 kHz
    //UCB1CTLW1 |= 0x40; // Use SMCLK, TX mode, keep SW reset
    //UCB1CTLW1 |= UCASTP_2;
    UCB1CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation
    //UCB1IE |= UCNACKIE + UCALIE + UCSTPIE + UCSTTIE + UCTXIE0 + UCRXIE0 | UCBCNTIE | USCI_I2C_UCCLTOIFG; // Interrupts Enable
    UCB1IE |= UCNACKIE + UCTXIE0 + UCRXIE0; // Interrupts Enable
    #include "I2Croutines.h"
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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

    我看到您关闭了 UCASTP 和 UCCLTO。 您看到了多少改进?

    1) 1) EUSCI 和 USCI 的工作原理大致相同、但它们是不同的实现方式、因此如果"插入"未记录的条件、它们的行为可能会有所不同。 因为(除了我提到的内容)我没有看到任何与你所做的事情完全不符的地方,这是我正在寻找的事情。

    2)我一直回到反向轮询函数、因为(a)它仅在写入之后使用、而不是在读取之后使用(b)它不执行它声称的操作(c)它可能会因意外工作而发生、因为它始终会延迟5ms [TWR]。 下面是一个实验:用一个裸"delay_ms (5)"替换对该函数的每次调用。

    此外,delay_ms()是如何工作的? 是否有可能留下不应该运行的东西? (在最初的版本中、它是一个自包含的__delay_cycles (500)。)

    3) 3) 3)您能否为 EEPROM 器件提供器件型号? 我找到了(MCHP) 24LC65 [DS21073K]的数据表、[表1-2注(4)]指出、每8个字节的 TWR 为5ms、因此对于32个字节、它将为4*5=20ms。 您的器件可能不是这样。 (我曾使用过类似的器件、但我在这里没有任何器件。)

    4) 4)另一件事对我来说是:在许多地方、会检查 UCBUSY、而 UCBUSY 实际上不 是在 I2C 模式中定义的。 相反、I2C 模式定义了一个单独的 UCBBUSY。 F2系列也是如此、高建先生显然取得了成功、但 UCBUSY 似乎可以做(未记录的)事情、但对 EUSCI 与 USCI 的行为不同。  

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

    Bruce、

    来自 EEPROM 24LC1025和 delay_ms()函数代码的信息如下;

    您能否按照您了解的方式编写 I2Croutines.c 代码、以便我在此使用 F5994进行测试?

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    delay.h
    // Example for 16MHz
    #define F_CPU 16000000UL
    #define F_CPU_NS (F_CPU/1000000000.0)
    #define F_CPU_US (F_CPU/1000000.0)
    #define F_CPU_MS (F_CPU/1000.0)
    #define F_CPU_S (F_CPU/1.0)
    // Delay Macros (more accurate -- static delay required)
    /*
    #define delay_ns(__ns) \
    if((uint32_t) (F_CPU_NS * __ns) != F_CPU_NS * __ns)\
    __delay_cycles((uint32_t) ( F_CPU_NS * __ns)+1);\
    else __delay_cycles((uint32_t) ( F_CPU_NS * __ns))
    */
    #define delay_us(__us) \
    if((uint32_t) (F_CPU_US * __us) != F_CPU_US * __us)\
    __delay_cycles((uint32_t) ( F_CPU_US * __us)+1);\
    else __delay_cycles((uint32_t) ( F_CPU_US * __us))
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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

    24LC1025数据表(DS20001941L)表1-2显示了 TWC = 5ms (最大值)、因此上述(3)不是问题。

    delay_ms 定义看起来不错。

    从删除 UCASTP 和 UCCLTO 中可以看出有多大的改进?

    如果没有测试用例、我将编码为"盲"、但我将从以下内容开始:

    1) 1)将所有出现的 UCBUSY 替换为 UCBBUSY

    2)使用 delay_ms (5)替换对 EEPROM_AckPolling 的调用(我只看到一个)。 如果这显示(积极)效果、那么我会考虑是否/如何重新实施。

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

    祝贺布鲁斯!!!!

    从删除 UCASTP 和 UCCLTO 中可以看出有多大的改进?

    回答:
    电池电流消耗在8.9uA 时变得更加稳定。 在20uA 和10uA 之间振荡之前。

    1) 1)将所有出现的 UCBUSY 替换为 UCBBUSY

    回答:
    通过使用 UCBBUSY、消耗仅增加一倍、达到1.650uA。 我返回使用 UCBUSY、消耗为8.9uA。

    2)使用 delay_ms (5)替换对 EEPROM_AckPolling 的调用(我只看到一个)。 如果这显示(积极)效果、那么我会考虑是否/如何重新实施。

    回答:
    该问题的解决方案是使用简单的 DELAY_ms (5)替换 EEPROM_AckPolling 函数。 解决了写入内存后电流消耗过大的问题。

    我承认、我在理解使用 EEPROM_AckPolling 函数时出现的问题时遇到了一些困难。 但是、无论出于什么目的、它都能发挥出色的作用!

    非常感谢 Bruce 的关注、尤其是他的解决方案!

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

    我很高兴你成功。 我也不知道 ACK 轮询功能到底有什么问题;也许有一天如果我有测试用例、我可以进行实验。

    至于 UCBBUSY:我的第一个想法是、检查会消耗更多的电流(我假设您的意思是16.5uA 而不是1.65uA)、因为它实际上是在测试某个东西、即有时 I2C 在此时确实很忙、UCBUSY 测试不会检测到它。 我不会争辩说成功、也许测试并不重要、但如果将来出现异常行为、可能需要将其放入您的实验室笔记本中。