2016-03-22 22 views
-1

私はMCF51EM256 Freescaleマイクロコントローラを使用しています。データを永続化するためにEEPROMにデータを保存するにはいくつかの問題があります。データをEEPROM、MICROCONTROLLERに保存

typedef struct { 
    ui64_s Ea_ps; 
    ui64_s Ea_ng; 
    ui64_s Er_q1; 
    ui64_s Er_q2; 
    ui64_s Er_q3; 
    ui64_s Er_q4; 
    uint16 F_ea; 
    uint16 F_er; 
}Ws_EnergyAcc64; 

typedef union{  
    uint64 v; 
    uint32 p[2]; 
} ui64_s; 

と:私はEEPROMで、この構造体保存する必要があり

これを行うためには

typedef unsigned long long int uint64; 
typedef unsigned long int uint32; 
typedef unsigned short int uint16; 

は、私はこの機能を実装しました:

void Save_EEPROM_WsEnergyAcc(long addr, Ws_EnergyAcc64* Acc) { 

    // WsEnergyAcc struct needs 56 bytes in EEPROM 

    uint32 F_ea_32 = (uint32) Acc->F_ea; 
    uint32 F_er_32 = (uint32) Acc->F_er; 

    Flash_Burst(addr, 2, Acc->Ea_ps.p); 
    Flash_Burst(addr + 8, 2, Acc->Ea_ng.p); 
    Flash_Burst(addr + 16, 2, Acc->Er_q1.p); 
    Flash_Burst(addr + 24, 2, Acc->Er_q2.p); 
    Flash_Burst(addr + 32, 2, Acc->Er_q3.p); 
    Flash_Burst(addr + 40, 2, Acc->Er_q4.p); 

    Flash_Burst(addr + 48, 2, &F_ea_32); 
    Flash_Burst(addr + 52, 2, &F_er_32); 

} 

場所 "Flash_Burst":

#define Flash_Burst(Address, Size, DataPtr) \ 
     Flash_Cmd((UINT32)Address, (UINT16)Size, (UINT32*)DataPtr, FLASH_BURST_CMD) 

UINT8 /*far*/ 
Flash_Cmd(UINT32 FlashAddress, 
     UINT16 FlashDataCounter, 
     UINT32 *pFlashDataPtr, 
     UINT8 FlashCommand) 
{ 
    /* Check to see if FACCERR or PVIOL is set */ 
    if (FSTAT &0x30) 
    {   
     /* Clear Flags if set*/ 
     FSTAT = 0x30; 
    } 

    if (FlashDataCounter) 
    { 
    do 
    { 
     /* Wait for the Last Busrt Command to complete */ 
     while(!(FSTAT&FSTAT_FCBEF_MASK)){};/*wait until termination*/ 

     /* Write Data into Flash*/ 
     (*((volatile unsigned long *)(FlashAddress))) = *pFlashDataPtr; 
     FlashAddress += 4; 
     pFlashDataPtr++; 

     /* Write Command */ 
     FCMD = FlashCommand; 

     /* Put FCBEF at 1 */ 
     FSTAT = FSTAT_FCBEF_MASK; 

     asm (NOP); 
     asm (NOP); 
     asm (NOP); 

     /* Check if Flash Access Error or Protection Violation Error are Set */ 
     if (FSTAT&0x30) 
     {  
      /* If so, finish the function returning 1 to indicate error */ 
      return (1); 
     } 

    }while (--FlashDataCounter); 
    } 
    /* wait for the last command to complete */ 
    while ((FSTAT&FSTAT_FCCF_MASK)==0){};/*wait until termination*/ 

    /* Return zero to indicate that the function executed OK */ 
    return (0); 
} 

と:場合

void testEEPROM(Ws_EnergyAcc64* Acc){ 

     Ws_EnergyAcc64 checkStruct; 

     Acc->Ea_ps.p[0] = 0x10000000; 
     Acc->Ea_ps.p[1] = 0x10000000; 
     Acc->Ea_ng.p[0] = 0x10000000; 
     Acc->Ea_ng.p[1] = 0x10000000; 
     Acc->Er_q1.p[0] = 0x10000000; 
     Acc->Er_q1.p[1] = 0x10000000; 
     Acc->Er_q2.p[0] = 0x10000000; 
     Acc->Er_q2.p[1] = 0x10000000; 
     Acc->Er_q3.p[0] = 0x10000000; 
     Acc->Er_q3.p[1] = 0x10000000; 
     Acc->Er_q4.p[0] = 0x10000000; 
     Acc->Er_q4.p[1] = 0x10000000; 
     Acc->F_ea = 0x0000; 
     Acc->F_er = 0x0000; 

    Save_EEPROM_WsEnergyAcc(PhR_ABS_Ws_addr, Acc); 

    Acc->Ea_ps.p[0] = 0x10011001; 
    Acc->Ea_ps.p[1] = 0x10011002; 
    Acc->Ea_ng.p[0] = 0x10011003; 
    Acc->Ea_ng.p[1] = 0x10011004; 
    Acc->Er_q1.p[0] = 0x10011005; 
    Acc->Er_q1.p[1] = 0x10011006; 
    Acc->Er_q2.p[0] = 0x10011007; 
    Acc->Er_q2.p[1] = 0x10011008; 
    Acc->Er_q3.p[0] = 0x10011009; 
    Acc->Er_q3.p[1] = 0x1001100A; 
    Acc->Er_q4.p[0] = 0x1001100B; 
    Acc->Er_q4.p[1] = 0x1001100C; 
    Acc->F_ea = 0x0000; 
    Acc->F_er = 0x0000; 

    Save_EEPROM_WsEnergyAcc(PhR_ABS_Ws_addr, Acc);  
    Init_EEPROM_WsEnergyAcc(PhR_ABS_Ws_addr, &checkStruct); 

    printf("%d\n", checkStruct.Ea_ps.p[0]); 
    printf("%d\n", checkStruct.Ea_ps.p[1]); 
    printf("%d\n", checkStruct.Ea_ng.p[0]); 
    printf("%d\n", checkStruct.Ea_ng.p[1]); 
    printf("%d\n", checkStruct.Er_q1.p[0]); 
    printf("%d\n", checkStruct.Er_q1.p[1]); 
    printf("%d\n", checkStruct.Er_q2.p[0]); 
    printf("%d\n", checkStruct.Er_q2.p[1]); 
    printf("%d\n", checkStruct.Er_q3.p[0]); 
    printf("%d\n", checkStruct.Er_q3.p[1]); 
    printf("%d\n", checkStruct.Er_q4.p[0]); 
    printf("%d\n", checkStruct.Er_q4.p[1]); 
} 

