第13回 EEPROM(1) 〜EEPROMとは〜

今回からEEPROMを使ったプログラムを作成してみます。

現在のタイマー機能の問題点

前回までのプログラムで、タイマー時間を設定する機能を追加することができました。

ところで、まだちょっと機能が足りませんよね。すでにお気づきかもしれませんが、タイマー時間を変更した場合、電源をOFFにすると変更した値は消されてしまい、次に電源を入れた時には元のデフォルトのタイマー時間に戻ってしまいます。

タイマー時間を変更したのであれば、その設定時間は電源を切ってもまた次回電源を入れた時に有効になっていて欲しいですよね。

PICマイコンに限らず、他のマイコンでも、この課題を解決する方法が用意されています。それは「EEPROM」と呼ばれる、電源をOFFにしても記憶内容を保持するメモリが搭載されています。

そこで今回から、タイマー時間を変更したらその設定時間を「EEPROM」に保存しておいて電源をOFFにしてもその設定時間を保持しておく、というプログラムを作成していきます。

 

メモリの種類

データを保持しておく「メモリ」には様々な種類がありますが、記憶保持の観点から大きく2種類に分かれます。

一つは電源がないと記憶した内容が消えてしまう「揮発性メモリ」、もう一つは電源をOFFにしても記憶内容が消えない「不揮発性メモリ」です。

これらは単に「消えるメモリ」「消えないメモリ」と呼べばいいところを、「揮発性メモリ」と呼んでいます。なんとなく意識高い系な気がしますが、学問の分野は基本的に意識高い系の用語を使う、という暗黙のルールがありますので我慢しましょう。

「揮発」という言葉ですが、一般に使われている意味とほぼ同じです。

例えば消毒用アルコールってすぐに蒸発してしまいますよね。これをちょっと難しくいうと「アルコールは揮発性が高い」と言ったりします。すぐに蒸発して消えてしまう液体を「揮発性がある」「揮発性が高い」というわけです。

「揮発性メモリ」とは、電源をOFFにすると記憶した内容が蒸発して消えてしまうことからこのように呼ばれています。ということは、日常生活で物忘れが多くなった場合には「最近、記憶の揮発性が高まった気がするんだよね」というと、、、ちょっと変ですね。

EEPROMは電源をOFFにしても記憶内容が消えないので、「不揮発性メモリ」と呼ばれています。

 

「EEPROM」とは

EEPROMは不揮発性メモリであることがわかりましたが、何の略なんでしょうか。

EEPROM = Electrically Erasable Programmable Read-Only Memory

です。日本に訳すと「電気的に消去、書き込み可能な、読み出し専用メモリ」です。

ん? ちょっとこれ、意味おかしくないですか?

「電気的に消去したり書き込み可能な」と言ってる割に「読み出し専用メモリ」ってなんか矛盾してるような気がします。「読み出し専用メモリ」でしたら消去とか書き込みができないような気もしますが…

気になってしまう方のために補足しておきますが、特にこの部分は読まなくても問題ありませんので、この説明は飛ばしていただいて構いません。

昔、コンピュータのメモリは「RAM (Random Access Memory)」と呼ばれる「読み書き可能・電源がないと記憶内容が消えるメモリ」と、「ROM (Read-Only Memory)」と呼ばれる「読み込みのみ可能(書き込み不可)・電源がなくても記憶内容が消えないメモリ」の2種類がありました。

このROMですが、いつどのようにデータを書き込むかというと、ROMライターと呼ばれるROMにデータを書き込む機器があり、新品のROMの内部接続回路を焼き切ってデータを書き込むようになっています。イメージとしては、ROMの中にたくさんヒューズが並んでいて、ヒューズがあるところが1、ヒューズが焼き切ってあるところが0、というように、記憶するデータに合わせてヒューズを焼き切っていきます。

このタイプのROM、ROMライタは今でも販売されています。

ROMの例
ROMライタの例

このようにデータを書き込んだROMは、ヒューズを焼き切ってしまっていますので、当然ながらデータ内容を変更できません。その代わり、電源がなくてもデータが保持できるわけです。このようなROMの仕組みでは、内容を変更したい場合はそのROMは捨てて新しいROMにデータを書き込むしかありません。

でも今回プログラムで実現しようとしているような、後からデータ内容を変更できる、電源をOFFにしても記憶内容が消えないメモリが欲しいですよね。

