2011年5月21日土曜日

【AVR】 ATmega8x Fuse-bit Memo

鬼門のヒューズビット?
 先のBlogではAVRマイコン基板を作成したが、ATmega8を使うのは初めてであった。もちろん、同じ系統のATmega48、168、328なら使ったことはあったのだが、なぜかmega8は初めてである。(少々賞味期限切れの感じだが、いま使わないと機会がなくなりそうで・・)

 この28pin AVRシリーズは類似点も多いので、あらかた同じで動作するのだが初めて使うなら一応データシートを見てからと言うことになる。 BASCOM-AVRは固有のチップへの依存度は低いのだがヒューズビットは個々に見ておこう。以下ヒューズビットの要点と感じたことをメモして行く。

 ヒーズビットの操作そのものは難しくはない。 写真のように今ではGUIプログラムで一発だし、BASCOM-AVRの対応ライタならプログラミング画面からも容易に操作できる。あるいはコマンド・プロンプトから文字列のキーインでやるのも難しいと言うほどではない。要するに、書き換えそのものは難しくないのだ。

 ところが、巷ではAVRマイコンの「ヒューズビット」は鬼門のように言われている。どうやらその理由は2つあるらしい。

1・とっても危険な行為:
 「ヒューズビットを下手にいじるとAVRマイコンがパーになる。怖いな〜!」、「使えなくなると怖いので触らないのが吉。素人はそのまま使うに限る」

2・説明が難解で自信が持てない:
 「ヒューズビットって良くわからん。ワタシがやりたいことに合う設定を誰かおせえて」、「ATMELのデータシートが難解で、結局どうしたら一番良いの!」

 確かに、無闇に操作するとプログラムの書込みができない状態に設定してしまう可能性がある。ISP書込みなら、リセット端子をI/Oポートに設定したらそれまでだ。ISP書込みではリセット端子を操作するのだから、それができぬ設定にしては旨くない。また、ISP書込みにはクロックの供給は必須だ。内部クロックをやめ外付け水晶発振子や外部クロックにするならそれに合わせることだ。クロックがないとAVRマイコンは無反応になってしまう。

 ヒューズビットは沢山あって細かく見るのも大変だ。しかし、よく使うのはヒューズビットLowだろう。実際それだけで困ることはほとんど無い。以下で、ATmaga8をテーマにヒューズビットLowのポイントをメモしておく。

ヒューズLowバイトの機能
 ヒューズビットは1バイト(=8bit)単位で操作する。HighバイトとLowバイトの2バイトがあり、そのうち「下位側」と称する方を良く操作する。 これはAVRマイコンが動作するクロックをLowバイト側で決めているからだ。

 また、AVRが正常に起動(スタートアップ)するまでの待ち時間もここで設定する。

 ほかに、あまり使うことはないのだがATmega8では電源電圧の低下を検出する「Brown out検出」の設定もLowバイトに含まれている。しかし必要が無ければそのままにしておけば良い。

 結局ヒューズLowバイトでは主にクロックの選択とスタートアップに関する部分がポイントだ。

ATmega8のクロック
 ATmega8の動作クロックは様々な方式から選択できる。

1・外付け水晶発振子あるいはセラミック発振子
 所定の端子に水晶発振子(クリスタル)あるいはセラロックのような発振子を接続してクロックを得る方法。一般に数MHzの周波数のものを使う。保証上限周波数はATmega8では16MHzで、最近のチップでは20MHzになっている。発振子の周波数や種類に応じ、ヒューズLowバイトの下位4bitを1111〜1010の種類で設定する。以下で詳しく説明。(クロックの周波数精度と安定性を要するとき使う)

2・特に低い周波数の水晶発振子
 同じ水晶発振子でも、特に低い周波数の発振子を外付けする方法。これは、時計用の32kHzのような周波数を言う。こうした低周波水晶発振子は数MHz〜の水晶と同条件では旨く発振できない。従って特別な設定が設けられている。ヒューズLowバイトの下位4bitを1001に設定する。(この設定はあまり使われないようだ)

3・外付けRCによる発振
 非常にラフな用途の場合、抵抗器RとコンデンサCの時定数でクロックを作ることができる。このあと説明する内蔵RC発振器では得られないクロック周波数にしたい時に使う。外付け水晶発振子やセラミック発振子より安価だが不安定だから周波数変動しても良いラフな用途に限る。ヒューズLowバイトの下位4bitを1000〜0101の種類で設定する。(一般にあまり使わない)

