前回 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 の最終番地に書き込んでおく必要がある。
今回は正確な 1 秒周期を作り出している。 1.6MHz のクロックでは 1 秒で 1600000 ステップになる。デバッグのステップ実行には F10 キーを押すかツールバーのステップアイコンをクリックする。プログラムソースを開いておけば次に実行される行にカーソルが表示される。
デバッグが無事済んだらその HEX ファイルを AVR に書き込んで実際に LED の点滅が 1 秒周期になっているかを確認する。 ATtiny15L は 2.7V から 5.5V までの供給電圧で動作する。
内蔵発振回路によるクロックの精度は温度、電源電圧等で変動する。時計のような用途にはとても使えないが、 PIC では内蔵発振回路を使ってインドアエアプレーンのコントロールで夏冬を通して問題となったことは一度もないので、 AVR でも通常の用途には十分使えるのではないかと思える。