====== 周波数カウンタV6(16ビットPIC採用)(PIC24FJ64GA002) ======
===== 概要 =====
今までは、8ビットのPICで製作をしてきましたが、今回は16ビットのPICで周波数カウンタを製作してみました。
{{:imgpaste:202004:admin-20200430-182300.png?500}}
{{:imgpaste:202004:admin-20200430-182309.png}}
===== 動作原理 =====
ゲートタイマ(1秒用、0.1秒用)には、TIMER1(16ビット)を使用しました。
クロック周波数が32MHz、プリスケーラ値が256なので、TIMER1への設定値は次の式で求めます。
0xBDC = 65536 - (1 / ((1 / (32MHz / 2)) * 256))
{{:imgpaste:202004:admin-20200430-182331.png?500}}
入力される信号のカウント用には、TIMER2とTIMER3を結合した、32ビットのカウンタを使用します。
従って、論理上は、4,294,967,296Hzまでのカウントが可能となります。
これでソフトウエアの仕組みも簡単になりました。
{{:imgpaste:202004:admin-20200430-182413.png?500}}
TIMER2は単体では、16ビットのタイマとして動作します。
{{:imgpaste:202004:admin-20200430-182421.png?500}}
TIMER3は単体では、16ビットのタイマとして動作します。
{{:imgpaste:202004:admin-20200430-182431.png?500}}
===== 回路図 =====
動作確認は、図1と図2で実施しました。
実用(感度、インピーダンス等)を考慮するのであれば、図2の箇所を図3のアンプに置き換えてください。
SW1で、プリスケーラの値を、1/1、1/8の切替を可能としました。
{{:imgpaste:202004:admin-20200430-182514.png}}
※注意事項
PIC24FJ64GA002の電源電圧は、規格では2.0V~3.6Vなのですが、今回は無理させて5.0Vを加えて
います。実用的な回路にするには、もう少し工夫が必要です。
===== ソースコード =====
//**********************************************************************
/*
「周波数カウンタ」
<DeviceFlags>
_IESO_OFF
_FNOSC_PRI
_FCKSM_CSDCMD
_OSCIOFNC_OFF
_POSCMOD_EC
_JTAGEN_OFF
_GCP_OFF
_GWRP_OFF
_BKBUG_OFF
_COE_OFF
_ICS_PGx1
_FWDTEN_OFF
*/
//**********************************************************************
#define LED PORTA.F0
//**********************************************************************
void Timer1Int() org 0x1A
{
Delay_Cyc(0, 215);
T1CON.F15 = 0;
T2CON.F15 = 0;
IFS0bits.T1IF = 0;
}
//**********************************************************************
void main()
{
unsigned long cnt;
char buf[20];
//
ADPCFG = 0xFFFF;
TRISA = 0b11111110;
TRISB = 0x0002;
// timer1(16bits) ゲートタイム制御
IPC0bits.T1IP0 = 1;
IFS0bits.T1IF = 0;
IEC0bits.T1IE = 1;
T1CONbits.TCKPS0 = 1;
T1CONbits.TCKPS1 = 1;
T1CON.F15 = 0;
// timer2+3(32bits) 周波数カウント制御
IPC2bits.T3IP0 = 1;
IFS0bits.T3IF = 0;
IEC0bits.T3IE = 0;
T2CONbits.TCKPS0 = 0;
T2CONbits.TCKPS1 = 0;
T2CONbits.T32 = 1;
T2CONbits.TCS = 1;
T2CON.F15 = 0;
//
Lcd_Custom_Config(&PORTB, 6, 7, 8, 9, &PORTB, 12, 11, 10);
Lcd_Custom_Cmd(LCD_CURSOR_OFF);
Lcd_Custom_Out(1, 1, "FreqCounter V6");
//
RPINR3bits.T2CKR0 = 1;
RPINR3bits.T2CKR1 = 0;
RPINR3bits.T2CKR2 = 0;
RPINR3bits.T2CKR3 = 0;
RPINR3bits.T2CKR4 = 0;
//
while(1) {
if (PORTA.F1 == 1)
T2CONbits.TCKPS0 = 0; // 1/1
else
T2CONbits.TCKPS0 = 1; // 1/8
//
TMR1 = 0xBDC; // 65536 - (1 / ((1 / 16MHz) * 256))
TMR2 = 0;
TMR3 = 0;
T1CON.F15 = 1;
T2CON.F15 = 1;
//
LED = 0;
while (T1CON.F15 == 1)
;
LED = 1;
//
cnt = TMR3;
cnt = cnt << 16;
cnt = cnt | TMR2;
if (PORTA.F1 != 1)
cnt *= 8;
//
LongWordToStr(cnt, buf);
Lcd_Custom_Out(2, 1, buf);
Lcd_Custom_Out(2, 11, "Hz");
//
Delay_ms(500);
}
}
//**********************************************************************
===== 動作確認 =====
{{:imgpaste:202004:admin-20200430-182642.png?500}}
手持ちの水晶発信器でいろいろと試してみました。
{{:imgpaste:202004:admin-20200430-182658.png}}{{:imgpaste:202004:admin-20200430-182702.png}}
左側:60MHz(プリスケーラ値は1/8です)
右側:40MHz(プリスケーラ値は1/8です)
{{:imgpaste:202004:admin-20200430-182727.png}}{{:imgpaste:202004:admin-20200430-182738.png}}
左側:32MHz(プリスケーラ値は1/8です)
右側:20MHz(プリスケーラ値は1/8です)
{{:imgpaste:202004:admin-20200430-182745.png}}{{:imgpaste:202004:admin-20200430-182749.png}}
左側:12MHz(プリスケーラ値は1/8です)
右側:6MHz(プリスケーラ値は1/1です)
{{:imgpaste:202004:admin-20200430-182755.png}}{{:imgpaste:202004:admin-20200430-182814.png}}
如何ですか?
こんな簡単な回路で60MHzまでを測定できるんですねえ。。。 ^_^
このページは稲崎様の閉鎖した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]]