4・校正済み内部RC発振
 内蔵された抵抗器RとコンデンサCの時定数で発振させクロックを得る方法。外付け部品不要なので便利である。厳密な周波数精度を要しない用途に適する。発振周波数はチップ個々に補正されているので、RC発振器としては比較的正確である。ヒューズLowバイトの下位4bitを0100〜0001の種類で設定する。(外付け部品がいらないので最もよく使われる)

5・外部クロック
 AVR内蔵の発振回路では水晶発振とは言っても精度や安定度に限界がある。おおよそ±10〜50ppmの変動は見込むべきだ。安定なクロック周波数が必要なら、温度補償型水晶発振器(TCXO)などを外付けして供給すると良い。 あるいは動作に適した既存のクロックがあれば、それを供給することもできる。複数のマイコンの同期を取り易いと言うメリットもある。ヒューズLowバイトの下位4bitを0000に設定する。(周波数カウンタや高精度な時計などで使われる)

 この項目で注目すべきは、下の方の赤の下線部分だ。ATmega8は出荷時にヒューズLowバイトの下位4bitが0001に設定されており、スタートアップSUT(後述)は電源の立ち上がりがゆっくりであると言う設定になっている。(どう使ってもいちばん無難と思われる設定になっている訳だ)

校正済み内蔵RC発振
 いちばんよく使われるのは校正済み内部RC発振だ。外付け部品不要で、I/Oポートも2つ増やせるメリットがある。 ATmega8の内部RC発振器は8MHzで発振している。 周囲温度が25℃で電源電圧が5Vのとき±3%以内の周波数精度となっている。クロックの周波数精度・安定度が程々でよい用途には最適だ。

 内部RC発振器で得られるクロック周波数は1,2,4,8MHzの4種類だ。8MHzを源に整数分周して低い周波数を得ている。分周せずに8MHz、1/2分周で4MHz、1/4で2MHz、1/8で1MHzである。この分周数をヒューズビットで設定している。

この8MHzは周波数の「校正値」が「校正バイト」と言う場所に書き込まれている。工場出荷時に規定の精度範囲になる最適値が書き込まれる。 校正バイトの書き換えは可能だ。5V以外の電源電圧で使用する場合など、実条件で校正すれば周波数精度を上げることができる。しかし周囲温度の変化でも周波数変動はあるから、周波数精度・安定度を要するならセラミック発振子や水晶発振子を使うべきだ。

# 設定だが、ヒューズLowバイトの下位4bitを:
0001で1MHz(←これが出荷時設定)
0010で2MHz
0011で4MHz
0100で8MHz
・・・・の設定でクロック周波数が選べる。

ほか、スタートアップ・タイムをきめる2ビット:SUTは、もっとも安全な「10」が初期設定されている。特に必要性がなければ書き換える必要は無いと思う。

外付けRCによる発振
 図の様に外付けの抵抗器RとコンデンサCの時定数でクロック発振させる。クロック・タイミング(周波数)がデリケートに影響しない用途向けだ。

 クロック周波数fは、おおよそf=1/(3RC)で計算できる。 なお、Cの値は少なくとも22pFにすべきで、CKOPTと言うヒューズ・ビットの設定でAVR内蔵の36pFを使うこともできる。(注:CKOPTはヒューズHighバイトにあり)もちろん、この36pFにも誤差があるし、配線によるストレー容量もあるから、計算式通りにはならない。 また温度係数も補償されないからクロック周波数がアバウトで良い用途に限定される。使用例は見ないが、特別低いクロック周波数をRC発振で得たい場合にでも使うのだろうか?

 スタートアップタイムに関しては、上記の「校正済み内蔵RC発振」と同じである。

外付け水晶発振子による発振
 水晶発振子を使うと周波数(周期)精度が良く安定したクロックを得ることができる。 マイコンの動作クロックをもとに時計やタイマーのような、時間精度を要する用途には最適だ。
 また、外部信号の周期や周波数を計測するアプリケーションにも安定したクロックが必要になる。 なお、セラミック発振子も使えるが周波数安定度は水晶発振子より100倍くらい悪いので用途目的次第である。

 AVRマイコンのXTAL端子は、図の様にインバータを使った発振回路になっている。XTL1がインバータの入口側、XTL2が出口側である。XTL1とXTL2とGND間に接続するコンデンサ、C1とC2は水晶発振子あるいはセラミック発振子の周波数により異なる。 具体的には次項の表にあるが、数〜16MHzの一般的なケースではいずれも15pFか22pFを使えば良い。 なお、セラッミック発振子ではC1とC2をメーカー指定の値にすべきだ。

 内蔵水晶発振器には2つのモードがある。発振振幅を抑えたモードと、発振振幅が電源電圧いっぱいに振れる「Full rail-to-rail swing」がある。 不要輻射を抑えるには前者が、ノイズが多い環境で使うには後者が向いている。いずれにするかは、ヒューズHighバイトにある「CKOPT」の設定で変更できる。私は(デフォルトの)発振振幅を抑えたモードで使うことが多い。


