前回まで4回を費やしてMSSPを一通りなでました。今回は「軽く」NVM(NONVOLATILE MEMORY)に入りたいと思います。PIC16FマイコンはプログラムメモリとしてFlashを搭載しているだけでなく、不揮発なデータ格納用にEEPROMを搭載しています。これがあれば電源切っても消えない設定など自由自在だっ。
※『PIC三昧』PIC関係の記事総目次はこちら
※作業はMicroChip社の統合開発環境 MPLAB X IDEと、その上で走るコンフィギュレーションツールMCC Classic を使用して行っています。ターゲット・マイコンはPIC16F18855です。
オンチップNONVOLATILE MEMORY
-
- PFM Program Flash Memory 、1ワード14-bit、14Kワード、32ワードを1ブロックとした消去書き込みに対応。エンデュランスは1万回。データ保持期間40年、書き込みサイクルタイムは 2.5ms MAX.
- Data EEPROM、1ワード8-bit、256ワード、バイト単位の書き変え可能。エンデュランスは10万回、データ保持期間40年、書き込みサイクルタイムは1バイトにつき5ms MAX.
MCC Classicでの設定
NVMをプログラムからアクセスするための関数を使うためにはその名も「MEMORY」というリソースをプロジェクトに追加する必要があります。
といっても設定項目などはなく、イネーブルにして関数がプロジェクトに取り込まれるようにするだけのようです。こんな感じ。
なお、今回もSTDIOをUSBシリアルに向けて出力を見れるようにしておくので、EUSARTも追加します。
手元のMCC Classicの場合、STDIOとして使うにあたっては前回同様の対処が必要です。
ピンマネージャの設定は以下の通りです。EUSARTのピンはUSBシリアルへのボード配線、PortAのビット0はLチカ用のLEDへの配線です。また、PortAのビット5を外部スイッチに接続し、EEPROMへの書き込みモードと読み出しモードの切り替えに使っています。
EEPROM Read&Write、手抜きなテストプログラム
PortAのビット5が0(GND)なら書き込みモードに入りEEPROMの全バイトに0から255を書き込みます。ビット1が1(3.3V)なら読みだしモードに入りアドレス0xF000から0xF0FFまでのEEPROMの全バイトを標準出力に送ります。その際、書き込み時にはアドレスの下8ビット=データとしてあるので、書き込めているか否かが分かるようになっています。
void main(void) { uint16_t adr; uint8_t dat; SYSTEM_Initialize(); INTERRUPT_GlobalInterruptEnable(); INTERRUPT_PeripheralInterruptEnable(); if (RA5 == 0) { printf("WRITE EEPROM\n"); adr = 0xF000; dat = 0; while (adr < 0xF100) { DATAEE_WriteByte(adr++, dat++); } printf("WRITE Complete.\n"); } else { printf("READ EEPROM\n"); adr = 0xF100; while (1) { RA0 = 1; __delay_ms(1000); adr = adr >= 0xF100 ? 0xF000 : adr + 1; printf("ADR=0x%04x RD=0x%02x\n", adr, DATAEE_ReadByte(adr)); RA0 = 0; __delay_ms(1000); } } }
なお、書き込み関数 DATAEE_WriteByte()は、書き込み完了確認待ちループを含むので戻ってくれば書き込みプロセスは完了しているとみなせます。ただし、書き込み中は割り込み禁止になるので、割り込み使っていると取りこぼしが発生する可能性があります。実際、書き込みモードで標準出力にPrintfすると取りこぼしが起きている気がします。EEPROM書き込み時は他の仕事は止めてこれに専念するのが良いように思います。
また、読み出し関数 DATAEE_ReadByte()は割り込みを操作したりしないようなのでお楽。ただし、内部の読み出しタイミングはNOPの個数でとってます。高速なシステムクロックの場合NOPの数が足らなくなる可能性があるようです。以下コメントは引用。
// NOPs may be required for latency at high frequencies
しかし、今回のシステムクロックは1MHz設定なので問題なしと思います。
実機動作確認
EEPROMの全バイト0xFFが読み取れるようです。
つづいてスイッチを書き込みモードにして走らせます。その後、再び読み出しモードにして読み出してみます。
アドレスの下8ビットと同じ値がデータとして書き込まれていることが確認できました。予定通りね。