AVR 超入門 NO.5

[Previous] [Next] [Index]
ATtiny15L の内蔵発振回路校正値の設定
 今回も発光ダイオードの点滅プログラムになる。 AT90S1200 の時と異なるのは内蔵発振回路を使い、 0.5 秒点灯 0.5 秒消灯の繰り返し時間を正確に合わせてみる。内蔵発振回路を使う場合、内蔵発振周波数のずれを補正するために、 ATtiny15L 一つ一つに周波数校正値が書き込まれている。タイミングを考慮したプログラムを組むときにはこの周波数校正値を OSCCAL レジスタにセットしてプログラムを実行することで、発振周波数のずれが最小に抑えられる。この設定はとても大事なのできちんと理解できるように勉強してみた。

 前回 PIC Programmer にセットして読み取った周波数校正値はプログラムメモリの最終番地とデータメモリの最終番地に記録されていた。この値はそれぞれの個体特有のものなので、プログラムの中にその値を記述することができない。どこかにメモしておいて、プログラムをライタに読み込んだあと、たとえばデータメモリの最終番地に付け加えてから AVR に書き込んでもいい。

 もっと楽に書き込めないかを考えてみたら、新品の AVR をセットしてリードコマンドを実行して周波数校正値をロードしたあと AVR に書き込むための HEX ファイルを読みんでライトコマンドを実行すれば、データメモリの最終番地に周波数校正値が書き込まれたままになる(補足:秋月の PIC Programmer Ver.4 を使い、秋月のライタソフト AVR Programmer Ver.6 を使って「コードファイルを開く」で読み込んだ場合)。プログラムでこのメモリの最終番地に書かれている周波数校正値を読み出して OSCCAL レジスタにセットすればいいことになる。この方法なら個体それぞれの周波数校正値の違いに対応できる。

 二度目以降の書き換えにおいてもリードコマンドを実行してから HEX ファイルを読み込むようにすれば周波数校正値をきちんと引き継ぐことができる。  データメモリは EEPROM でこの EEPROM へのアクセスには I/O 空間でアクセスすることになる。つまり in/out 命令を使う。この命令の使い方がちょっとわかりにくかったが、 EEPROM の最終番地(0x3F) から周波数校正値を読み出して OSCCAL レジスタにセットする手順は下記のようになる。

	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レジスタに周波数校正値をセット
 上記 5 行をプログラムのはじめに記述すれば ATtiny15L は 1.6MHz の最もずれの少ない発振周波数で動作する。ただし AVR のプログラムを書き換えるときは前もってリードコマンドを実行して EEPROM の最終番地に周波数校正値を読み込むか、ライタソフトでその値を EEPROM の最終番地に書き込んでおく必要がある。

ledtest2.asm (テキスト形式)

ledtest2.asm

 では AVRstudio できちんと 0.5 秒点灯、 0.5 秒消灯のタイミングを確認してみよう。 Project Name を ledtest2 として Build and run を実行する。すると Simulator Options ウィンドウが自動的に開くので、でバイスに ATtiny15L を指定し、 Frequency に 1.600000MHz と入力する(選択できるリストの中ににないので手入力)。つぎにメニューの View からか Processor をチェックすると Processor ウィンドウが開く。 StopWatch でタイミングが確認できる。 StopWach に表示される時間は必要ならいつでもクリアできるので経過時間のチェックにはとてもいいのだが、長時間タイマでは小数点以下 2 桁しか表示されないので、厳密なタイミングは確認できない。そのようなときは Cycle Counter で確認する。

 今回は正確な 1 秒周期を作り出している。 1.6MHz のクロックでは 1 秒で 1600000 ステップになる。デバッグのステップ実行には F10 キーを押すかツールバーのステップアイコンをクリックする。プログラムソースを開いておけば次に実行される行にカーソルが表示される。

 画像のサイズは今回の説明のため小さくしてあるが、実際のデバッグでは大きな画面で作業した方が楽。デバッグを行うためにソースファイルと IO ウィンドウと Processor ウィンドウを開く。そのあと画像にある行まで F10 キーを押してカーソルを進める。この時点で Processor ウィンドウの Cycle Counter を見ると、プログラムをスタートしてからカーソル行までのステップ数が表示されているのがわかる。ここまで 11 ステップで実行されたことを示している。もう 1 ステップ進めると出力が ON になり LED が点灯する。

 1 ステップ進めた画像。 IO ウィンドウを見ると Port B Data のチェックボックスがすべてチェックされている。すなわちすべての出力が ON になったことを示している。

 F10 を押して画像の行まで進める。現在の行を 1 ステップ進めると出力が OFF になり LED は消灯する。このときの Processor ウィンドウの Cycle Counter を見ると 800011 ステップを示している。厳密には 800012 ステップとならなければならないが、点灯時と消灯時のタイマーを共用していてトータルして正確な 1 秒周期を作り出している。

 loop を一周したときの画像。前の同じ行にカーソルがある時の Processor ウィンドウの Cycle Counter と見比べてみるとその差がぴったり 1600000 ステップになっていることがわかる。もしこの値にずれがある場合はタイマループのカウンタ値を変更したり nop を挿入するなどして、再度メニューの Project から Build and run を実行したあとデバッグする。

 デバッグが無事済んだらその HEX ファイルを AVR に書き込んで実際に LED の点滅が 1 秒周期になっているかを確認する。 ATtiny15L は 2.7V から 5.5V までの供給電圧で動作する。

 内蔵発振回路によるクロックの精度は温度、電源電圧等で変動する。時計のような用途にはとても使えないが、 PIC では内蔵発振回路を使ってインドアエアプレーンのコントロールで夏冬を通して問題となったことは一度もないので、 AVR でも通常の用途には十分使えるのではないかと思える。


[Previous] [Next] [Index]
2003/09/08
2003/09/11 update