水晶発振のヒューズビット設定
 使用する水晶発振子の周波数帯によって3種類の設定がある。 さらに、発振振幅の選定があるので全部で6種類の設定があることになる。

 多くの場合、数〜16MHzの水晶発振子を使うだろう。発振振幅を抑えたモード(=初期設定)で発振させるなら、CKOPT=1、CKSEL3..1=111で良い。 殆どの場合、これで良い筈だ。 なお、CKSEL0も1で使うケースが殆どのはずで、結局CKSEL3..0=1111と言うことになる。(次項を参照)

 別のAVRマイコンにクロックを供給する場合はCTOPT=0として、フルスイング発振させた方が安心だ。出力はXTL2端子側から取り出す。(注:ヒューズ・ビット:CKOPTはヒューズHighバイトにあり)

 C1とC2であるが、上項のように多くの場合15pFか22pFを付けておけば良いようだ。 セラミック発振子の場合、3端子型ならC1とC2は発振子に内蔵されているから外付け不要である。

 幾つか調べてみたが、2端子型のセラミック発振子も数MHzなら水晶発振子と同じ15pFか22pFで良いようだ。 但し1MHz以下ではもっと大きな容量が必要で、村田製作所のセラロック(R)では100pFが指定値である。たとえば455kHzのセラロックを使う場合などだ。

 アマチュアの用途なら「発振すればOK」であるが、製品に使うには電源電圧、周囲温度の変化のほか、マイコンのロットによるバラツキも検討しておかないと安心できない。

スタートアップ・タイム
 電源を加えてからクロックが安定し、内部が初期状態にリセットされ、初めてマイコンは正常に動作する。 従って、電源電圧が加えられ一定時間経過してからプログラムはスタートする。

 同様に、スリープやパワーダウンの状態から復帰する場合も暫くの待ち時間が必要だ。 どの程度の時間で起動するかはヒューズビットのスタートアップ・タイム・ビットで決定する。

 特別に短い起動を必要としなければ、十分な起動時間を取って、ゆっくりした起動の方が確実であろう。 また、マイコンに加わる電源電圧の起動特性も関係する。 一般の安定化電源では設定電圧に安定するまでに、数10〜数100mSの時間が必要だからSlowly rising powerを選択するべきだ。

 起動時間がクリチカルではない用途なら、セラミック発振子の場合で:CKSEL0=1、SUT1..0=00にする。水晶発振子の場合で:CKSEL0=1、SUT1..0=11でも良いと思う。

 注釈が付いているが、パワーダウンあるいはパワーセーブ状態からの復帰で安定まで待つ(必要のある)クロック数は:セラミック振動子で258クロック、水晶発振で1,000クロックでも良い。但し、いずれも精度を要しない場合に限る。また上限に近いクロック周波数では推奨されないとある。 普通はもっと待つ方が良いのである。

 参考:セラミック発振子の待ちクロック数が少ないのは発振に要する起動時間が短いからだ。 Qが極めて高い水晶発振子は発振振幅が安定するまでに時間を要する。従ってやや長く待つ必要がある。

外部クロックの与え方
 外部からクロックを与える場合は、ヒューズビット:CKSEL3..0=0000とする。 また、信号はXTAL1端子に加えること。 与える信号の振幅は、ゼロから電源電圧までフルスイングする矩形波信号が良い筈で、Duty=50%に近いものが好ましい。

 負荷としては重くないので普通のC-MOSやPull-up抵抗付きのLS-TTLでドライブできる。 なお、TCXOほか、缶入り水晶発振器の出力は、C結合になっていることがある。 その場合は電源電圧の半分に相当するバイアス電圧を掛けた方が良い。 特に発振振幅が不足気味のオシレータではバイアスを掛けないと動作が不安定になることがある。 ドライブするオシレータ側の事情によるが、10kΩ〜47kΩ程度の抵抗器を2本用意し、1本目:電源→XTAL1端子、2本目:XTAL1端子→GNDに接続してバイアスを掛ける。

 スタートアップ・タイムは、上記と同様に特別な事情が無ければ十分な時間待つ方が望ましく:SUT1..0=10の設定が望ましいと思う。 なお、SUT1..0=11は「将来用の予約」なので設定してはいけない。

