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.

[参考译文] CCS/TM4C123GH6PM:可变数据存储在 EEPROM 存储器中

Guru**** 2601915 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/740112/ccs-tm4c123gh6pm-variable-data-storing-in-eeprom-memory

器件型号:TM4C123GH6PM

工具/软件:Code Composer Studio

大家好、我目前正在研究 TM4C123GXL Launchpad 的 EEPROM 模块、我在了解 EEPROM 时遇到了一些问题。

问题是如何声明变量、并且变量将在程序中反复更新。 如果断电并重新连接、并且我正在打印该变量内容、则意味着它应该打印更新的值、而不是第一 个初始化的值。

因此、请帮助解决此问题。

谢谢你。

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

    您好!

     下面的示例代码显示了如何对 EEPROM 进行编程、这也可以在 TivaWare 外设驱动程序库用户指南的第9.3节中找到。 如果要打印更新后的值,则需要首先使用 EEpromProgram()对数据进行编程,以将数据存储在 EEPROM 中,然后使用 EEpromRad()将其读出。

    uint32_t ui32EEPROMInit;
    uint32_t pui32Data[2];
    uint32_t pui32Rad[2];
    //
    启用 EEPROM 模块。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_EEPROM0);
    //
    等待 EEPROM 模块准备就绪。
    //
    while (!SysCtlPeripheralReady (SYSCTL_Periph_EEPROM0))
    }{
    //
    
    //等待 EEPROM 初始化完成
    //
    ui32EEPROMInit = EEPROMInit();
    //
    //检查 EEPROM 初始化是否返回错误
    //并通知应用
    //
    if (ui32EEPROMInit!= EEPROM_INIT_OK)
    {
    while (1)
    {
    }
    //
    
    //将一些数据编程到地址0x400的 EEPROM 中。
    //
    pui32Data[0]= 0x12345678;
    pui32Data[1]= 0x56789abc;
    EEPROMProgram (pui32Data、0x400、sizeof (pui32Data));
    //
    //读回它。
    //
    EEPROMRead (pui32Read、0x400、sizeof (pui32Read)); 

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

    感谢您 Charles、您发布的节目我已经执行了、该代码没有问题。 是  

    int b=10、a;

    void main()

    SysCtlClockSet (SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHz);
    SysCtlPeripheralEnable (SYSCTL_Periph_EEPROM0);
    SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);

    GPIOPinTypeGPIOInput (GPIO_PORTF_BASE、GPIO_PIN_4);
    GPIOPadConfigSet (GPIO_PORTF_BASE、GPIO_PIN_4、GPIO_Strength _4mA、GPIO_PIN_TYPE_STD_WPU);
    GPIOPinConfigure (GPIO_PA0_U0RX);// PA0配置为 UART RX
    GPIOPinConfigure (GPIO_PA1_U0TX);// PA1配置为 UART TX
    GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

    EEPROMInit();
    EEPROMMassEras();
    EEPROMProgram (b、0x0、sizeof (b));

    while (1)



    IF (!GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_4))



    EEPROMRead (A、0x0、sizeof (A));
    A=A-2;
    UARTprintf ("\n 剩余余额为%i\n",a);
    EEPROMProgram (A、0x0、sizeof (A));
    SysCtlDelay (20000);


    在上面的代码中、如果我在值递减2后按下开关、并且下次按下相同的按钮时在 UART 终端上打印、那么就不会出现问题。 但让我们考虑一下、我已经按了开关两次、并且值变为6、如果我断开电源并将其重新连接、那么现在将其打印在终端上、如果我再按开关一次、则意味着我应该在终端上得到4、因为我正在进行编程 EEPROM、但我得到的是8、而不是4。 为什么会发生这种情况。 有什么方法可以获得我所期望的输出。

    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当您调用 EEPROMProgram (A、0x0、sizeof (a))时、您如何知道第二个程序命令成功。 当成功时 EEPROMProgram()将返回0或失败时返回非0值。 您应该在对 EEPROMProgram 的任何调用以及具有返回值的任何 API 调用上检查返回值。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这里不是 API,我刚才给出的上述程序有一个未经测试的代码示例。 我的疑问是、如果断电并返回、我们如何在 EEPROM 中编程时恢复更新的数据。  

    在上面的示例中、我们可以看到、当电源掉电并返回时、'b'的值将更新为初始值10、因为闪存将从开始执行。 因此、我们对 EEPROM 进行编程的情况也是如此、因此我们将得到的结果首先仅是递减值、即8、我不会得到功率下降前的值(减2)。

    因此、除了 Tivaware 示例外、请发布一个解释 EEPROM 的示例。

    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    断电后再上电时、您将再次重新运行相同的代码。 您将首先执行 EEPROMProgram (b、0x0、sizeof (b))、如果在电源关闭之前按了两次开关、则会覆盖先前存储在 EEPROM 中的内容(即6)。 您需要在代码中添加一些智能。 例如、您可以检查 RESC 寄存器以查看是否由于 POR 而复位。 根据这些信息、您可以选择直接读取 EEPROM 内容、而无需首先向其中写入10。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Charles、

    当你检查读取的状态时、我使用了一个 API SysCtlResetCauseGet ()并且我正在通过将它存储在一个32位整数变量中来打印该 API 的返回值。 首次上传代码后、状态为"19"。 如果我断开电源并将其重新连接、我将获得状态为"3"。 因此 、在程序中、我将使用条件  

    V=SysCtlResetCauseGet ();
    UARTprintf ("由于%i"、v 重置);
    如果(v==19)

    EEPROMProgram (AMOUNT、0x0、sizeof (AMOUNT));

    首次上传代码后、'if'块正在执行。 如果我断开电源并将其重新连接、则意味着'if'未执行、因此 EEPROM 再次不会初始化为基值 i.e、10。

    但 EEPROM 在电源关闭之前不会保留该值。 它正在使用值0进行初始化。

    这背后的原因是什么? 如何保留 EEPROM 内容? 是否有任何 API 或任何设置可保留 EEPROM?

    谢谢你。

      

     

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您有哪个版本的器件? 不确定您是否遇到了勘误表之一。 有关 EEPROM 的一些问题、请查看勘误文档。

    当您首次使用 v=19对"Amount (金额)"进行编程时、您能否先读回它以查看它是否已成功编程?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是当 v=19时,EEPROMProgram()将数据加载到 EEPROM 存储器中意味着它 工作正常。  EEPROM API 中存在问题、所有问题都正常工作、我检查了所有这些问题。

    但是、如果我切断电源、EEEPROM 存储器中的数据将擦除。 正如我们所知、EEPROM 是一种非易失性存储器、它应该保留数据、但此处并未发生这样的情况。 如果 launchpad 第二次上电、则意味着 EEPROM 存储器中只能看到0。

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

    #include
    #include
    #include "inc/hw_memmap.h"
    #include" driverlib/gpio.h"
    #include" driverlib/pin_map.h"
    #include" driverlib/sysctl.h"
    #include" driverlib/uart.h"
    #include "inc/tm4c123gh6m.h"
    #include "utils/uartstdio.h"
    #include "driverlib/debug.h"
    #include "driverlib/EEPROM.h"

    #define GPIO_PA0_U0RX 0x00000001 // UART RX 的 UART 引脚地址
    #define GPIO_PA1_U0TX 0x00000401 // UART TX 的 UART 引脚地址
    #define GPIO_PB0_U1RX 0x00010001

    unsigned char a[]="00002A5AB9C9";

    int i=0;
    uint32_t *数量、* bal;
    uint32_t am=25,b;

    int main()

    uint32_t v;
    SysCtlClockSet (SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHz);
    //启用外设 UART 0
    SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
    SysCtlPeripheralEnable (SYSCTL_Periph_UART1);

    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
    SysCtlPeripheralEnable (SYSCTL_Periph_EEPROM0);

    GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_1_GPIO_PIN_2|GPIO_PIN_3);

    GPIOPinConfigure (GPIO_PA0_U0RX);// PA0配置为 UART RX
    GPIOPinConfigure (GPIO_PA1_U0TX);// PA1配置为 UART TX
    GPIOPinConfigure (GPIO_PB0_U1RX);// PB0配置为 UART RX

    GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);
    GPIOPinTypeUART (GPIO_PORTB_BASE、GPIO_PIN_0);
    金额= AM (&A);
    Bal=&b;
    EEPROMInit();
    EEPROMMassEras();

    GPIOPinTypeGPIOInput (GPIO_PORTF_BASE、GPIO_PIN_4);
    GPIOPadConfigSet (GPIO_PORTF_BASE、GPIO_PIN_4、GPIO_Strength _4mA、GPIO_PIN_TYPE_STD_WPU);

    UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC);
    UARTStdioConfig (0、9600、16000000);
    UARTConfigSetExpClk (UART1_base、SysCtlClockGet ()、9600、(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
    UARTprintf ("欢迎使用 RFID 演示\n");

    IntEnable (INT_UART1);
    UARTIntEnable (UART1_BASE、UART_INT_RX|UART_INT_RT);
    IntMasterEnable();

    V=SysCtlResetCauseGet ();
    UARTprintf ("由于%i"、v 重置);
    如果(v==19)

    EEPROMProgram (AMOUNT、0x0、sizeof (AMOUNT));
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_3,0X08);
    SysCtlDelay (1333333);
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_3,0X00);

    while (1);

    空 uartint()

    unsigned char comp[12];
    unsigned int m=0、n=0;
    UARTIntClear (UART1_BASE、UART_INT_RX);
    COMP[I]= UARTCharGet (UART1_BASE);
    UARTCharPut (UART0_BASE、COMP[i]);
    i++;

    if (i==12)

    for (i=0;i<12;i++)

    if (a[i]=comp[i])
    M++;
    其他
    M=0;

    if (m>10)

    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1,0X02);
    SysCtlDelay (20000);
    //bal=&b;
    EEPROMRead (bal、0x0、sizeof (bal));
    *bal=*bal-2;
    //b=b-2;
    UARTprintf ("\n 剩余余额为%i\n"、*bal);
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1,0X00);
    EEPROMProgram (bal、0x0、sizeof (bal));


    其他

    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1,0X00);
    SysCtlDelay (20000);
    UARTprintf ("\n 集成卡\n");

    I=0;

    这是我正在使用 RFID 读取器和卡的代码。 上传代码后、如果我扫描卡一次、则表示将被扣减2、如果我再次扫描、则再次扣减2、依此类推。 更新后的值将存储在 EEPROM 中。如果我断开电源并将其连接回、扫描卡意味着它应该打印"更新后的值- 2"、但它打印 的是"-3"。 代码中的问题是什么?

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

    我编写了这个小程序、可能会有所帮助。 该程序需要使用另一个 EEPROM 位置作为标志、以确定何时将数据初始化为10或何时从断电后它离开的位置恢复递减。 您必须写入另一个只需先将标志初始化为0的程序。 该标志使用 EEPROM 的第一个位置。 每次按下 SW1时、该值将递减的应用数据存储在0x400。 首次运行该程序后、根据 SW2按下后的标志值、它将以值10重新启动以进行编程或从其关闭的位置恢复。 要对其进行测试、您将执行以下操作:

    1.创建另一个程序、首先将第一个 EEPROM 位置(标志)编程为零。

    2.运行以下程序。

    3.按下 SW2开关,它将应用程序值初始化为10

    4.按 SW1,每次按时它都会递减1。

    5.您可以尝试在应用程序值达到0之前拔下电源线。 例如、当应用程序值为8时、您可以拔下电源线。

    6.重新连接电源

    7.再次按 SW1。 您应该会看到要编程的应用程序值将从7开始、然后向下。

    int
    main (void)
    {
    uint32_t ui32EEPROMInit;
    uint32_t flag=0x12345678;
    uint32_t pui32Data;
    uint32_t pui32Read;
    //
    //启用 EEPROM 模块。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_EEPROM0);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
    GPIOPinTypeGPIOInput (GPIO_PORTF_BASE、GPIO_PIN_4);
    GPIOPadConfigSet (GPIO_PORTF_BASE、GPIO_PIN_4、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU);
    
    HWREG (GPIO_PORTF_BASE_GPIO_O_LOCK)= GPIO_LOCK_KEY;
    HWREG (GPIO_PORTF_BASE_GPIO_O_CR)|= GPIO_PIN_0;
    GPIOPinTypeGPIOInput (GPIO_PORTF_BASE、GPIO_PIN_0);
    GPIOPadConfigSet (GPIO_PORTF_BASE、GPIO_PIN_0、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU);
    //
    //等待 EEPROM 模块准备就绪。
    //
    while (!SysCtlPeripheralReady (SYSCTL_Periph_EEPROM0))
    {
    }
    
    ConfigureUART();
    
    //!
    //
    UARTprintf ("EEPROM 测试!\n");
    
    //
    //等待 EEPROM 初始化完成
    //
    ui32EEPROMInit = EEPROMInit();
    //
    //检查 EEPROM 初始化是否返回错误
    //并通知应用程序
    //
    if (ui32EEPROMInit!= EEPROM_INIT_OK)
    {
    while (1)
    {
    }
    }
    
    EEPROMRead (&flag、0x0、4);
    
    while (1){
    if (GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_0)== 0x0){//如果 SW2被按下并且标志等于0、
    
    if (flag =0){//初始化标志并将 pui32Data 复位为10
    pui32Data = 10;
    标志= 0x12345678;
    EEPROMProgram (&flag、0x0、4);
    EEPROMRead (&flag、0x0、4);
    
    EEPROMProgram (&pui32Data、0x400、4);
    EEPROMRead (&pui32Read、0x400、4);
    UARTprintf ("\n 将数据初始化为10\n");
    
    
    } 否则、如果(FLAG = 0x12345678){//如果 FLAG 未清除、则可能表示功率损耗
    EEPROMRead (&pui32Read、0x400、4);
    pui32Data = pui32Read; //从它恢复 EEPROM 编程,它以前是关闭的
    UARTprintf ("\n 从其关闭的位置重新启动 EEPROM 程序\n");
    
    
    } 否则{
    while (1);
    }
    中断;
    
    }
    }
    SysCtlDelay (1000000);
    
    执行{
    
    while (GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_4));
    
    // if (flag = 0x12345678){
    UARTprintf ("\n 剩余余额为%i\n"、pui32Read);
    pui32数据--;
    EEPROMProgram (&pui32Data、0x400、4);
    EEPROMRead (&pui32Read、0x400、4);
    
    
    //}
    
    SysCtlDelay (1000000);
    
    
    } while (pui32Data > 0);
    
    if (flag = 0x12345678){
    标志= 0;
    EEPROMProgram (&flag、0x0、4);
    }
    
    while (1);
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢你查尔斯···········我得到了结果。