ArduinoでAD9834DDSをコントロールする基本的なスケッチはできましたので、次はロータリーエンコーダーで周波数を変更できるようにし、LCDで周波数を表示するようにします。つまり、VFO化します。
ロータリーエンコーダーについては、既に実験を終わっています。記事はこちら
ロータリーエンコーダーの制御スケッチでは、Arduinoの割り込み機能を使っています。
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
・
・
ISR(PCINT2_vect){
}
の部分です。
この記述について、私が持っている唯一のArduinoの参考書「Arduinoをはじめよう」を調べましたが、分かりませんでした。
Web上でもArduinoの割り込みに関する記事は多くありません。いろいろ調べて、ようやく理解できました。
私と同じようにArduinoの割り込みで悩んでいる方のために、分かったことを記録しておきたいと思います。
まず、基本的なことですが、Arduino UNOは、AVRマイコンATmega328Pを使った小さなマイコンシステムであるということです。つまり、Arduino UNOの正体はATmega328Pなのです。
そこで、ATmega328Pの説明書を読むと、このマイコンにはたくさんの割り込みがあります。
優先順位(プライオリティ)の高い方から (最初の数字は割込ベクトル番号)
1 リセット
2 外部割込要求0
3 外部割込要求1
4 ピン変化割込要求0
5 ピン変化割込要求1
6 ピン変化割込要求2
7 ウォッチドックタイマ完了
8~11 タイマカウンタ2関係割込
12~14 タイマカウンタ1関係割込
15~17 タイマカウンタ0関係割込
以下省略
今回使うのはピン変化割込要求2です。これは、ピンの状態(電圧)が変化した時に割込要求を生じます。
この割込を有効にするのが
PCICR(Pin Change Interrupt Control Register)という内部レジスタです。このレジスタは、8ビットで、ビット0~2がPCI0~PCI2に対応します。
ここで、PCI0は、PCINT0~7に、 PCI1は、PCINT8~14、PCI2は、PCINT16~23に対応します。
ロータリーエンコーダは、PCINT18とPCINT19に接続しますので、PCI2を有効にします。
その記述が、 PCICR |= (1 << PCIE2); です。
次に、PCI2のグループのどのピンをモニタするかを記述しているのが、
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19); です。
PCMSK(Pin Change Enable Mask Register)は、0から2の3つあります。
なお、<<は左にシフトする演算で、それぞれのビットまで1を左にシフトして、PCICR、PCMSK2とORをとることにより、それぞれのビットを1にします。
PCICRとPCMSKレジスタの各ビットの内容です。
最後に
ISR(){
_}
は、Interrupt Service Routineで、割込を生じた時(今回は、PCINT18またはPCINT19ピンの状態に変化が生じた時)に、ここに書かれたスケッチが実行され、再び元のプログラムに戻ります。
sei();は割込全体を有効にする関数です。