Brown-out Detection
 停電と言うのはBlack-outであるが、Brown-outと言うのは電圧低下状態のことだ。 たとえば電池が減ってきて規定の電源電圧を下回ったら、通常の処理をやめて待機準備に入る必要があるかもしれない。

 Brown-out Detectionと言うのは、そうした電源電圧の低下を察知する機能のことだ。その機能をON/OFFすることができる。 通常はデフォルトのOFFのままで良いだろう。

 たまたまATmega8ではヒューズLowバイトに含まれているのでここで説明している。 おなじ28pin AVRでも、ATmega48〜ATmega328ではヒューズHighバイトに含まれている。 但し、機能は概ね同じなので、電圧低下処理が必要な機器なら詳細を読んで機能させる。 


ヒューズバイトの書き換え
 意味がわかれば恐れることもない。 意味もわからず無闇に書き換えようとするから、復帰不能な状態に設定してしまうのだ。

 外付け水晶発振子や外部クロックの状態に設定しただけなら、所定のクロックを与えれば大丈夫。 再びチップが応答するようになって再度書き換えできるようになる。 従って過度に怖がらなくても良い。

 もちろん、水晶発振子なりオシレータが手元に無いと困ってしまう。数MHzの良質な水晶発振子や出力波形確認済みのオシレータ・モジュールを用意しておくとかなり安心できる。

 図はhidspx-GUIの画面だ。今の場合Clock周波数を内蔵8MHzに変えたいだけだった。ヒューズLowバイトの下位4ビットを、「0100」にすれば良い。16進で言えば「4」にする。上位4ビットは無変更なので「1110」即ち「E」である。結局、初期値が「E1」だったものを「E4」にすれば良いのだ。

 もうわかったから上の方にある、ヒューズビットの窓に所定の設定をインプットし「Write」ボタンを押せば書き換え完了だ。 けして難しいものではない(だろうと思う)。

参考)ATmega48PA、ATmega88PA、ATmega168PA、ATmaga328PではヒューズLowバイトの初期値は「62」になっている。内部RC発振器の1MHzで動作しており、上記と同様8MHzのクロックにするには「E2」に書き換える。「E4ではない」ので注意を! 詳細はATmega48/88/168/328のマニュアルを参照。

                    −・・・−

後記
AVRマイコンの様々な機能のうち、内部の回路的な部分はユーザープログラムからでは操作できない。 (内部にある)スイッチに相当するものがヒューズビットだ。 その「スイッチ」で内蔵回路の接続を切り替える。 例えば内部のRC発振器を停止しクロック入力を足ピンに切り替えてやれば外部クロックで動作できる。 おおよそそうした切換えを行なうのがヒーズビット(ヒューズバイト)の役割だ。

 在庫品の活用が目的だったのだが、このBlogを書き始めて暫くしてATmega8はもう既に過去のデバイスであることに気付いた。 現行主流のATmega48〜328とはヒューズバイトのアサインが随分違うのだ。 新チップに対応すれば良かったのだが、もう大半書き終えていたのでそのまま行くことにした。 もしATmega48、88、168、328を使うなら、ここに書いたATmega8とは違うので注意を。クロックなど考え方は同じなので所定のビットを同様に設定してやれば大丈夫。

 ヒューズビット(バイト)は回路屋には理解し易いが、ソフト専門の人には難解かもしれない。 しかし恐れる必要はない。 機能は各チップで概ね同じだから少しマニュアルに目を通せば心配いらない。 それにヒューズとは言っても一回切ってしまったら修復(再接続)できない訳ではなく、(限度はあるが)普通の意味では何回でも書き替え自在だ。

以上、例によって自身の備忘用Blogなのであるが、こうやって書いてみると、やっぱりヒューズビットは面倒だなあ。(笑) de JA9TTT/1

(おわり)

6 件のコメント:

JG6DFK さんのコメント...

おはようございます。

私も「ヒューズビット=切ったら終わり」という印象が強いのですが、実際にはPICでも16F84の時代から可逆のようです。「切ったら終わり」はたぶんワンタイム版の名残なのでしょうが、いずれにせよこのタイプは一度書いたらもう使えません。Hi.

