SCIでデータを不揮発メモリに格納し、電源OFF前のデーターを保持する必要が発生しました。

 

最初EEP-ROM のキーワードで探したが、WEBではどうにも見つからない。悩んでもがいてみると、ようやく解決方法が見えてきた。

 データーシートの中では、NVM不揮発性メモリ)という検索キーワードでした。

その中で、データー用のメモリは、DFM(データーフラッシュメモリー)の記述にて解説していました。集中力が切れてると、探せません・・・

 

DFMは、8bit X 1024 の大きさです。詳細は、データーシート、10.4に記載されています。

 

読み出しの手順は、

 

1. Set the NVMADR registers to an address within the intended page.

2. Set the NVMCMD control bits to ‘b000 (Byte Read).

3. Set the GO bit to start the DFM byte read.

4. Monitor the GO bit or NVMIF interrupt flag to determine when the read has completed.

 

でサンプルコードは、Example 10-9. Reading a Byte from Data Flash Memory in C

 

// Code sequence to read one byte from DFM

// DFM target address is specified by DFM_ADDR

// Variable to store the byte value from desired location in DFM

 

uint8_t ByteValue;

 

// Load NVMADR with the desired byte address

 

NVMADR = DFM_ADDR;

NVMCON1bits.CMD = 0x00;        // Set the byte read command

NVMCON0bits.GO = 1;                 // Start byte read

while (NVMCON0bits.GO);           // Wait for the read operation to complete

ByteValue = NVMDATL;                // Store the read value to a variable

 

読み込みだけなので、簡単みたいです。

 

書込み手順は、

1. Set NVMADR registers with the target byte address.

2. Load NVMDATL register with desired byte.

3. Set the NVMCMD control bits to ‘b011 (Byte Write).

4. Disable all interrupts.

5. Perform the unlock sequence as described in the Unlock Sequence section.

6. Set the GO bit to start the DFM byte write.

7. Monitor the GO bit or NVMIF interrupt flag to determine when the write has been completed.

8. Interrupts can be enabled after the GO bit is clear.

9. Set the NVMCMD control bits to ‘b000.

 

そのコードは、Example 10-10. Writing a Byte to Data Flash Memory in C

 

// Code sequence to write one byte to a DFM

// DFM target address is specified by DFM_ADDR

// Target data is specified by ByteValue

 

// Save interrupt enable bit value

uint8_t GIEBitValue = INTCON0bits.GIE;

 

// Load NVMADR with the target address of the byte

 

NVMADR = DFM_ADDR;

NVMDATL = ByteValue;               // Load NVMDAT with the desired value

NVMCON1bits.CMD = 0x03;        // Set the byte write command

INTCON0bits.GIE = 0;                  // Disable interrupts

 

//––––––––– Required Unlock Sequence –––––––––

NVMLOCK = 0x55;

NVMLOCK = 0xAA;

NVMCON0bits.GO = 1; // Start byte write

//–––––––––––––––––––––––––––––––––––––––––––––––

while (NVMCON0bits.GO);           // Wait for the write operation to complete

// Verify byte write operation success and call the recovery function if needed

if (NVMCON1bits.WRERR){

WRITE_FAULT_RECOVERY();

}

 

 INTCON0bits.GIE = GIEBitValue;            // Restore interrupt enable bit value

NVMCON1bits.CMD = 0;                            // Disable writes to memory

 

どこかで見たことがある様な、EEPROM の書き込み手順と同じな気がします。

(因みに消し方とかは、DataSheet から確認を。)

 

さて、このコード内で自分で決めるのは、2

ByteValue はデーターの値なので まあ簡単かもしれない。

DFM_ADDR は、何を入れるのですか?

 

NVMADR のレジスタ長は、24 ビット長という事なので、これを指定すればよいのね。

但し上位2ビットはマスクされるので、実質22ビットのアドレス空間と考えれば良さそうです。

 

Figure 9-1. Program and Data Memory Map

から考えるとData EEPROM 1024Bytes)は 380000h3803FFh にエントリーされている様子

 

1バイトのデーターならこの空間内のアドレスを指定すればいいのでしょう。

 

define EEPROM_START         380000h

にオフセットアドレスを加える感じで、アドレス指定すればいいのではないかと思います。

 

これを元に関数として作成したのがこちらです。(XC8MPLAB X V6.05

 

 

void  EEP_ROM_write(uint8_t ByteVAlue, uint8_t Bytedata){

 

uint8_t GIEBitValue = INTCON0bits.GIE; // Save interrupt enable bit value

 

// Load NVMADR with the target address of the byte

NVMADR = EEPROM_START+ ByteVAlue;    // EEPROM START ADD + Offset Add

NVMDATL = Bytedata;           // Load NVMDAT with the desired value

NVMCON1bits.CMD = 0x03;       // Set the byte write command

INTCON0bits.GIE = 0;          // Disable interrupts

 

//????????? Required Unlock Sequence ?????????

NVMLOCK = 0x55;

NVMLOCK = 0xAA;

NVMCON0bits.GO = 1; // Start byte write

//???????????????????????????????????????????????

while (NVMCON0bits.GO);       // Wait for the write operation to complete

INTCON0bits.GIE = GIEBitValue; // Restore interrupt enable bit value

NVMCON1bits.CMD = 0;          // Disable writes to memory

}

 

この関数を書き込んで、チェック。無事コンパイル通りました。

 

無事に、電源OFF前に書き換えた内容で、再起動時に表示。

 

動作OKです。