こんにちは、ENGかぴです。
PIC16F1827はEEPROMを搭載しており電源をOFFしてもデータ保持ができます。MCCでMEMORYを追加してEEPROMにデータの読み書きを行います。実装例としてEEPROMに書き込んだデータを読み込んでLCDに表示しました。
LCDはAQM1602XA-RN-GBW(秋月電子)を使用しています。PIC16F1827で動作確認したことについてリンクをまとめています。
PICマイコン(PIC16F1827)で実現できる機能と解説リンクまとめ
EEPROMの使い方
PIC16F1827の設定はMCCを使っています。MCCの使い方については下記記事にまとめています。
MPLAB Code Configurator(MCC)の追加と使い方
今回はMCCを使用してMEMORY・TMR0・MSSP1の設定を行っています。LCDの動作は下記記事を流用しておりEEPの処理を追加して動作確認を行っています。
PICマイコン(PIC16F1827)のI2C通信を実装する
本記事ではEEPの使い方を中心に説明しています。
System Moduleの設定
最初に共通事項であるSystem Moduleの設定を行います。MPLAB X IDEを起動しMCCのアイコンをクリックしてMCCを有効にします。

内部クロックを使用するためINTOSCを選択しています。クロック周波数は任意でもよいですが4MHz_HFを選択しています。クロックを高速にするほど消費電流が増えてしまいます。他にも設定項目はありますがクロックの設定のみとしています。
PR:わからないを放置せず、あなたにあった最低限のスキルを身に着けるコツを教える テックジム 「書けるが先で、理解が後」を体験しよう!
MEMORYの設定
MEMORYをDevice Resources内のPeripherals欄のMEMORYを選択して追加します。

MEMORYを追加してAdd DataEE Routinesにチェックを入れます。GenerateをクリックするとFLASHとEEPROMに関する関数が追加されます。
MCCが生成した関数の使用例(EEP)
#define EEP_ADRS_M 0x00
#define EEP_ADRS_C 0x80
/* EEPデータ読み込み処理 */
void EepRead(void){
uint8_t dat;
uint8_t chk;
dat = DATAEE_ReadByte(EEP_ADRS_M);
chk = DATAEE_ReadByte(EEP_ADRS_C);
if(dat == chk){ //二重化チェック
if( dat == 0xFF){
dat = 0;
}
btncntInit = dat;
}
}
上の例ではEEPROM領域のアドレス0x00と0x80のEEPROMのデータを読み込んでいます。前提としてこれらのアドレスに同一のデータを書き込んでおく必要がありますが、読み込み時に2つのデータを比較してEEPROMのデータが健全であるかのチェックを行うことができます。
2つのデータが一致する場合はEEPROMのデータが健全であるとみなして変数に格納します。EEPROMのデータはイレースした場合や初期状態では0xFFとなるため0xFFが採用されないようにしています。
私の場合は2つのデータでチェックを行った後に範囲チェックする方法でソフト開発を行うことが多いのですがEEPROMがハード的に問題となったことが一度もないため範囲チェックのみ十分だと感じています。
uint8_t btncnt;
uint8_t btncntInit;
//EEP書き込みの例
if( btncnt != btncntInit){
DATAEE_WriteByte(EEP_ADRS_M, btncnt); //EEP書き込み
DATAEE_WriteByte(EEP_ADRS_C, btncnt); //EEP書き込み
btncntInit = btncnt;
}
EEPROMの書き込み回数が有限であるため可能な限り不要な書き込みを防ぐことが推奨されます。上の例では2つの変数が不一致であった場合のみEEPROMのデータの書き込みを行うようにしています。
MSSP1(MSSP1)を設定する
MSSPはMaster Synchronous Serial Port の略称です。PICマイコンのI2C通信はMSSP機能に含まれています。Device Resources内のPeripherals欄のMSSP1を選択して追加します。

