PIC16F18325の基本動作から応用プログラムまでを学びます。

ホーム
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
    
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
Data EEPROM
2017-09-02

PIC16F18325には、電源を切っても保存内容が消えない不揮発性のデータEEPROMが256 バイトあります。 マイコンを使用する環境によりその初期設定値など変更しなければならないときには非常にありがたいメモリです。しかし、その読み書きは多少複雑です。また、書込みには通常のRAMより時間がかかります。データEEPROMに保存されたデータを読み出すには、以下の手順が必要です。

  1. NVMADRに0x7000 + EEPROMアドレスを書き込む
  2. NVMCON1のRDをセット
  3. データがNVMDATに現れる

データEEPROMへデータを書込むには、以下の手順が必要です。

  1. NVMCON1のWREN ビットをセット
  2. NVMADRに0x7000 + EEPROMアドレスを書き込む
  3. NVMDATにデータを書き込む
  4. NVMCON2 に55hを書き込む
  5. NVMCON2 にAAh を書き込む
  6. NVMCON1のWR ビットをセット

書き込みサイクルが完了すると、ハードウェアによって

これらの手順は、XC8のライブラリにすでに設定されているため、実際のプログラムでは、

関数を使用すれば目的を達成することができます。また、PICへのプログラム書き込み時に、EEPROMに初期値をセットするには、XC8のライブラリに設定されているマクロ命令を使用します。

かっこ内に、8ビット値を8個指定します。例のように、初めの1バイトしか使用しない場合にでも、8個全てをパラメータとして指定します。 この値が、EEPROMの先頭アドレスから順にセットされます。この命令を32個並べることで、256アドレス全てに、データをプリセットすることができます。

データEEPROMに関連するに関連するレジスターを一覧で説明します。

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
INTCON GIE PEIE - - - - - INTEDG
PIE2 TMR6IE C2IE C1IE NVMIE SSP2IE BLC2IE TMR4IE NCO1IE
PIR2 TMR6IF C2IF C1IF NVMIF SSP2IF BLC2IF TMR4IF NCO1IF
NVMADRH - NVM アドレス< 14 - 8 >
NVMADRL NVM アドレス< 7 - 0 >
NVMDATH - - NVM データ< 13 - 8 >
NVMDATL NVM データ< 7 - 0 >
NVMCON1 - NVMREGS LWLO FREE WRERR WREN WR RD
NVMCON2 EEPROM 制御レジスタ2 ( 物理レジスタではない)
レジスタ BIT 説明 1 0
INTCON 7 GIE インタラプトを使用許可 許可
6 PEIE ペリフェラルインタラプトを使用許可 許可
PIR2 4 NVMIF EE書き込み完了フラグ 完了 待ち
PIE2 4 EEIE インタラプトを使用許可 許可
NVMADRL 7-0 EEPROM アドレスレジスタ - -
NVMADRH 14-8 EEPROM アドレスは、0x70 - -
NVMCON1 7     - -
6 NVMREGS データEEPROMにアクセスするには 1 にセット Data Prgm
5 LWLO Progrm PROMにアクセスするに使用
4 FREE Progrm PROMにアクセスするに使用 許可 禁止
3 WRERR エラーフラグ ビット エラー 完了
2 WREN データEEPROM 書き込みイネーブルビット 許可 禁止
1 WR 書き込みサイクル制御ビット (リセットはできない) 開始 完了
0 RD 読み出し開始制御ビット (リセットはできない) 開始 待機

データEEPROM のプログラム例

PushSWを押した回数をLEDでカウントするプログラムです。SWが押されるたびにカウント数をdataEEPROMに書込み、LEDにも反映します。 DataEEPROMに毎回保存しているため、電源を切ってから再び電源を供給したときには、前のカウント数からスタートします。まお、プログラム直後のカウント数は、「3」に設定してあります。

<プログラム>

/*************************************
 * File: EE DataPROM sample
 * System ClockはConfigで内部1MHzに設定
 * RA3 のSWが押されたらEEPROMデータを+1する
 * RC0-RC3 にEE_POMデータを表示
 * PIC16F18325
 * Created on July 22, 2017, 2:37 PM
 **************************************/

#include <xc.h>
#define _XTAL_FREQ 1000000      // delay_ms(x) のための定義

#pragma config FEXTOSC = OFF,RSTOSC = HFINT1  // HFINTOSC (1MHz)
#pragma config CLKOUTEN = OFF,CSWEN = OFF,FCMEN = OFF
#pragma config MCLRE = OFF,PWRTE = OFF,WDTE = OFF,LPBOREN = OFF
#pragma config BOREN = OFF,BORV = LOW,PPS1WAY = OFF,STVREN = ON
#pragma config DEBUG = OFF
#pragma config WRT = OFF,LVP = OFF,CP = OFF,CPD = OFF

#define LEDs    LATC
#define pushSW  PORTAbits.RA3

//------ プログラム直後のEEPROMの初期データ --------
__EEPROM_DATA(3,0,0,0,0,0,0,0);
//---------------------------------------------

void main(void) {
    char data;
    LATC = 0;
    TRISC = 0b110000;           // RC0-RC3を出力に設定
    TRISA = 0b111111;           // PortAを入力に設定
    ANSELA = 0;                 // 全てのpinをデジタルに設定
    ANSELC = 0;
    __delay_ms(100);            // 安定を待つ
    while(1){
        data = eeprom_read(0);  // EEPROM 0番地 読み込み
        LEDs = data;            // LEDを点灯
        while(!pushSW);         // SW ON/OFF を待つ
        __delay_ms(5);
        while(pushSW);
        __delay_ms(5);
        data++;                 // LEDのカウントを1増やす
        eeprom_write(0, data);  // EEPROM 0番地 書込み
    }
}
//*************************************************
// コンパイラがEEPROM読み書きをサポートしていないときは
// 以下の関数を使用する
//*************************************************
//unsigned char eeprom_readbyte(unsigned char address)
//{
//    NVMADRH = 0x70;                 // アドレスをセット
//    NVMADRL = address;              // アドレスをセット
//    NVMCON1bits.NVMREGS = 1;        // EEPROM を選ぶ
//    NVMCON1bits.RD = 1;             // 読み出しの開始
//    while(NVMCON1bits.RD == 1);     // 読み出し終了を待つ
//    return NVMDATL;                 // データを持って復帰
//}
//void eeprom_writebyte(unsigned char address, unsigned char data)
//{
//	char GIE_on;
//    NVMADRH = 0x70;                 // アドレスをセット
//    NVMADRL = address;              // アドレスをセット
//    NVMDATL = data;                 // データをレジスタに書き込む
//    NVMCON1bits.NVMREGS = 1;        // EEPROM を選ぶ
//    NVMCON1bits.WREN = 1;           // EEPROM書き込みを有効に
//    GIE_on = INTCONbits.GIE;        // 割込環境を待避
//    INTCONbits.GIE = 0;             // 割込みを禁止
//    NVMCON2 = 0x55;                 // EEPROM書き込み暗号を書く
//    NVMCON2 = 0xAA;                 // EEPROM書き込み暗号を書く
//    NVMCON1bits.WR = 1;             // 書き込みの開始
//    if(GIE_on)INTCONbits.GIE = 1;   // 割込み環境を復旧
//    while(PIR2bits.NVMIF == 0);     // 書き込み終了を待つ
//    PIR2bits.NVMIF = 0;             // NVMIF bit クリア
//    NVMCON1bits.WREN = 0;           // 以降は書き込みを禁止する
//}