ロータリエンコーダは、位相のずれたパルスを出力する事により回転変位をパルス変換する部品です。
マウスに使われているような「光学式」の物、接点でメカ的に作られた「摺動式」の物、相対的な値を
出す「インクリメンタル方式」、絶対的な位置を出す「アブソリュート方式」など種類は沢山あります。
今回は秋月で売っている\200 の、摺動式でインクリメンタル方式の物を使ってみます。
まずは、どんなパルスが出ていて、何をすれば良いか調べてみます。
同じように見えますが良く見ると、違いがわかります。
時計回りなら A相のパルスが立ち上がるのはB相がLowの時のみ。
反時計回りならA相のパルスが立ち上がるのはB相がHighの時のみ。
時計回りならA相のパルスが立ち下がるのはB相がHighの時のみ。
反時計回りならA相のパルスが立ち下がるのはB相がLowの時のみ。
パルスの立ち上がり、立ち下り時にもう片方の相がHighかLowかを調べれば回転方向が取得できます。
H8/3052はハードでロータリエンコーダに対応しているので以下のように、PA-0、PA-1に繋ぎます。
プルアップしているためパルスの論理が逆になりますが、ソフトで対応すれば良いので気にしません。
ちなみに、A相と B相を入れ替えて繋げば正しい論理になります。
ハードウェアでサポートしているためプログラムは短いです。
まずはI/Oの定義。本来は外部ファイルに全てのI/Oを定義したファイルを作りインクルードします。
MDF EQU 6 ; 位相計数モード STR2 EQU 2 ; カウンタスタート 2 TSTR EQU H'FFFF60 ; タイマスタートレジスタ(R/W) TMDR EQU H'FFFF62 ; タイマモードレジスタ(R/W) TCNT2 EQU H'FFFF7C ; W タイマ 2 カウンタ(R/W)
初期化処理。ITU2のカウンタをクリアし、位相計数モードにして、タイマのカウンタをスタートさせます。
;****************************************************************************** ; ロータリエンコーダの初期化 ; ; _RotEncInit ; 2004/12/21 : 初期バージョン完成 ; ; [書式] void RotEncInit(void) ; ; ; [IN] なし ; ; [OUT] なし ; ; [DED] R0 ;****************************************************************************** public _RotEncInit _RotEncInit: SUB.W R0,R0 ; カウンタクリア MOV.W R0,@TCNT2 BSET.B #MDF,@TMDR ; 位相計数モード BSET.B #STR2,@TSTR ; カウンタスタート 2 RTS
次にカウンタ値を取得するルーチン。カウンタ値を取得するだけです。
;****************************************************************************** ; ロータリエンコーダのステップ数取得 ; ; _RotEncCheck ; 2004/12/21 : 初期バージョン完成 ; ; [書式] int RotEncCheck(void) ; ; ; [IN] なし ; ; [OUT] int = ステップ数 ; ; [DED] なし ;****************************************************************************** public _RotEncCheck _RotEncCheck: MOV.W @TCNT2,R0 ; カウンタ値(ステップ数)取得 RTS
最後にカウンタ値を取得して、カウンタをクリアするルーチン。
;****************************************************************************** ; ロータリエンコーダのステップ数取得とクリア ; ; _RotEncRead ; 2004/12/21 : 初期バージョン完成 ; ; [書式] int RotEncRead(void) ; ; ; [IN] なし ; ; [OUT] int = ステップ数 ; ; [DED] E0 ;****************************************************************************** public _RotEncRead _RotEncRead: MOV.W @TCNT2,R0 ; カウンタ値(ステップ数)取得 SUB.W E0,E0 ; カウンタクリア MOV.W E0,@TCNT2 RTS
使い方は、まず初期化を行い、RotEncCheckでエンコーダがある程度回転するのを待ちます。
一定値に達したら、RotEncReadで読み出しとクリアを行い、なんらかの処理をします。
#include <stdio.h> extern void RotEncInit(void) ; // ロータリエンコーダの初期化 extern int RotEncCheck(void) ; // ロータリエンコーダのステップ数取得 extern int RotEncRead(void) ; // ロータリエンコーダのステップ数取得とクリア void main(void) { RotEncInit() ; // ロータリエンコーダの初期化 while(1) { if(abs(RotEncCheck()) > 10) { // ロータリエンコーダのステップ数取得 int step = RotEncRead() ; // ロータリエンコーダのステップ数取得とクリア // なんらかの処理 } } }