void Init_EEPROM_WsEnergyAcc(long addr, Ws_EnergyAcc64* Acc) { 

    uint32 F_ea_32; 
    uint32 F_er_32; 

    Acc->Ea_ps.p[0] = *(uint32 *)addr; 
    addr = addr + 4; 
    Acc->Ea_ps.p[1] = *(uint32 *)addr; 
    Acc->Ea_ps.v = (uint64) Acc->Ea_ps.p[0] << 32 | Acc->Ea_ps.p[1]; 

    addr = addr + 4; 
    Acc->Ea_ng.p[0] = *(uint32 *)addr; 
    addr = addr + 4; 
    Acc->Ea_ng.p[1] = *(uint32 *)addr; 
    Acc->Ea_ng.v = (uint64) Acc->Ea_ng.p[0] << 32 | Acc->Ea_ng.p[1]; 

    addr = addr + 4; 
    Acc->Er_q1.p[0] = *(uint32*)addr; 
    addr = addr + 4; 
    Acc->Er_q1.p[1] = *(uint32*)addr; 
    Acc->Er_q1.v = (uint64) Acc->Er_q1.p[0] << 32 | Acc->Er_q1.p[1]; 

    addr = addr + 4; 
    Acc->Er_q2.p[0] = *(uint32*)addr; 
    addr = addr + 4; 
    Acc->Er_q2.p[1] = *(uint32*)addr; 
    Acc->Er_q2.v = (uint64) Acc->Er_q2.p[0] << 32 | Acc->Er_q2.p[1]; 

    addr = addr + 4; 
    Acc->Er_q3.p[0] = *(uint32*)addr; 
    addr = addr + 4; 
    Acc->Er_q3.p[1] = *(uint32*)addr; 
    Acc->Er_q3.v = (uint64) Acc->Er_q3.p[0] << 32 | Acc->Er_q3.p[1]; 

    addr = addr + 4; 
    Acc->Er_q4.p[0] = *(uint32*)addr; 
    addr = addr + 4; 
    Acc->Er_q4.p[1] = *(uint32*)addr; 
    Acc->Er_q4.v = (uint64) Acc->Er_q4.p[0] << 32 | Acc->Er_q4.p[1]; 

    addr = addr + 4; 
    F_ea_32 = *(uint32*) addr; 
    Acc->F_ea = (uint16) F_ea_32; 

    addr = addr + 4; 
    F_er_32 = *(uint32*) addr; 
    Acc->F_er = (uint16) F_er_32; 

}

私の機能をテストするために、私は少しテストプログラムを行いました私はEEPROMに1回書き込むだけで、例のようにEEPROMを何度も書き込むと動作しませんが、常に0x1000000が出力されます。

誰かが私を助けることができますか?なぜ機能しないのですか?私が一度書くことができれば、なぜ私はそれを何度もやることができないのですか?

ありがとうございました!

+0

EEPROMとフラッシュが混乱しているようです。あなたはどこにでもEEPROMを書いていますが、実際にはフラッシュを使っているようです。 – ElderBug

+0

@ElderBug多くのMCUにはEEPROMエミュレーションモジュールがあります。明らかに、フラッシュメモリに書き込みます。 – LPs

+0

@LPs私はEEPROM-on-flashを宣伝するものは見ていません。私が見たすべてのMCUは、EEPROMをEEPROM(エミュレートされているかもしれませんが、明示的ではないかもしれません)として宣伝しています。 OPのMCUは後者の場合です。 EEPROMはありません。とにかく、たとえ類似性があっても、2つを混同しないほうが明らかです。 – ElderBug

答えて

1

EEPROMを書く度にマストを消去します。はじめて動作したのは、おそらくJTAGが大量消去を実行したためです。

最新のMCUのEEPROMはエミュレートされており、オンチップフラッシュメモリの一部を使用しています。これはなぜあなたが書く前にそれを消去しなければならないかを説明します。

+0

ありがとう!私はFlash_Eraseマクロを持っていましたが、プロジェクトでコンパイルエラーが発生するため、私はそれを使用しませんでした。私は他のポストでそれについて尋ねます。 ありがとうございました! – Kroka