//********************************************************************** /* <タコメータ>  ■機能概要   車のエンジンの回転数を測定し、表示する。   シガーライターソケット(cigarette lighter socket)から、電源を取り   その電源に含まれるスパークノイズより回転数を求める。  ■表示内容   回転数   回転数(バー表示)   平均電圧   最大電圧   最小電圧  ■CONFIGの設定 ・LVP_OFF   ・MCLR_OFF   ・WDT_OFF   ・EXTCLK */ //********************************************************************** #define LED PORTA.F3 #define SW PORTA.F5 //********************************************************************** static unsigned int aveAd, maxAd, maxAdTmp, minAd, minAdTmp; static unsigned long tmpAd; static unsigned int cntAd; static unsigned int tachoCnt, tachoCntTmp; static unsigned char highCnt; static unsigned char lowCnt; static unsigned char secFlag; void interrupt() { static unsigned int ad; // 1msecの割り込み処理 if (PIR1.CCP1IF == 1) { PIR1.CCP1IF = 0; //アナログデータをA/D変換で取り込み累積する。 ad = Adc_Read(2); tmpAd += ad; cntAd++; //1秒毎に回転数、平均電圧、最大電圧、最小電圧を求める。 if (cntAd == 1000) { //平均電圧 aveAd = tmpAd / cntAd; tmpAd = 0; cntAd = 0; //最大電圧 maxAd = maxAdTmp; maxAdTmp = 0; //最小電圧 minAd = minAdTmp; minAdTmp = 1024; //回転数 tachoCnt = tachoCntTmp; tachoCntTmp = 0; secFlag = 1; //LEDのON/OFF LED = ~LED; } //今回取り込んだ電圧が平均電圧より高いかを判断する。 if (ad >= (aveAd + 10)) { highCnt++; lowCnt = 0; if (highCnt == 2) tachoCntTmp++; } //今回取り込んだ電圧が平均電圧より低いかを判断する。 if (ad <= (aveAd - 10)) { lowCnt++; highCnt = 0; if (lowCnt == 2) tachoCntTmp++; } //今回取り込んだ電圧が平均電圧とほぼ同等かを判断する。 if ((ad < (aveAd + 10)) && (ad > (aveAd - 10))) { highCnt = 0; lowCnt = 0; } //最大電圧を求める。 if (ad > maxAdTmp) maxAdTmp = ad; //最小電圧を求める。 if (ad < minAdTmp) minAdTmp = ad; } } //********************************************************************** void main() { static unsigned char buf[20], cnt; static unsigned int ad; // アナログの設定 ANSEL = 0b00000100; // 使用する。 // ポートの設定 TRISA = 0b10110100; TRISB = 0b00001111; OPTION_REG.F7 = 0; // PORTBをプルアップする。 // CCPの設定 PIE1.CCP1IE = 1; PIR1.CCP1IF = 0; CCP1CON = 0b00001011; CCPR1L = 0x88; // 0.001sec...(1÷20000000)*4*5000 CCPR1H = 0x13; // TIMER1の設定 PIE1.TMR1IE = 0; PIR1.TMR1IF = 0; TMR1L = 0; TMR1H = 0; T1CON.T1CKPS0 = 0; T1CON.T1CKPS1 = 0; T1CON.TMR1ON = 1; // 変数の初期化 TMR1L = 0; TMR1H = 0; // LCD(液晶モニタ)の初期化 Lcd_Custom_Config(&PORTB,4,5,6,7,&PORTA,1,0,6); Lcd_Custom_Cmd(LCD_CURSOR_OFF); Lcd_Custom_Out(1, 1, "TachoMeter V1"); Delay_ms(1000); Lcd_Custom_Cmd(LCD_CLEAR); // LED = 1; // LED off! aveAd = 0; maxAdTmp = 0; minAdTmp = 1024; tmpAd = 0; cntAd = 0; highCnt = 0; lowCnt = 0; secFlag = 0; tachoCnt = 0; tachoCntTmp = 0; // 割り込み(全体)の設定 INTCON.PEIE = 1; INTCON.GIE = 1; // while (aveAd == 0) ; // while(1) { // 1秒周期でデータを表示する。 if (secFlag == 1) { //回転数を表示する。 secFlag = 0; WordToStr(tachoCnt * 20, buf); Lcd_Custom_Out(1, 1, buf); Lcd_Custom_Out(1, 6, "rpm"); // if (SW == 0) { //最大、最小、平均を表示する。 WordToStr(maxAd * 5, buf); Lcd_Custom_Out(2, 1, buf); Lcd_Custom_Out(2, 6, "mV"); // WordToStr(minAd * 5, buf); Lcd_Custom_Out(2, 9, buf); Lcd_Custom_Out(2, 14, "mV"); // WordToStr(aveAd * 5, buf); Lcd_Custom_Out(1, 9, buf); Lcd_Custom_Out(1, 14, "mV"); } else { //回転数をバー表示する。 for (cnt = 0; cnt < 16; cnt++) { if (cnt < ((tachoCnt * 20) / 200)) Lcd_Custom_Chr(2, cnt + 1, 0xFF); else Lcd_Custom_Chr(2, cnt + 1, ' '); } // WordToStr((maxAd - minAd) * 5, buf); Lcd_Custom_Out(1, 9, buf); Lcd_Custom_Out(1, 14, "mV"); } } } } //**********************************************************************