
以前、PICを使った、エンジン回転数検出の回路を公開しましたが、エンジンの回転数検出が簡単にできるようになると、色々、おもちゃを作成することができるようになります。
【例】
・VTEC切り替えを任意の回転数に。
・設定した回転数(レブリミッター)で、赤のLEDを点灯させ、ブザーを鳴らす。
・その他
レシプロカル方式(パルスの2点間の時間をカウンターを回して、何パルスかかったかで、時間を得る)に関しての具体的プログラム ソースが、なかなか、見当たらなかったので、今回、公開してみることにします。
私は、基本的に、出し惜しみしないタイプです。
皆さんに、電子(電気)工作に興味をもって頂ければ、幸いです。
以下、 /* からが、ソースになりますが、ソースをコピーし、貼り付けしましたが、スペースが、ぐちゃぐちゃで、見辛くなってしまったことは、ご容赦願いたいと思います。
/*
Hard ware Pin assignment list
1 VDD
2 GP5 O(not use)
3 GP4 O(not use)
4 GP3 O(not use)
5 GP2 I(IG PULSE IN)
6 GP1 O(L=0-3,600rpm : H=3,600rpm-9,000rpm)
7 GP0 O(not use)
8 VSS
VDD 4.5 to 5V P12F629
*/
/*MEMO
測定は、レシプロカル方式
1rpmは、 0.0166Hzで、IG_PULSEは、0.0333Hz=30sec
500rpmは、 8.33Hzで、IG_PULSEは、 16.66Hz=60.000mS=60,000uS
1,000rpmは、 16.67Hzで、IG_PULSEは、 33.33Hz=30.000mS=30,000uS
2,000rpmは、 33.33Hzで、IG_PULSEは、 66.66Hz=15.000mS=15,000uS
3,000rpmは、 50.00Hzで、IG_PULSEは、100.00Hz=10.000mS=10,000uS
3,500rpmは、 58.33Hzで、IG_PULSEは、116.66Hz= 8.571mS= 8,571uS(217B)
3,600rpmは、 60.00Hzで、IG_PULSEは、120.00Hz= 8.333mS= 8,333uS(208D)
3,900rpmは、 65.00Hzで、IG_PULSEは、130.00Hz= 7.692mS= 7,692uS(1E0C)
4,000rpmは、 66.66Hzで、IG_PULSEは、133.33Hz= 7.500mS= 7,500uS(1D4C)
4,500rpmは、 75.00Hzで、IG_PULSEは、150.00Hz= 6.666mS= 6,666uS
5,000rpmは、 83.33Hzで、IG_PULSEは、166.66Hz= 6.000mS= 6,000uS
6,000rpmは、 60.00Hzで、IG_PULSEは、120.00Hz= 5.000mS= 5,000uS
7,000rpmは、116.66Hzで、IG_PULSEは、233.33Hz= 4.285mS= 4,285uS
8,000rpmは、133.33Hzで、IG_PULSEは、266.66Hz= 3.750mS= 3,750uS
8,400rpmは、140.00Hzで、IG_PULSEは、280.00Hz= 3.571mS= 3,571uS
9,000rpmは、150.00Hzで、IG_PULSEは、300.00Hz= 3.333mS= 3,333uS
*/
#include
//定型文なので、変えない
__CONFIG(0x31C4); //内蔵OSC使用等
#define MHz 000000
#define _XTAL_FREQ 4MHz //Delay用 4MHz設定
unsigned char temp_h,temp_l;
unsigned int temp_all;
unsigned int mokuhyo;
//----------------------------------------------
// initPort
//----------------------------------------------
static void initPort(){
OSCCAL = _READ_OSCCAL_DATA(); //OSC出荷補正値で校正
GPIO = 0x00; //PORT設定をリセット
TRISIO = 0x0C; //GPIO2だけ、入力設定
WPU2 = 0;
GPPU = 1;
INTEDG = 1; //INT PIN EDGE立上り検出
T1CON = 0x00;
GPIO1 = 0; //GPIO1=L(IAB ON)
}
//----------------------------------------------
//main処理 --------------------------------------
//----------------------------------------------
void main(void){
initPort();
temp_all= 0xFFFF;
mokuhyo = 0x208D; //3,600rpm設定
while(1){
INTE = 1; //INTエッジ割り込み使用
GIE = 1; //割り込み許可
}
}
//----------------------------------------------
//エッジ割り込み処理 -------------------------------
//----------------------------------------------
static void interrupt intr(void){
INTF = 0;
TMR1L = 0;
TMR1H = 0;
TMR1IF = 0;
TMR1ON = 1; //TMR1 ON
while(INTF==0){
} //2つ目のエッジを待つ
TMR1ON = 0; //TMR1を止める
temp_h = TMR1H;
temp_l = TMR1L;
temp_all= (temp_h*0x0100)+temp_l;
if(TMR1IF){
temp_all= 0xFFFF; //TMR1オーバーフロー時固定
}
if(temp_all < mokuhyo){
GPIO1 = 1; //GPIO1=H(IAB OFF)
mokuhyo = 0x217B; //3,500rpmに目標修正
}
else{
GPIO1 = 0; //GPIO1=L(IAB ON)
mokuhyo = 0x208D; //3,600rpmに目標修正
}
GIE = 0; //割り込み禁止
INTF = 0; //エッジ検出しない
}
この上の } まで。
やっていることは、
・PIC P12F629(\80位)を使用。
・内部の4MHzを使用し、安く。(エンジンの回転数は遅いので、精度も充分です)
・内部4MHzを使うので、1/4の周波数で、PICのカウンターは動きます。つまり、1カウント=1MHz=1uSですので、3,600rpmを検出したい場合、上記計算で、8,333回(8,333uS)カウントしたことを検出すればいいので、16進数に直し、8,333(DEC)⇒208D(HEX)が目標値になります。
・タイマーは、TMR1(16bitカウンター)を使用。上位8bitと、下位8bitを扱いやすくするため、16bit値に直してます。これは、比較を容易にするためです。
・最後の方に、3,600rpmをまたいで、バルブがON-OFFを敏感に反応するので、3,600rpmを超えたら、3,500rpmを下回るまで、バルブを動作させない(ヒステリシス)動作をさせています。
MPLABの『MPLAB IDE v8.40』と、フリーで使える、『HI-TECH C Compilers』で上記ソースをそのまま、Buildすれば、即、使用可能です。(あとは、PICへの書き込み機が必要)
目的の用途に合わせて、回転数、PORT設定など修正すれば、色々な用途で使えますね。
回路図では、ECU内部に、仕込みましたが、当然、ICM信号(0-12V)を、インバータ(Tr)で受けて入力すれば、同じことができます。
尚、これを使用して、トラブルが発生しても、当方は一切、責任を負いません。
質問が有れば、答えられる範囲で答えます。
追記(2012.2.10)
上記ソースで、コンパイルエラーが、発生した場合の対処法。
HITEC CのVer.9.81までは、そのまま、コンパイル可能ですが、Ver.9.83では、エラーがでます。
その場合、2箇所を下記に差し替えてください。
OSCCAL = _READ_OSCCAL_DATA(); //OSC出荷補正値で校正
↓
OSCCAL;
GPPU = 1;
↓
nGPPU = 1;
OSCCALは、コマンド対応された。GPPU bitは、極性表記が必要になり、nGPPUに変わった。