MSSP1を選択しSerial ProtocolをI2Cを選択するとModeやClockの設定画面が表示されます。PICマイコンがLCDに対してコマンドを送信するためMasterとなります。
I2C通信が完了したときに割り込みを発生させることができますが特に処理する必要はないため割り込みは使用していません。
TMR0を設定する
TMR0はDevice Resources内のPeripherals欄のTimerを選択しTMR0をクリックして追加します。

Timer Clock内でクロックに関する設定を行います。Clock Sourceは内部クロックを使用しているためFOSC(FOSC/4)を指定します。PrescalerはClock Sourceに対してTMR0のカウントアップする分周比を指定します。
Timer PeriodはTMR0がオーバーフローするタイミングを設定します。1ms毎にオーバーフロー割り込みが発生しますがCallback Function Rateを0x0A(10)を指定しているため10ms毎にコールバック関数が呼び出されます。
void mainTimer(void); //タイマー0割り込みのコールバック関数
//コールバック関数の使用例
TMR0_SetInterruptHandler(mainTimer); //コールバック関数を指定
上記例ではmainTimer()が10ms毎にコールされます。
PR:スキマ時間で自己啓発!スマホで学べる人気のオンライン資格講座【スタディング】まずは気になる講座を無料で体験しよう!
動作確認

PIC16F1827のI2CをLCDに接続しSW1をDIに接続します。SW1を押した回数をLCD上に表示します。SW1を2秒間長押しすると現在のボタンを押した回数をEEPROMに書き込みます。長押しする際もSW1を押した回数がカウントされるためEEPROMに書き込む前にカウント値を-1するようにしています。MCCでのピン設定は以下の通りです。

PB3はINPUTでウィークプルアップ(WPU)設定しています。WPUを有効にするためにはRegistersのnWPUENをenabledにする必要があります。
Easy SetupでWPUにチェックするのみでは有効にならないので注意が必要です。Notificationsにワーニングで通知されます。
EEPROMへの書き込みが終わる(カウントが-1された後)と電源をOFFします。EEPROMに保存されているデータは電源をOFFしても保持されるため次に電源をONしたときにEEPROMのデータの確認を行いデータが消えていないことを確認します。
電源をONすると初期画面が2秒表示されます。メイン処理に遷移すると初期化時に読み込んだEEPROMのデータを表示します。LCDの1段目に「EEP DATA READ:7」と表示しているためEEPROMのデータは0x07が書き込まれています。実際にPICKIT4を使ってEEPROMのデータを確認します。

PICマイコンのEEPROMのデータはMPLAB X IDEを使って確認することができます。ツール上部のDevice Memory ReadをクリックするとPICマイコンに書き込まれているプログラムメモリやEEPROMを読み込むことができます。

Device Memory ReadをクリックしてPICマイコンから読み込みます。Window欄の「Target Memory Views」からEE Data Memoryを選択します。

EEPROMのデータを確認するとアドレス0x00と0x80において0x07が書き込まれていることが分かります。LCDの表示も7であったためEEPROMのデータが読み込めていることが確認できました。
ソースコード全体
ソースコードは記事作成時点において動作確認できていますが、使用しているライブラリの更新により動作が保証できなくなる可能性があります。また、ソースコードを使用したことによって生じた不利益などの一切の責任を負いかねます。参考資料としてお使いください。
リンクからZIPファイル形式のファイルをダウンロードし、任意の場所に展開していただくとテキストファイルが生成されます。
main.cをコピーすると使用できます。本ソースコードはMPLAB X IDEにMCCのプラグインをインストールしていることが前提となります。MCCをインストールする方法は下記記事を参考にしてください。
MPLAB Code Configurator(MCC)の追加と使い方
関連リンク
PICマイコンを使ってマイコンのレジスタの設定やMPLAB X IDEのプラグインであるMCCを使用して動作確認したことについてまとめています。
PICマイコン(PIC12F675)で実現できる機能と解説リンクまとめ
PICマイコン(PIC16F1827)で実現できる機能と解説リンクまとめ
PR:無料トライアル実施中【PC専用】AIスライド資料作成ツールの利用:イルシル
最後まで、読んでいただきありがとうございました。