喜び勇んでテストする。よしよし、3つの7セグLEDがデタラメながら点滅しはじめた。ここまで来たらあともう少しだ。このあと、HC595のスペックを勘違いするなど(ラッチとOEを間違える)、まともに動くまでえらい時間がかかったのだが、このあとの苦労の方がもっと大変だったので全部省略する。悪戦苦闘の末、3つの7セグLEDで現在温度(今のところ単なる補正前の3桁のADC値)を表示することに成功した。本当の泥沼はこれからだったのである。ロータリーエンコーダーの入力が2本だったとは(11/3/2011)7セグの表示が何とか動き始めたので、ブレッドボードで、ついでに温度設定までのテストをすることにした。出来上がってから頭を抱えるより、ブレッドボードでバグをつぶす方が楽である。ロータリーエンコーダーを持ち出して、スペックを調べ始める。ここでまた重大な誤りに気づいた。ロータリーエンコーダーの入力は1本ではないのである。押し込めたピンがまた足らないことになったのである。CR内蔵クロックにすれば、もう2本空くが、CRクロックは、UARTが9600bpsを超えるだけでも不安定になるので余り使いたくなかった。ここしか空きは残っていない。涙を飲んで、クリスタル発振からCR内蔵発振に切り替える。ロータリーエンコーダーの制御法を勉強する。調べたところでは、やはりChaNさんの方式が主流なようだ。2入力を2ビットとして記録し、前後4ビットのテーブルを比較して正転か逆転を判断する。オシロで波形を調べているうちに気がついた。どちらかのデータの立ち上がり(立下りでも同じ)で割り込みをかけ、そのときのもう一方の入力を調べれば、一発で正逆転が判断できることがわかった。割り込みなので、タイマーでサンプリングするより正確である。ウェブで調べたが、これを明記している記事は見つからない。チャートを確かめてもこれで出来る筈だ。意気揚々とコーディングに入る。ふーむ、回転は認識するが、正逆転しない。どちらをまわしても正転するか逆転するか一方向だけである。おかしい、オシロのデータはちゃんと正転と逆転では値が違うのに、入力ピンが1を認めない。常に0としか読まない。最初、元のXtalのピン(PB5)で入力を調べているのでこれが何かまずいのかと思い、別の空きピンに入力を移してみる(7セグLEDはまだ全部実装していない)が、同じ。入力ピンが動かなくなってしまった。INT0(PB6)などの割り込みピンは何の問題もなく動いているのにおかしい。Tiny861のバグ(だろう)に振り回されてふらふら(11/5/2011)とんでもないことになっている。Tiny861で入力ピンが0のまま読み取れない。PINポートをデータに取り込んで、表示させても0のままだ。考え付く限りの入力ピンの状態を調べるコードを入れてテストするが、がんとして入力は1にならない。残っている全部のピン入力が言うことを聞かない。受信割り込みや、外部割込みのINT0(PB6)は動いているというのに何故だろう。何かとても基本的なことを間違えているのかもしれない。頭の中が混乱してきた。いつものAVRのピン入力が突然動かなくなったのだ。PINとPORTでは今まで散々悩まされてきた。昔買った、AVRのリファレンス本まで取り出して、基本から読み直す。手がかりは得られない。おかしなことをしているわけではない。完全に暗礁に乗り上げた。なると、どうもハードを疑うしか考えられなくなった。そのものが生きているか、ピンの割り込みだけでも生きているのか調べてみることにした。いうよりこれくらいしか調べるところがなくなった。Tiny861のピンチェンジ割り込みは、すべて共通の割り込みエントリーである。今のプログラムは、UARTの受信割り込みに使っている。ここへテストピン(PA4)の割り込みが来ても識別できるようなコードを加え、UARTに影響がないようにする。ピンチェンジのテストをする。うーむ、テスト用のLEDがついて動いたようだが、本当にPA4の割り込みがどうかは確認できない。7セグLEDの数字はエンコーダーの動きに応じて、増えたり減ったりしている。直ったのだ!何ということだ。ピンチェンジ割り込みをenableにしないと、入力ピンが動かないとは。こんな話は今まで聞いたことがない。コードを減らして行って、「入力ピンにするには、グローバル割り込みマスクレジスターGIMSKでそのピンに対するピンチェンジ有効のビットを立てる必要がある」ということがわかった(出力は問題ない)。いやあ、これはバグだろう。ウェブで探してみるが、それらしい記事は見つからなかった。本家のデータシートにもERRATAの記述はない。昨日の夜からほぼ半日これにふりまわされた。わかってしまえば、回避は簡単である。Tiny861は、ピンチェンジ割り込みは2段階で設定する。GIMSKレジスターで範囲(PCINT8~11までは、ビットPCIE0に、PCINT0~7とPCINT12~15までは、PCIE1という変則な設定)で割り込みを可能にする。次に、個別のピンの割り込みは、さらにそれぞれのピンに応じてPCMSK0レジスターかPCMSK1レジスターにピン単位に設定する。ややこしいやり方である。2段階なので、ERRATAを回避するには、こちらの方を未設定にしておけば良い。これで割り込みは起きない。入力ピンは正常に動く。いずれにしても、これで6ヶの7セグLEDを想定どおり動かせる見通しが立った。このあと、ADコンバーターの設定でPA3がおかしかったり(AREFを使う設定が、レジスター2つにまたがっている!)、ステートメントのコピーミスで同じ数字を2箇所に出したりするようなトラブルはあったが、とにかく無事にブレッドボード上で、6個の7セグLEDが点って、それぞれ動くところまで来た。やれやれ、これで一安心である。このあたりでブログに報告することにしよう。いやあ、今度もドラマの連続だったなあ。