/* <周波数カウンター>  ★コンパイル時にマクロを利用して機能を切り替えることが出来ます。  <FC_TYPE_A>    sw1:プリスケーラの切り替え      ・sw1=1 1/1      ・sw1=0 1/8    sw2:ゲートタイムの切り替え      ・sw2=1 1秒      ・sw2=0 0.1秒  <FC_TYPE_B>    sw1:-455kHzの有無切り替え      ・sw1=1 -455Khz      ・sw1=0 -0Khz    sw2:表示レンジの切り替え      ・sw2=1 Hz表示      ・sw2=0 kHz表示 */ //********************************************************************** #define FC_TYPE_A #define sw1 PORTB.F2 #define sw2 PORTB.F3 //********************************************************************** void interrupt() { if (PIR1.TMR1IF == 1) { PIR1.TMR1IF = 0; // TRISA.F4 = 0; // ゲートを閉める。 PORTA.F4 = 0; T1CON.TMR1ON = 0; // TIMER1を停止する。 } } //********************************************************************** unsigned long FreqMeasurement100msec() { unsigned long freq; // TRISA.F4 = 0; //ゲートを閉める。 PORTA.F4 = 0; // TIMER0の設定 INTCON.T0IF = 0; TMR0 = 0; // TIMER1の設定 TMR1L = 0xB0; TMR1H = 0x3C; // freq = 0; // 割り込みを許可する。 INTCON.PEIE = 1; INTCON.GIE = 1; // 開始 T1CON.TMR1ON = 1; // Delay_Cyc(2); asm nop; asm nop; asm nop; asm nop; asm nop; asm nop; asm nop; // TRISA.F4 = 1; //ゲートを開ける。 // 測定 while (T1CON.TMR1ON != 0) { if (INTCON.T0IF == 1) { INTCON.T0IF = 0; freq++; } } if (INTCON.T0IF == 1) { INTCON.T0IF = 0; freq++; } freq *= 256; freq += TMR0; return (freq); } //********************************************************************** void main() { static unsigned long freq, temp; // 0...4294967295 static unsigned char buf[12]; static unsigned short cnt, prescaler, gateTime; // アナログの設定 ANSEL = 0b00000000; // →今回は使用しない。 // ポートの設定 TRISA = 0b10111100; TRISB = 0b00001100; OPTION_REG.F7 = 0; // PORTBをプルアップ設定する。 // TIMER0の設定 INTCON.T0IE = 0; INTCON.T0IF = 0; OPTION_REG.T0CS = 1; OPTION_REG.T0SE = 0; #ifdef FC_TYPE_A OPTION_REG.PSA = 1; OPTION_REG.PS0 = 0; OPTION_REG.PS1 = 0; OPTION_REG.PS2 = 0; #endif #ifdef FC_TYPE_B OPTION_REG.PSA = 0; OPTION_REG.PS0 = 0; OPTION_REG.PS1 = 1; OPTION_REG.PS2 = 0; #endif // TIMER1の設定 PIE1.TMR1IE = 1; PIR1.TMR1IF = 0; T1CON.T1CKPS0 = 1; T1CON.T1CKPS1 = 1; T1CON.TMR1ON = 0; // #ifdef FC_TYPE_A prescaler = 1; gateTime = 10; #endif #ifdef FC_TYPE_B prescaler = 8; gateTime = 1; #endif // Lcd_Custom_Config(&PORTB,4,5,6,7,&PORTA,1,0,6); Lcd_Custom_Cmd(LCD_CURSOR_OFF); Lcd_Custom_Out(1, 1, "FreqCounterEx R1"); Delay_ms(1000); Lcd_Custom_Cmd(LCD_CLEAR); // while (1) { freq = 0; for (cnt = 0; cnt < gateTime; cnt++) { freq += FreqMeasurement100msec(); } // 補正 freq = freq * prescaler; freq = freq * (10 / gateTime); #ifdef FC_TYPE_B // -455kHzの有無 if (sw1 == 1) { freq -= 455000; Lcd_Custom_Out(2, 1, "[-455kHz][0.1s]"); } else { Lcd_Custom_Out(2, 1, " [0.1s]"); } // 表示レンジの切り替え if (sw2 == 1) { LongToStr(freq, buf); Lcd_Custom_Out(1, 1, &buf[3]); Lcd_Custom_Out(1, 9, "Hz [1/8]"); } else { temp = freq / 1000; if ((freq - (temp * 1000)) > 500) { temp++; } LongToStr(temp, buf); Lcd_Custom_Out(1, 1, &buf[3]); Lcd_Custom_Out(1, 9, "kHz[1/8]"); } #endif #ifdef FC_TYPE_A // 表示 LongToStr(freq, buf); Lcd_Custom_Out(1, 1, &buf[3]); Lcd_Custom_Out(1, 9, "Hz"); // プリスケーラの切り替え if (sw1 == 1) { OPTION_REG.PSA = 1; OPTION_REG.PS0 = 0; OPTION_REG.PS1 = 0; prescaler = 1; Lcd_Custom_Out(2, 1, "[1/1]"); } else { OPTION_REG.PSA = 0; OPTION_REG.PS0 = 0; OPTION_REG.PS1 = 1; prescaler = 8; Lcd_Custom_Out(2, 1, "[1/8]"); } // ゲートタイムの切り替え if (sw2 == 1) { gateTime = 10; Lcd_Custom_Out(2, 7, "[1sec] "); } else { gateTime = 1; Lcd_Custom_Out(2, 7, "[100msec]"); } #endif } } //**********************************************************************