ということで、「あとから記憶内容を消去したり書き込んだりできるROM」が開発されたわけです(このメモリは、先ほどのヒューズを焼き切るタイプのROMの構造・原理とは違います)。

ここで我に返ってみます。「ROM」って読み出し専用メモリ」でしたよね。ということは、先ほど自分で言ってしまった「あとから記憶内容を消去したり書き込んだりできるROM」とは「あとから記憶内容を消去したり書き込んだりできる、読み出し専用メモリ」ってわけで、自分も矛盾した結論を出してしまったわけです。

 

PIC12F1822のEEPROM

それでは、PIC12F1822のEEPROMについて確認してみましょう。

最初にどれぐらいの記憶容量があるか確認します。以下はPIC12F1822のデータシートです。

Pic app 13 eeprom spec
(Microchip社 PIC12F1822データシートより引用・加工)

枠で囲んだ部分がEEPROMの容量の仕様です。データシートから256バイトであることがわかります。「メガバイト」とか「ギガバイト」ではなく「バイト」です。

メモリやSSDがギガバイト単位の世の中で、256バイトとはずいぶん少なくて心もとない気もしますが、マイコンでしたらこのぐらいの容量で十分なケースが多いです。今回のタイマー時間の保持も1バイトのみ使用しますので、256バイトはうまく使えば有効に活用できます。

このEEPROMですが、マイコン内部では独立したモジュールになっています。

Pic app 13 eeprom module
(Microchip社 PIC12F1822データシートより引用・加工)

これからこのEEPROMに対して読み書きしていくわけですが、256バイトあるEEPROMのどこに書いたり、どこから読むか、場所を指定する必要があるわけです。この場所のことを「アドレス」または「番地」と呼ばれています。

例えばPIC12F1822ではEEPROMの256バイトに対して以下のようにアドレスが割り当てられています。

Pic app 13 eeprom address

プログラムでEEPROMを扱う場合、「どのアドレスにデータを書くか」あるいは「どのアドレスからデータを読むか」という指定を行います。

それでは次に、EEPROMの具体的な使い方をみてみましょう。

 

PICマイコンのEEPROMの使い方

最初はEEPROMからのデータの読み出しです。例えばアドレス0から読み出した値を変数 read_data (unsigned char)に格納したい場合は、

read_data = eeprom_read(0);

とかけばOKです。

次にEEPROMへのデータの書き込みです。例えば write_data (unsigned char)の値をアドレス0に書き込みたい場合は、

eeprom_write(0, write_data);

とかけばOKです。

まとめると、EEPROMからデータを読み出す場合は、

eeprom_read( アドレス );

とかげは、返り値が読み出したデータになります。

またEEPROMへのデータの書き込みは、

eepprom_write( アドレス, データ );

とかけば、指定したアドレスにデータが書き込まれます。

これで読み書きができますが、初期値はどのように設定すればいいでしょうか。EEPROMの初期値は main関数で書き込むことはできません。

例えば、main関数の最初に

eeprom_write(0, 5);

などと、アドレス0にデータ5を書き込むように書いてしまうと、電源を投入するたびにmain関数が呼ばれますので、毎回アドレス0が5になってしまいます。

初期値を設定したい場合は、main関数の外に以下のフォーマットで書きます。

__EEPROM_DATA (アドレス0のデータ, アドレス1のデータ, アドレス2のデータ,アドレス3のデータ,アドレス4のデータ,アドレス5のデータ, アドレス6のデータ, アドレス7のデータ);

“EEPROM”の前はアンダースコア2個、”EEPROM”と”DATA”の間はアンダースコア1個です。

このように書いておくと、PICKIT3でプログラムを書き込む際、一緒にEEPROMにこのデータも書き込んでくれます。

なお、この書き方には注意点があります。必ず8バイト単位で書きます。以下の書き方はNGです。

__EEPROM (0x00, 0x01, 0x02, 0x03);

これは4バイトしかありません。

8バイトに満たない場合は、0xFFで埋めて8バイトにします(0xFFでなくても構いませんが…)。例えば、アドレス0に0x1Fを書き込んでおきたい場合は、

__EEPROM_DATA (0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);

と書きます。また、8バイトを超える場合は、この行を複数行書きます。

以上がEEPROMの概要とプログラム方法です。

次回は、設定したタイマー値をEEPROMに保存、読み出しを行うプログラムを追加したいと思います。

 

更新履歴

日付 内容
2017.7.30 新規投稿
2018.12.2 誤記訂正

« »