PICでもそうですが、高機能化に伴いConfiguration Registerの設定が複雑化して参ります。WDTのデフォルトがなぜかONなのにも参りますが、それより参るのは、ソースコード上で動作条件をどのような形で指定すればいいのかがマニュアルに明記されていないことです。

私はそれで悪戦苦闘し、結局Cのインクルードファイルを見てようやく理解できました。本当に不親切ですが、これはPICだけでしょうか。

TTT/hiro さんのコメント...

JG6DFK/1 児玉さん、おはようございます。

ちょっとコメントしにくい題材と思いましたが、さっそく有難うございます。
> 「ヒューズビット=切ったら終わり」という印象が・・
そう感じる人も多いと思いますね。大昔あったヒューズロムの名残なのでしょうか。ワンタイムマイコンも不可逆でしたしねえ・・・。

> マニュアルに明記されていないことです。
BASCOM-AVR任せなので良くは見ていませんが、AVRのマニュアルにも説明が難解な部分がありますね。全部は目を通せませんからトラブって初めて読むような状況です。hi

> これはPICだけでしょうか。
世の中のどのマイコンのマニュアルも不完全で不親切なようですね。 昨今の複雑な動きをするチップはどれでも厄介です。(笑)

JA6IRK@岩永 さんのコメント...

おはようございます。
そうですね! 当局の場合は、フューズと言えば切れたら、交換するしかないと言う印象があります。
従って、一度設定したら二度と変更できないと言うような!
当局の場合、AVRはBASCOMで始めましたので、マニュアル無しで比較的容易になじめました。と言っても、OSCの内部/外部切り替えとか、最近のチップのCLK1/8の解除とかしか使っていませんが(笑)
ここまで丁寧に、フューズビットの解説をされたものは、あまり無いのではないかと思います。
永久保存版でお願いします。
チップが進歩するたびに変わって行くのが難儀なのと、新しいH/Wの機能が追加されると、その機能を理解しないと設定できないのが、難儀です。

ところで、USBaspでの対応チップは何処までかご存知でしょうか?
ATMEGA382なども問題なく、書き込みできますか?
その時のBASCOMのバージョンは?
先日(だいぶ前ですが)、使おうとしたらチップ認識せず、HIDaspxに戻して用をたしてしまいました。
コメントで質問してすみません。

TTT/hiro さんのコメント...

JN3XBY 岩永さん、こんにちは。

コメント有難うございます。
> 切れたら、交換するしかないと言う印象が・・・
そうなんですよ。 名前が良くないですよね。(笑)

> 永久保存版でお願いします。
ヒューズビットの全てを網羅している訳ではなくて不完全なものですので・・。それに旧型のATmega8ですし・・。こんなものでも使えそうなら継続しましょう。hi

> USBaspでの対応チップは何処までか・・・
自分の持っているチップしか確認していませんので、対応範囲は良くわかりません。 ただ、状況によって認識されないケースもあるようなので、HIDaspxやSTK200互換ライタなどでカバーするケースもあります。

 面倒なので原因追及はしてませんが、BASCOMのバージョンによるのかも知れません。USBaspへの対応もいずれもっと安定になることを期待しています。(笑)

T.Takahashi JE6LVE/JP3AEL さんのコメント...

こんばんは

ちょっとAVR工作から離れていたり、新チップを使うとき、ヒューズビットの設定はおっくうですね。
設定を間違えるとFuseBitの書き換えすらできなくなりますし。
BASCOMやhidspx-GUIのように上位と下位を一緒に書き換えられると間違いも少ないのですが、
別々に書き込むタイプで数個AVRを使えなくしてしまいました。
2313なのでよかったですが(笑)

新チップ対応を考えると純正のAvrStudioとAVRUSBMKIIがあればとりあえずhexファイルは書き込めるかな。

TTT/hiro さんのコメント...

JE6LVE/3 高橋さん、おはようございます。

いつもコメント有難うございます。
> ヒューズビットの設定はおっくうですね。
変えずに済むとホントに気が楽ですねえ。一手間省けるって言う感じでしょうか。(笑)

> 純正のAvrStudioとAVRUSBMKIIがあれば・・・
やはり純正が良さそうですね。BASCOM-AVRは追い付いていないこともあるようです。BASCOMから離れてhexなら行けますね。まあ、そんな最新チップは使わない(手に入らない)ので支障はない感じです。hi hi