AVRの内蔵CRクロックを校正する

AVRには外部クロックがなくても動作するように、ICの内部にRC発振回路によるクロックを内蔵しています。

工場出荷時に規定の周波数(基本的に8MHz)になるように校正されていますが、データシートによると10%までの誤差がある可能性があり、シリアル通信では致命傷になります。

そこで、個別に調整できるようにOSCCAL(発振校正レジスタ)が存在します。このレジスタをプログラム実行時に書き換えることで発振周波数を変更できます。OSCCALが大きいほど高い周波数で、小さいほど低い周波数で動作します。

AVRはヒューズビットのCKOUTをプログラム(0)することにより、CLK0端子からシステムクロックが出力されます。これを測定機器で観測しながらOSCCALレジスタを操作することによりクロックを調整します。

校正

手元にあったATmega88を8Mhzに校正してみました。今回は周波数の測定には周波数カウンタを利用しました。もちろんオシロスコープで周波数を算出しても構いません。

工場出荷時の校正値はAVR ISP mkⅡを利用して読み出せます。この個体は0xbbになっていました。この状態での発振周波数はこのようになりました。

工場出荷時(0xbb) 8.09MHz

工場出荷時(0xbb) 8.09MHz

8.09MHzと少し高い周波数になっていました。誤差は+1.3%とデータシートの許容範囲10%に比べるとかなりよい精度です。が、少し高いので0xbaにしてみました。

OSCCAL = 0xba 8.03MHz

OSCCAL = 0xba 8.03MHz

0xbaにしたところ8.03MHz。これでもまだ高いので、0xb9にしてみます。

OSCCAL = 0xb9 7.99MHz

OSCCAL = 0xb9 7.99MHz

0xb9にすると7.99MHzと誤差は-0.13%とかなり高精度にできました。しかし、残念ながらCR発振は気温等に影響されるので常にこの精度を維持することはできません。あくまでも「今の環境」での周波数です。

実験

試しにどこまでいけるのか、CLK0端子を周波数カウンタに接続しながらいろいろとOSCCALを操作して動作周波数を見てみます。

OSCCALを0x00にしてみると、3.92MHz。

OSCCAL = 0x00 3.93MHz

OSCCAL = 0x00 3.93MHz

半分の0x7fでは、8.08MHz。あれ?0xb9の時より高い?

OSCCAL = 0x7f 8.08MHz

OSCCAL = 0x7f 8.08MHz

そこで、0x8fにしてみると、6.53MHz。データシートを読んでみると、最上位ビットは高周波範囲(1)か低周波範囲(0)かの選択になっているようで、この2つの範囲は重なっており、0x7fの時の方が0x80のときより高い周波数になっているようです。

OSCCAL = 0x8f 6.53MHz

OSCCAL = 0x8f 6.53MHz

最後にもっとも大きい0xffにしてみると、12.97MHzとなりました。

OSCCAL = 0xff 12.97MHz

OSCCAL = 0xff 12.97MHz

これほど範囲が広いのであれば無理矢理でよければ内蔵CRである程度の速度まで動かすことができそうです。

おまけ

周波数カウンタに接続したブローブをどこにもつながないと、商用電源のノイズを広うようで、60Hz近辺の周波数が表示されました。

商用電源のノイズ 60hz

商用電源のノイズ 60hz

この記事はAVRに投稿されました タグ: , , , , . このパーマリンクをブックマークする。 コメントを投稿するか、トラックバックをどうぞ: トラックバック URL.

4 コメント