第 9 章 CAN 133
10.3 チュートリアル
10.3.1 万能カウンタ
環境図は下記になります。
ケーブル
オープンコレクタ出力
1A+(12V)
中継端子台
DC+12V
ロータリエンコーダ
GND VCC A相 B相
外部電源 + -ITC-N3620
1A- 1B- 1Z-1B+(12V) 1Z+(12V)
Z相
CN5
ケーブル
レベル出力 (DC+5V)
1A+(5V)
中継端子台
DC+5V
ロータリエンコーダ
VCC A相 B相 Z相
外部電源 + -ITC-N3620
1A- 1B- 1Z-1B+(5V) 1Z+(5V)
GND
CN5
Step1 プログラム作成
パルスカウントモード、平均周波数測定モード、周期測定モード、位相差幅測定モード、タイマモード、分周期モード、パ ルスジェネレータモードの7つの機能モードから選択して使用することが出来ます。
例えば、パルスカウントモードでの制御手順では、UcntSetPulseCountMode 関数で機能モード設定、UcntSetBaseClock
関数やUcntSetTriggerConfig関数でカウンタ設定を行います。
UcntStartCount関数でカウントを開始し、UcntReadCounter関数でカウント値の取得を行います。
エディタを起動し、下記に示すプログラムを入力して、ファイル名を「encoderpulsecount.c」として保存してください。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "ifucnt.h"
int main(int argc, char *argv[]) {
int i, nRet, nDevice;
int nChannel;
unsigned long dwChSel;
unsigned long dwCountMode;
unsigned long dwLoadMode;
unsigned long dwLatchMode;
unsigned long dwLoadData;
unsigned long dwCounter[4];
// デバイス番号 1 のデバイスを制御 nDevice = 1;
// デバイスをオープン nRet = UcntOpen(nDevice);
if (nRet != IFUCNT_ERROR_SUCCESS) { goto EXIT_CLOSE;
}
// パルスカウントモードに設定 nChannel = 1; // チャンネル1
dwCountMode = IFUCNT_COUNT_PHASE_1 | IFUCNT_DIR_NORMAL; // 位相差パルスカウントモード 1逓 倍, 通常方向(カウントアップ)
dwLoadMode = 0x10; // 同期エッジ dwLatchMode = 0x00; // ラッチ無効
nRet = UcntSetPulseCountMode(nDevice, nChannel, dwCountMode, dwLoadMode, dwLatchMode);
if (nRet != IFUCNT_ERROR_SUCCESS) {
// プリロードデータに 0 を設定 dwLoadData = 0;
nRet = UcntSetLoadData(nDevice, nChannel, dwLoadData);
if (nRet != IFUCNT_ERROR_SUCCESS) { goto EXIT_CLOSE;
}
// カウントを開始
dwChSel = 0x01 << (nChannel - 1);
nRet = UcntStartCount(nDevice, dwChSel, IFUCNT_CMD_START);
if (nRet != IFUCNT_ERROR_SUCCESS) { goto EXIT_CLOSE;
}
// カウント値を取得し、表示 for (i = 0; i < 1000; i++) {
nRet = UcntReadCounter(nDevice, dwChSel, &dwCounter[0]);
if (nRet != IFUCNT_ERROR_SUCCESS) { goto EXIT_CLOSE;
} else {
printf("[%d] %08lXh¥n", i, dwCounter[(nChannel - 1)]);
}
usleep(10 * 1000);
}
// カウントを停止
nRet = UcntStopCount(nDevice, dwChSel, IFUCNT_CMD_STOP);
if (nRet != IFUCNT_ERROR_SUCCESS) { goto EXIT_CLOSE;
}
EXIT_CLOSE:
// デバイスをクローズ UcntClose(nDevice);
if (nRet != IFUCNT_ERROR_SUCCESS) { exit(EXIT_FAILURE);
}
return 0;
}
Makefileの作成
下記ソースを「Makefile」という名前で、ソースファイルと同一のディレクトリに保存してください。
all: encoderpulsecount
encoderpulsecount: encoderpulsecount.o
$(CC) encoderpulsecount.o -o encoderpulsecount -lgpg6320u encoderpulsecount.o: encoderpulsecount.c
$(CC) -Wall -c encoderpulsecount.c -o encoderpulsecount.o clean:
rm -f *.o encoderpulsecount
Step2 コンパイル/実行
ソースコード・Makefileを保存したディレクトリに移動し、コマンドラインから下記コマンドを実行します。
下記コマンドを実行することでコンパイルを行う事が出来ます。
make
コンパイルが成功すると、オブジェクトファイル「encoderpulsecount.o」と実行ファイル「encoderpulsecount」が作られま す。
※ErrorやWarningが表示された場合はコードの記述に誤りがありますので内容を見直してください。
プログラムを実行するには、以下のコマンドを実行します。
./encoderpulsecount
正常に処理が終了すると下記が表示されます。
[0] 00000000h [1] 00000001h [2] 00000002h [3] 00000003h
…
[998] 000003E6h [999] 000003E7h
Step3 プログラムの解説
カウンタ製品を制御する前段階として、カウンタ製品をオープンするUcntOpen関数を呼び出しています。
以下に引数と対応を示します。
int UcntOpen(
int nDevice, /* デバイス番号 */
);
引数名 内 容
nDevice オープンするデバイス番号を指定します。
この引数を与えて関数を呼び出すと、ドライバは引数に適合するカウンタ製品を検索し、合致した製品がある場合 は、戻り値として0を返します。
プログラマは、このデバイス番号を使って以降のAPIの呼び出しを行います。
カウンタ製品を制御するためには、まずカウンタのモード設定を行ないます。
カウンタのモードには様々な種類があり、パルスカウントモード、平均周波数測定モード、周期測定モード、位相 差幅測定モード、タイマモード、分周器モード、パルスジェネレーターモードがあります。
これらの設定を行なうには、以下の関数を使用します。
カウンタモード 関数
パルスカウントモード UcntSetPulseCountMode関数 平均周波数測定モード UcntSetFreqAvgMode関数 周期測定モード UcntSetCycleMode関数 位相差幅測定モード UcntSetPhaseDiffMode関数 タイマモード UcntSetTimerMode関数 分周器モード UcntSetFreqDividerMode関数 パルスジェネレーターモード UcntSetPulseGeneratorMode関数
ここでは、パルスカウントモードの設定を行なうためのUcntSetPulseCountMode関数を使用します。
それぞれの引数で、設定を行なうチャンネル、カウンタモード、プリロードモード、ラッチモードを設定する事が出来 ます。
ここでは、設定を行なうチャンネルを1とし、位相差パルスカウント・1逓倍・通常方向(カウントアップ)、同期エッジ、
ラッチ無効に設定しています。
次にプリロードデータの設定を行ないます。設定を行なうには、UcntSetLoadData関数をしようします。
ここでは、設定するチャンネルを1とし、プリロードデータを0としています。
設定が終わると、カウンタを開始させます。カウンタを開始するには、UcntStartCount関数を使用します。開始するチャ ンネル、スタートモードを指定します。
開始するチャンネルは複数のチャンネルを一度に指定することができ、bit1~bit4にそれぞれCH1~CH4が割り当てら れています。
ここでは、カウントを開始するチャンネルを1のみとし、スタートモードをソフトスタートとしています。
UcntStartCount関数を 実行す る と 、 カ ウ ン ト が 開始さ れ ま す 。 現在の カ ウ ン ト 値を1件ご と に 取得す る に は 、 UcntReadCounter関数を使用します。UcntStartCount関数同様、取得するチャンネルは複数同時に指定することができ、
第3引数で渡された変数のポインタに結果を返します。
ここでは、for文を使用して、現在のカウント値をprintf関数を使用して、1000回表示しています。
接続したロータリエンコーダをまわすことで、カウントアップを行ないます。
カウントを停止するには、UcntStopCount関数を使用します。UcntStartCount関数同様、停止するチャンネルは複数同時 に指定することができます。
ここでは、チャンネル1を指定してカウント停止を行なっています。
最後にカウンタ製品の制御を終了するためには、UcntClose関数を用います。
オープンしたカウンタ製品は、使用後は必ずクローズしてください。
★UcntClose関数を呼ばないと、どうなるか?
UcntClose関数を呼び出さないと、カウンタ製品はオープンしたままの状態になります。
オープン状態なので、UcntOpen関数を呼び出した場合、エラーが返ります。
オープンしたら必ずクローズしてください。