AVR 超入門 NO.11

[Previous] [Next] [Index]
EEPROM データメモリへのアクセス (ATtiny15L)
 ATtiny15L には 64 バイトのデータメモリがある。出荷時にデータメモリの最終番地に内蔵発振回路の周波数校正値が記録されていて、読み出す操作はすでに試した。

 今回は EEPROM データメモリへの書き込みを試してみた。 AT90S1200 にも 64 バイトのデータメモリがあり、こちらの書き込み方法を参考にいろいろ試してみたが、何度やってもデータメモリに書き込むことができなかった。 ATtiny15L のマニュアルを見たがなかなか理解できず、ようやく AT90S1200 とは命令の一部に違いがあることがわかった。 PIC のマニュアルのように、肝心な部分にはプログラミングサンプルを載せてあれば理解しやすいのにと思うのは私だけではないはず。

EEPROMアクセスプログラム(テキスト形式)

 本来は電源を切ってもデータメモリの内容はそのまま保存されていなければならないが、電源が切れるときに緩やかな電源降下などで、メモリの内容が消えたり書き換えられたりしてしまうことがあるようで、メモリへのアクセス、特に書き込み手順は少々複雑になっている。また、読み出しより書き込みに時間がかかるようで、データーを連続して書き込むときは前のデータがきちんと書き込まれたのを確認してから次を書き込むようにプログラムする必要がある。

 データメモリへのアクセスは I/O ポートアクセスとなるので in/out 命令を使うということをすでに周波数校正値の読み出しの時に学んだ。

 EEPROM データメモリからの読み出しを復習してみると
 @ 読み出したい EEPROM データメモリの番地を EEAR レジスタにセットする。
 A EECR レジスタの bit1(EERE) に 1 をセットして読み込みモードに設定する。
 B EEDR レジスタに指定したデータメモリの内容がセットされる。
という流れになる。

	ldi	temp,0x3F  	; tempにEEPROMの最終番地をセット        (1step)
	out	EEAR,temp  	; EEAR(EEPROM Address Register)         (1step)
				; 読み出すEEPROMのアドレスをEEARにセット
	sbi	EECR,EERE  	; EECR(EEPROM Control Register)         (2steps)
				; EERE(EEPROM Read Enable)
				; EECRにEERE(読み込みモード)を設定
	in	temp,EEDR  	; EEDR(EEPROM Data Register)            (1step)
				; EEDRに読み出されたデータをtempにセット
	out	OSCCAL,temp  	; OSCCAL(Oscilator Caliblation Register)(1step)
				; OSCCALレジスタに周波数校正値をセット
 EEPROM データメモリへの書き込みは
 @ 書き込みたい EEPROM データメモリの番地を EEAR レジスタにセットする。
 A 書き込むデータを EEDR レジスタにセットする。
 B EECR レジスタの bit3(EEMWE) に 1 をセットして EEPROM データメモリへの書き込みを許可する。
 C EECR レジスタの bit2(EEWE) に 1 をセットして書き込みモードに設定する。
という流れになる。データの書き込みが完了すると EEWE にセットした 1 が自動的にクリアされるので、続いてデータを書き込むときは EEWE がクリアされたのを確認してから書き込むようにする。下記に EEPROM データメモリの 0x30 番地に 5 を、 0x31 番地に 8 を書き込む例を示す。

	ldi	temp,0x30
	out	EEAR,temp
	ldi	temp,5
	out	EEDR,temp
	sbi	EECR,EEMWE
	sbi	EECR,EEWE

wait:	sbic	EECR,EEWE  	; Skip if Bit in I/O Register Cleared
	rjmp	wait		; EECRレジスタのEEWEビットがクリアされたら次の書き込みがOK

	ldi	temp,0x31
	out	EEAR,temp  	; 書き込むアドレスをEEARにセットする
	ldi	temp,8
	out	EEDR,temp  	; 書き込むデータをEEDRにセットする
	sbi	EECR,EEMWE  	; この記述が ATtiny15L では必要なのを見落としていた
	sbi	EECR,EEWE
 では実際に AVRstudio を使ってシミュレーション画面で見てみよう。

 画面にはプログラムソースウィンドウと IO ウィンドウのみを出してある。 IO ウィンドウの EEPROM を開くと Data, Address, Control Register 等が表示されている。プログラムカーソルは EEAR に $30 をセットした直後の行にある。 IO ウィンドウの Address の部分が 0x30 となっているのが確認できる。

 ここではプログラムカーソルが EEDR に 5 をセットした直後を示している。 IO ウィンドウの Data に 0x05 と表示されているのが確認できる。

 プログラムカーソルが 1 ステップ進んで EECR レジスタの EEMWE をセットした直後になるが、 IO ウィンドウの Control Register(0x1C) の bit2 にチェックが入っているのが確認できる。また同時に EEMWE にもチェックが入っている。この時点で EEPROM への書き込みが許可される。

 ここでプログラムカーソルがさらに 1 ステップ進み、 EECR レジスタの EEWE がセットされる。 Control Register の bit1 と EERE にチェックが入っている。これでアドレス $30(0x30) に 5 が書き込まれる。書き込みには時間がかかるが、書き込みが完了すると EEMWE と EEWE が自動的にクリアされる。 EEWE のクリアが確認できたら次の書き込み作業に移る。

 EEPROM データメモリへの書き込みプログラムをコンパイルし、生成された HEX ファイルを AVR にライタで書き込んでみると、秋月の PIC Writer Ver.4 では書き込み後にベリファイエラーがでた。 EEPROM データメモリ表示は書き込んだ後も変化がないが、リードコマンドを実行してみたらなんと EEPROM データメモリの 30 番地と 31 番地に 5 と 8 が書き込まれていた。どうしてこのようになるのだろう。プログラムが実行されるときに書き込まれると思っていたのだが・・・。実用上はこれでも問題ないが何とも不思議だ。

 今までデータメモリを使うようなプログラムを組んだことがないが、例えばデータメモリにあらかじめ PWM 制御のデータを書き込んでおいて、プログラム内で参照するような利用方法も考えられるが、プログラムメモリ内で処理するのとどちらが処理スピードが速いだろう?それとも、もっとよい利用方法があるだろうか。

 まとめてみると比較的簡単に EEPROM にアクセスすることができるということがわかるが、理解できるようになるまで半日以上を費やしてしまった。


[Previous] [Next] [Index]
2003/09/25