====== ミニ周波数カウンタ(kHz表示) ====== ===== 概要 ===== 通常、1個のPICで、周波数カウンタを製作する場合、測定した結果は、LCDに表示したり、パソコンへRS232Cでデータ転送したりします。7セグメントのLEDを使って、ダイナミック点灯させる事例は、あまり見かけません。 その理由は、測定周期と表示周期が * 周波数カウンタの測定周期→1秒、0.1秒 * ダイナミック点灯の表示周期→5msec~1msec というふうに、異なり共存が難しいためです。 今回は、この問題点を解決し、次のような仕様の周波数カウンタを製作します。 <仕様> * ゲートタイムは0.1秒とする。表示はkHz単位とする。 * 測定範囲は、1kHz~15MHzまでとする。 * 1kHz~9999kHzまでは、4桁のkHz表示とする。 * 10MHz以上は、2桁のMHz+2桁のkHz表示とする。(例。12.34MHz) * スイッチ切り替えで、-455kHzの設定を可能とする。(ラジオ受信周波数表示用) ===== 動作原理 ===== 周波数カウンタの測定周期の1秒や0.1秒は、5msecの200倍または20倍に相当するので、測定周期と表示周期を、共通のタイマー割り込みで処理させることが出来そうです。 つまり、 * 5msec周期のタイマー割り込みを発生させる。 * 割り込み処理では、7セグメント(4桁)のLEDをダイナミック点灯させる。 * 割り込み処理では、0.1秒(5msec×20回)間の、周波数をカウントする。 {{:imgpaste:202004:htmikan-20200430-094658.png}} ===== 回路図 ===== 通常、ダイナミック点灯をさせる場合、7セグメントLEDへの供給電圧の制御は、トランジスタ等を使用します。 そして輝度を得るために、セグメントに接続する抵抗も、小さめの値(100Ω前後)にします。 今回は、PICのポート直としました。そのため、ポートの最大電流を考慮し、1KΩと大きめの値にします。 {{:imgpaste:202004:htmikan-20200430-094723.png}} |<100px>| ^ ポート ^ 7SEG ^ | PORTB(0) | G | | PORTB(1) | A | | PORTB(2) | F | | PORTB(3) | B | | PORTB(4) | C | | PORTB(5) | dp | | PORTB(6) | dp | | PORTB(7) | E | ===== ソースコード ===== //********************************************************************** /*   <ミニ周波数カウンタ(kHz表示)> */ //********************************************************************** #define DATA0 0b00100001 #define DATA1 0b11100111 #define DATA2 0b00110100 #define DATA3 0b10100100 #define DATA4 0b11100010 #define DATA5 0b10101000 #define DATA6 0b00101000 #define DATA7 0b11100001 #define DATA8 0b00100000 #define DATA9 0b10100000 #define DATA_SPACE 0b11111111 #define SPACE 10 #define NON_SEG 0b00000000 #define SEG1 PORTA.F6 #define SEG2 PORTA.F0 #define SEG3 PORTA.F1 #define SEG4 PORTA.F2 #define ON 1 #define OFF 0 //********************************************************************** short seg_flg, data1, data2, data3, data4, dot; short tbl[11] = {DATA0, DATA1, DATA2, DATA3, DATA4, DATA5, DATA6, DATA7, DATA8, DATA9, DATA_SPACE}; short fc_flg; void interrupt() { if (PIR1.CCP1IF == 1) { PIR1.CCP1IF = 0; //周波数カウンタ処理 switch (fc_flg) { case -1: break; case 0: TRISA.F4 = 1; //ゲートを開ける。 fc_flg++; break; case 20: TRISA.F4 = 0; // ゲートを閉める。 PORTA.F4 = 0; fc_flg = -1; break; default: fc_flg++; break; } //7SEG(4桁)点灯処理 switch (seg_flg) { case 0: seg_flg = 1; SEG4 = OFF; PORTB = (dot == 1) ? tbl[data1] & 0b11011111 : tbl[data1]; SEG1 = ON; break; case 1: seg_flg = 2; SEG1 = OFF; PORTB = (dot == 2) ? tbl[data2] & 0b11011111 : tbl[data2]; SEG2 = ON; break; case 2: seg_flg = 3; SEG2 = OFF; PORTB = (dot == 3) ? tbl[data3] & 0b11011111 : tbl[data3]; SEG3 = ON; break; case 3: seg_flg = 0; SEG3 = OFF; PORTB = (dot == 4) ? tbl[data4] & 0b11011111 : tbl[data4]; SEG4 = ON; break; } } } //********************************************************************** unsigned long FreqMeasurement() { unsigned long freq; // TRISA.F4 = 0; //ゲートを閉める。 PORTA.F4 = 0; INTCON.T0IF = 0; TMR0 = 0; freq = 0; // fc_flg = 0; //測定開始 // 測定 while (fc_flg != -1) { if (INTCON.T0IF == 1) { INTCON.T0IF = 0; freq++; } } if (INTCON.T0IF == 1) { INTCON.T0IF = 0; freq++; } freq = ((freq * 256) + TMR0) * 8 * 10; return (freq); } //********************************************************************** void main() { static char buf[16]; static long freq, tmp; // TRISA = 0b00100000; TRISB = 0b00000000; // OSCCON = 0b01110000; // クロックを8Mhzに設定する。 ANSEL = 0b00000000; // A/D変換は使用しない。 // TIMER0の設定 OPTION_REG.T0CS = 1; OPTION_REG.PSA = 0; OPTION_REG.PS2 = 0; OPTION_REG.PS1 = 1; OPTION_REG.PS0 = 0; // TIMER1の設定 PIE1.TMR1IE = 0; PIR1.TMR1IF = 0; T1CON.T1CKPS0 = 1; T1CON.T1CKPS1 = 1; T1CON.TMR1ON = 0; TMR1L = 0; TMR1H = 0; // CCPの設定 PIE1.CCP1IE = 1; PIR1.CCP1IF = 0; CCP1CON.CCP1M3 = 1; CCP1CON.CCP1M2 = 0; CCP1CON.CCP1M1 = 1; CCP1CON.CCP1M0 = 1; CCPR1L = 0xE2; // 5msec...(1÷8000000)*4*8*1250 CCPR1H = 0x04; // // SEG1 = OFF; SEG2 = OFF; SEG3 = OFF; SEG4 = OFF; seg_flg = 0; data1 = SPACE; data2 = SPACE; data3 = SPACE; data4 = SPACE; dot = 0; fc_flg = -1; // 割り込みを許可する。 INTCON.PEIE = 1; INTCON.GIE = 1; // T1CON.TMR1ON = 1; // while (1) { //測定 freq = FreqMeasurement(); tmp = freq / 1000; //kHz未満四捨五入 if ((freq - (tmp * 1000)) >= 500) tmp++; //-455kHz有無 if (PORTA.F5 == 0) tmp = tmp - 455; //表示 LongToStr(tmp, buf); if (tmp < 10000) { dot = 0; data1 = buf[7] == ' ' ? SPACE : buf[7] - '0'; data2 = buf[8] == ' ' ? SPACE : buf[8] - '0'; data3 = buf[9] == ' ' ? SPACE : buf[9] - '0'; data4 = buf[10] == ' ' ? SPACE : buf[10] - '0'; } else { dot = 2; data1 = buf[6] == ' ' ? SPACE : buf[6] - '0'; data2 = buf[7] == ' ' ? SPACE : buf[7] - '0'; data3 = buf[8] == ' ' ? SPACE : buf[8] - '0'; data4 = buf[9] == ' ' ? SPACE : buf[9] - '0'; } Delay_ms(500); } } //********************************************************************** ===== 動作確認 ===== いつものブレッドボードで動作確認しましたが、基板に実装すれば、かなりコンパクトになると思います。 {{:imgpaste:202004:htmikan-20200430-095031.png?500}} {{:imgpaste:202004:htmikan-20200430-095042.png}}{{:imgpaste:202004:htmikan-20200430-095113.png}} 左側から、100kHz、500kHz、1MHz、2MHz {{:imgpaste:202004:htmikan-20200430-095119.png}}{{:imgpaste:202004:htmikan-20200430-095122.png}}{{:imgpaste:202004:htmikan-20200430-095125.png}}{{:imgpaste:202004:htmikan-20200430-095129.png}} 左側から、3MHz、4MHz、5MHz、6MHz {{:imgpaste:202004:htmikan-20200430-095135.png}}{{:imgpaste:202004:htmikan-20200430-095138.png}}{{:imgpaste:202004:htmikan-20200430-095141.png}}{{:imgpaste:202004:htmikan-20200430-095144.png}} 左側から、7MHz、8MHz、9MHz、10MHz {{:imgpaste:202004:htmikan-20200430-095149.png}}{{:imgpaste:202004:htmikan-20200430-095152.png}}{{:imgpaste:202004:htmikan-20200430-095156.png}}{{:imgpaste:202004:htmikan-20200430-095159.png}} 左側から、11MHz、12MHz、13MHz、14MHz {{:imgpaste:202004:htmikan-20200430-095205.png}}{{:imgpaste:202004:htmikan-20200430-095208.png}}{{:imgpaste:202004:htmikan-20200430-095212.png}}{{:imgpaste:202004:htmikan-20200430-095217.png}} 左側から、15MHz、16MHz(若干、精度が悪くなります) {{:imgpaste:202004:htmikan-20200430-095222.png}}{{:imgpaste:202004:htmikan-20200430-095226.png}} 左側:通常表示 右側:-455kHz表示 {{:imgpaste:202004:htmikan-20200430-095232.png}}{{:imgpaste:202004:htmikan-20200430-095236.png}} 如何ですか? これを自作ラジオに取り付ければ、受信周波数を直読することが簡単に出来ますね。 ^_^ ※外付けの8MHzクリスタルオシレータを省いて、PIC内臓の8MHzクロックを使用することにより、精度は少し悪くなりますが、とてもコンパクトな、周波数カウンタを実現することが出来ます。 このページは稲崎様の閉鎖したHPのコピーで、著作権は稲崎様にあります。[[elechobby:picdic:picdic|詳細]] This page is a copy of Mr. Inasaki's closed website, and the copyright is held by him.[[elechobby:picdic:picdic|Details]]