PICの基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
ロータリ エンコーダを使う

マイコンの設定値を連続的に変化させるには、Push SWやボリュームを使うよりロータリーエンコーダを使用した方が操作性が向上します。 ロータリーエンコーダには、2つのSWが組み込まれており、ノブを回すことでそのSWが交互にOn/Offします。 具体的なタイミングは下図に示したように、A_pin の波形とB_pin の波形の位相が90°ずれて出力され、そのずれ方で回転方向を知ることができます。
 プログラムでは、前回のモニター結果と、今回のモニター結果を組み合わせてノブの回転方向を見極めています。このため、もし、チャタリングが発生しても、時間の経過で出力が安定したときの最終的なカウント値は常に回転方向と一致した正しい結果が得られます。この方法を採用することで、プログラミングが大変にシンプルになりました。

<ロータリーエンコーダ製品例>

プログラム例

基本的な使用例として、ロータリーエンコーダの回転で、4つのLEDに表示される2進数を増減させるプログラムを示します。

//  File name: Rotary Encorder
//  Description:
//  ロータリーエンコーの回転に対応した
//  値を4ヶのLEDで表示する。
//  Notes: 4MHz内部クロック
//        LED  RC0-3
//        Rotary Encorder
//             RB4,RB5
//    Language: MPLAB xc8
//    Target: PIC18F14K50

#include < xc.h>
#define _XTAL_FREQ 4000000      // delay_ms(x) のための定義

#define  LED         LATC
#define  A_pin       PORTBbits.RB5
#define  B_pin       PORTBbits.RB4

//-- コンフィグレーション --------
#pragma config MCLRE  = OFF, PWRTEN = OFF, BOREN  = OFF, BORV  = 30
#pragma config WDTEN  = OFF, WDTPS  = 32768, STVREN = ON, FOSC = IRC
#pragma config PLLEN  = ON,  CPUDIV = NOCLKDIV, USBDIV = OFF
#pragma config FCMEN  = OFF, IESO   = OFF, HFOFST = OFF, LVP   = OFF
#pragma config XINST  = OFF, BBSIZ  = OFF, CP0    = OFF
#pragma config CP1    = OFF, CPB    = OFF, WRT0   = OFF
#pragma config WRT1   = OFF, WRTB   = OFF, WRTC   = OFF
#pragma config EBTR0  = OFF, EBTR1  = OFF, EBTRB  = OFF

//-------プロトタイプ--------------------------------------------------
char readRE(void);

#pragma code

void main(void){
    char count = 0;
    OSCCON = 0b01010010;      // 内部クロック4Mhz
    PORTC = 0;
    TRISB = 0xF0;             // PortB 入力
    TRISC = 0xF0;             // PortC RC0-3出力
    ANSEL  = 0;               // デジタル入力
    ANSELH = 0;
    INTCON2bits.RABPU = 0;    // RA/RB WeekPullUpをONに設定
    while(1){                 // 繰り返しループ
        count += readRE();    // 変化分を加算する
//      LED = count >> 2;     // 1ノッチで4カウント進むタイプ
        LED = count;          // ノッチのないタイプ
    }                         // ここまで繰り返し
}

//------------------ readRE ------------------------------
// 直前の状況と今回の状況を合わせた16通りの組合せから
// 左右どちらに回転をしたのか判定することができる
// 戻り値は (-1,0,1) の3通り
//--------------------------------------------------------
char readRE(void){
  static char RE_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
  static char RE_old = 0;               // 共通変数(値は保存)
  char RE_now;
  RE_now = B_pin * 2 + A_pin;           // 今回情報の読取
  RE_old <<= 2;                         // 前回の読取値と
  RE_old |= ( RE_now & 0x03 );          // 今回の読取値を組合わせる
  return (RE_states[(RE_old & 0x0F)]);  // 変化分を戻り値をする
}