液晶の表示が出来るようになったので、次はロータリーエンコーダとタクトスイッチの入力を処理するサンプルを作ってみた。
はじめ、キー入力があったときに割り込みを使って処理することを考えていた。
そのためには、入力変化割り込みを有効にする必要があるらしい。そのためのレジスタがCNxIEというものらしいのだが、このレジスタの設定方法がまったくわからない。リファレンスマニュアルを読んでも詳しい設定方法が書いてないし、サンプルを探したが、dsPIC、PIC24Fでは見当たらない。
何がわからないかというと、dsPIC33FJ32GP202のピン番号とChange Notification Registerのマッピングが一致しないのだ。チップ自体は28ピンで、このうち入力に使えないVddやVssなどを除くと21ピンが対象ピンとなる。この数は、CNレジスタの有効な数と一致する。しかし、このCNレジスタの番号がPORTA、PORTBの並びとはまったく異なるのだ。かといって、ほかにマッピングするためのレジスタは見当たらない。
さんざん考えた末、この割り込みを使う方法はあきらめて、タイマーで周期的にキー入力を見るというオーソドックスな方法に切り替えた。
このオーソドックスな方法、案外簡単ながら強力だなと思った。キー入力には必ずチャタリングが付きまとうものだが、周期的にスキャンするので、前回の値とを比較するだけでチャタリングが除去できてしまう。
ELMさんのテクニカルノートがとても参考になった。ここにはチャタリング対策やロータリーエンコーダの使い方などがC言語のプログラム付で解説されている。FreeRTOSへの実装にも、ほぼそのまま利用可能だ。
これで、OKだと思ってPICに書き込んで動かしてみたが、キーの2つは正常に動作するのだが、ほかがまったく反応しなかった。
これでまた少し悩んだ。
配線をチェックしたり、テスターでキー入力の変化がPICに届いているかなど調べた。問題なかった。
では、ソフト側の問題かと考えていたら、どうも、A/D変換用の入力ピンが認識していないことがわかってきた。マニュアルを読むと、AD1PCFGレジスタを設定しないと、TRISxレジスタで入力を指定した場合にPORTxの値が読み込めないとある。
さらにdsPIC30のマニュアルなども読んでみた。そうしたら、0でA/D、1でディジタルI/Oとなると書いてある。
ソースを修正して、AD1PCFG=0xFFFF;としてみたら、全てのキーとロータリーエンコーダの値がとれるようになった。ヤッター!
0 件のコメント:
コメントを投稿