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

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

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

  1. EEADRにアドレスを書き込む
  2. EECON1のRDをセット
  3. データがEEDATAに現れる

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

  1. EECON1のWREN ビットをセット
  2. EEADRにアドレスを書き込む
  3. EEDATAにデータを書き込む
  4. EECON2 に55hを書き込む
  5. EECON2 にAAh を書き込む
  6. EECON1のWR ビットをセット

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

これらの手順を、以下の関数にまとめました、実際のプログラムは例を参考にしてください。

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

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

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

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
RCON IPEN SBOREN RI TO PD POR BOR
INTCON GIE/GIEH PEIE/GIEL TMR0IE INTIE RABIE TMR0IF INT0IF RABIF
PIR2 OSCFIF C1IF C2IF EEIF BCLIF USBIF TMR3IF CCP2IF
PIE2 OSCFIE C1IE C2IE EEIE BCLIE USBIE TMR3IE CCP2IE
IPR2 OSCFIP C1IP C2IP EEIP BCLIP USBIP TMR3IP CCP2IP
EEADR EEADR7 EEADR6 EEADR5 EEADR4 EEAD3 EEADR2 EEADR1 EEADR0
EEDATA EEPROM データレジスタ
EECON1 EEPGD CFGS   FREE WRERR WREN WR RD
EECON2 EEPROM 制御レジスタ2 ( 物理レジスタではない)
レジスタ BIT 説明 1 0
RCON 7 IPEN 2レベルのインタラプト優先度 使用
INTCON 7 GIEH 高優先度インタラプトを使用許可 許可
6 GIEL 低優先度インタラプトを使用許可 許可
PIR2 4 EEIF 送信バッファ フラグ 待ち
PIE2 4 EEIE インタラプトを使用許可 許可
IPR2 4 EEIP インタラプト優先度
EEADR 7-0 EEPROM アドレスレジスタ - -
EECON1 7 EEPGD データEEPROMにアクセスするには 0 にリセット Prgm Data
6 CFGS データEEPROMにアクセスするには 0 にリセット Confg Data
5     - -
4 FREE フラッシュ ロウ( ブロック) 消去イネーブルビット 許可 禁止
3 WRERR エラーフラグ ビット エラー 完了
2 WREN データEEPROM 書き込みイネーブルビット 許可 禁止
1 WR 書き込みサイクル制御ビット (リセットはできない) 開始 完了
0 RD 読み出し開始制御ビット (リセットはできない) 開始 待機

データEEPROM のプログラム例

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

<プログラム>

//  File name: EEPROM
//  Description: Data EEPROM example
//  4つのLEDがpushSWをカウントする。
//  カウント値は毎回data EPROMに保存され、電源OFFでも消えない。
//  Notes: 4MHz内部クロック
//        LED RC0
//        LED RC1
//        LED RC2
//        LED RC3
//    Language: MPLABX XC8
//    Target: PIC18F14K50

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

#define  pushSW  PORTBbits.RB7

//-------------- コンフィグレーション --------------------------------
#pragma config MCLRE  = OFF
#pragma config PWRTEN = OFF, BOREN  = OFF, BORV   = 30
#pragma config WDTEN  = OFF, WDTPS  = 32768
#pragma config STVREN = ON
#pragma config FOSC   = IRC  //  内部クロック
#pragma config PLLEN  = ON,  CPUDIV = NOCLKDIV, USBDIV = OFF
#pragma config FCMEN  = OFF, IESO   = OFF, HFOFST = OFF
#pragma config LVP    = OFF, XINST  = OFF, BBSIZ  = OFF
#pragma config CP0    = OFF, CP1 = OFF, CPB = OFF, CPD = OFF
#pragma config WRT0   = OFF, WRT1 = OFF
#pragma config WRTB   = OFF, WRTC = OFF, WRTD = OFF
#pragma config EBTR0  = OFF, EBTR1 = OFF, EBTRB = OFF

unsigned char eeprom_readbyte(unsigned char);
void eeprom_writebyte(unsigned char, unsigned char);

//------ プログラム直後のEEPROMの初期データ --------------------------

__EEPROM_DATA(3,0,0,0,0,0,0,0);

//--------------------------------------------------------------------


void main(void){
    char data;
    unsigned char EEadd;            // EEPROMアドレス
    OSCCON = 0b01010010;            // 内部クロック4Mhz
    TRISC = 0xF0;                   // 入出力設定
    ANSEL = 0;                      // すべてデジタル設定
    ANSELH= 0;

    EEadd=0;                        //  アドレスリセット
    data = eeprom_readbyte(EEadd);      //  EEPROM 0番地 読み込み
    while(1){                       // 繰り返しループ
        LATC = data;                // LEDを点灯
        while(!pushSW);             // SWが押されていないこと
        __delay_ms(10);             // チャタリング防止10mS遅延
        while(pushSW);              // SWが押されるのを待つ
        __delay_ms(10);             // チャタリング防止10mS遅延
        data++;                     // LEDのカウントを1増やす
        eeprom_writebyte(EEadd, data);  // EEPROM 0番地 書込み
    }
}

unsigned char eeprom_readbyte(unsigned char address)
{
    EEADR = address;            // アドレスをセット
    EECON1bits.EEPGD = 0;       // EEPROM を選ぶ
    EECON1bits.CFGS = 0;        // EEPROM を選ぶ
    EECON1bits.RD = 1;          // 読み出しの開始
    while(EECON1bits.RD == 1);  // 読み出し終了を待つ
    return EEDATA;              // データを持って復帰
}
void eeprom_writebyte(unsigned char address, unsigned char data)
{
	char GIE_on;
    EEADR = address;                // アドレスをセット
    EEDATA = data;                  // データをレジスタに書き込む
    EECON1bits.EEPGD = 0;           // EEPROM を選ぶ
    EECON1bits.CFGS = 0;            // EEPROM を選ぶ
    EECON1bits.WREN = 1;            // EEPROM書き込みを有効に
    GIE_on = INTCONbits.GIE;        // 割込環境を待避
    INTCONbits.GIE = 0;             // 割込みを禁止
    EECON2 = 0x55;                  // EEPROM書き込み暗号を書く
    EECON2 = 0xAA;                  // EEPROM書き込み暗号を書く
    EECON1bits.WR = 1;              // 書き込みの開始
    if(GIE_on)INTCONbits.GIE = 1;   // 割込み環境を復旧
    while(PIR2bits.EEIF == 0);      // 書き込み終了を待つ
    PIR2bits.EEIF = 0;              // EEIF bit クリア
    EECON1bits.WREN = 0;            // 以降は書き込みを禁止する
}