====== 周波数カウンタV9(PIC18シリーズ最小)(PIC18F1320) ======
===== 概要 =====
PIC16Fシリーズには、16ビットのタイマーモジュールが、1個しかなく、また、タイマーの制御(ON/OFF)が貧弱なため、周波数カウンタのように、
* ゲートタイム用のタイマーモジュール(ON/OFF制御)
* 周波数カウント用のタイマーモジュール(ON/OFF制御)
を実現しようとすると、結構煩雑(意にそぐわない)な処理が必要となります。
PIC18Fシリーズでは、16ビットのタイマーモジュールが、2個に強化され、且つ、タイマーの制御(ON/OFF)も可能となり、周波数カウンタの実現には、とても便利になりました。
今回は、PIC18Fシリーズでは、最もピン数の少ない、PIC18F1320(18ピン)を使用し、出来るだけコンパクトに仕上げてみました。
<仕様>
* ゲートタイム切り替え(1秒/0.1秒)
* -455kHz切り替え(有/無)
* 表示切替(Hz/kHz)
* 測定範囲(10Hz~60MHz)
===== 動作原理 =====
<ゲートタイム>
ECCPモジュールとTIMER1を組み合わせ、コンペアモードで使用することにより、0.1秒の周期割り込みを発生させる。
割り込みを、フリーランさせることにより、測定の開始と完了の処理を単純化させる。
* 測定の開始(測定処理→割り込み処理へ指示)
* 測定の完了(割り込み処理処理→測定処理へ指示)
<周波数カウント>
TIMER3と32ビットの変数(freq)を組み合わせ、周波数をカウントする。TIMER3でオーバーフローが発生する都度に、freq変数をインクリメント(+1)する。測定完了後に次式により周波数を求める。
freq=(freq×65536)+(TMR3H×256)+TMR3L
===== 回路図 =====
{{:imgpaste:202004:admin-20200430-180358.png}}
===== ソースコード =====
//**********************************************************************
/*
<周波数カウンタV9>
*/
//**********************************************************************
#define LED PORTA.F0
#define GATE_TIME_1SEC 10
#define GATE_TIME_100MSEC 1
#define SW1 PORTA.F1
#define SW2 PORTA.F4
#define SW3 PORTA.F5
//**********************************************************************
short fc_flg, gateTime;
void interrupt()
{
if (PIR1.CCP1IF == 1) {
PIR1.CCP1IF = 0;
//
//周波数カウンタ処理
switch (fc_flg) {
case -1:
break;
case 0:
T3CON.TMR3ON = 1; //ゲートを開ける。
fc_flg++;
LED = 1;
break;
default:
if (gateTime == fc_flg) {
T3CON.TMR3ON = 0; //ゲートを閉める。
fc_flg = -1;
LED = 0;
} else {
fc_flg++;
}
break;
}
}
}
//**********************************************************************
unsigned long FreqMeasurement()
{
static unsigned long freq;
//
T3CON.TMR3ON = 0; //ゲートを閉める。
PIR2.TMR3IF = 0;
TMR3L = 0;
TMR3H = 0;
freq = 0;
//
fc_flg = 0; //測定開始
// 測定
while (fc_flg != -1) {
if (PIR2.TMR3IF == 1) {
PIR2.TMR3IF = 0;
freq++;
}
}
if (PIR2.TMR3IF == 1) {
PIR2.TMR3IF = 0;
freq++;
}
freq = (freq * 65536) + (unsigned long)((TMR3H << 8) | TMR3L);
return (freq);
}
//**********************************************************************
void main()
{
static unsigned char buf[20], cnt;
static unsigned long freq, temp;
//
// OSCCON.IRCF2 = 1;
// OSCCON.IRCF1 = 1;
// OSCCON.IRCF0 = 1;
ADCON1 = 0b11111111;
TRISA = 0b11111110;
TRISB = 0b01000000;
//TIMER3の設定
PIE2.TMR3IE = 0;
PIR2.TMR3IF = 0;
T3CON.RD16 = 0;
T3CON.T3CKPS0 = 0;
T3CON.T3CKPS1 = 0;
T3CON.T3CCP1 = 0;
T3CON.NOT_T3SYNC = 1;
T3CON.TMR3CS = 1;
T3CON.TMR3ON = 0;
TMR3L = 0;
TMR3H = 0;
//TIMER1の設定
PIE1.TMR1IE = 0;
PIR1.TMR1IF = 0;
T1CON.T1CKPS0 = 1;
T1CON.T1CKPS1 = 1;
T1CON.NOT_T3SYNC = 1;
T1CON.TMR1CS = 0;
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 = 0xA8; // 0.1sec...(1÷8000000)*4*8*25000
CCPR1H = 0x61; //
//LCDの設定
Lcd_Custom_Config(&PORTB,0,1,3,2,&PORTB,4,5,7);
Lcd_Custom_Cmd(Lcd_CURSOR_OFF);
Lcd_Custom_Cmd(LCD_CLEAR);
Lcd_Custom_Out(1, 1, "FreqCounterV9");
for (cnt = 0; cnt < 16; cnt++) {
Lcd_Custom_Chr(2, cnt + 1, 0x00);
Delay_ms(100);
}
Lcd_Custom_Cmd(LCD_CLEAR);
//
fc_flg = -1;
gateTime = GATE_TIME_1SEC;
// 割り込みを許可する。
INTCON.PEIE = 1;
INTCON.GIE = 1;
//
T1CON.TMR1ON = 1;
//
while (1) {
freq = FreqMeasurement();
if (gateTime == GATE_TIME_100MSEC)
freq *= 10;
//ゲートタイム切替
if (SW1 == 1) {
gateTime = GATE_TIME_1SEC;
Lcd_Custom_Out(2, 1, " 1sec");
} else {
gateTime = GATE_TIME_100MSEC;
Lcd_Custom_Out(2, 1, "0.1sec");
}
//-455kHz切替
if (SW2 == 0) {
freq = freq - 455000;
Lcd_Custom_Out(2, 8, "-455kHz");
} else {
Lcd_Custom_Out(2, 8, " ");
}
//Hz/kHz切替
if (SW3 == 1) {
LongToStr(freq, buf);
buf[16] = 0x00;
buf[15] = ' ';
buf[14] = 'z';
buf[13] = 'H';
buf[12] = buf[10];
buf[11] = buf[9];
buf[10] = buf[8];
buf[9] = buf[7] != ' ' ? ',': ' ';
buf[8] = buf[7];
buf[7] = buf[6];
buf[6] = buf[5];
buf[5] = buf[4] != ' ' ? ',': ' ';
Lcd_Custom_Out(1, 1, &buf[2]);
} else {
temp = freq / 1000;
if ((freq - (temp * 1000)) >= 500)
temp++;
LongToStr(temp, buf);
buf[16] = 0x00;
buf[15] = 'z';
buf[14] = 'H';
buf[13] = 'k';
buf[12] = buf[10];
buf[11] = buf[9];
buf[10] = buf[8];
buf[9] = buf[7] != ' ' ? ',': ' ';
buf[8] = buf[7];
buf[7] = buf[6];
buf[6] = buf[5];
buf[5] = buf[4] != ' ' ? ',': ' ';
Lcd_Custom_Out(1, 1, &buf[2]);
}
}
}
//**********************************************************************
===== 動作確認 =====
{{:imgpaste:202004:admin-20200430-180611.png?500}}
{{:imgpaste:202004:admin-20200430-180620.png}}{{:imgpaste:202004:admin-20200430-180624.png}}
32MHzを測定してみました。
左上:ゲートタイム=1秒、Hz表示
右上:ゲートタイム=0.1秒、Hz表示
左下:ゲートタイム=1秒、kHz表示
右下:ゲートタイム=1秒、kHz表示、-455kHz
{{:imgpaste:202004:admin-20200430-180644.png}}{{:imgpaste:202004:admin-20200430-180648.png}}
{{:imgpaste:202004:admin-20200430-180653.png}}{{:imgpaste:202004:admin-20200430-180655.png}}
左側:60MHz
右側:40MHz
{{:imgpaste:202004:admin-20200430-180706.png}}{{:imgpaste:202004:admin-20200430-180709.png}}
左側:32MHz
右側:20MHz
{{:imgpaste:202004:admin-20200430-180723.png}}{{:imgpaste:202004:admin-20200430-180730.png}}
左側:100kHz
右側:10kHz
{{:imgpaste:202004:admin-20200430-180753.png}}{{:imgpaste:202004:admin-20200430-180801.png}}
左側:1kHz
右側:100Hz
{{:imgpaste:202004:admin-20200430-180807.png}}{{:imgpaste:202004:admin-20200430-180813.png}}
左側:10Hz
右側:5Hz
{{:imgpaste:202004:admin-20200430-180823.png}}{{:imgpaste:202004:admin-20200430-180826.png}}
如何ですか?
ハードもソフトも、かなりシンプルに仕上がりましたね。^_^
このページは稲崎様の閉鎖した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]]