====== 周波数カウンタV5(集大成版) ======
===== 概要 =====
今迄に多数の周波数カウンタを製作してきましたが、機能や構造の見直しを含めここに集大成してみました。
===== 動作原理 =====
特に拘った箇所は、基準時間(1秒、0.1秒)を発生させる仕組みです。
独自に発案した方式で、PIC内臓の「TIMER1」モジュールのみを使用します。これにより、プログラムの構造をシンプルにすることが出来ます。
<仕様>
* アナログデータ(0~5V)のバー16点表示
* sw0=1無し
* sw0=0有り
* プリスケーラの切り替え
* sw1=11/1
* sw1=01/8
* ゲートタイムの切り替え
* sw2=11秒
* sw2=00.1秒
* -455kHzの有無切り替え
* sw3=1-0kHz
* sw3=0-455kHz
* 表示レンジの切り替え
* sw4=1Hz表示
* sw4=0kHz表示
===== 回路図 =====
{{:imgpaste:202004:htmikan-20200429-180936.png}}
===== ソースコード =====
//**********************************************************************
/*
<周波数カウンター>
sw0:アナログデータのバー16点表示
・sw0=1 無し
・sw0=0 有り
sw1:プリスケーラの切り替え
・sw1=1 1/1
・sw1=0 1/8
sw2:ゲートタイムの切り替え
・sw2=1 1秒
・sw2=0 0.1秒
sw3:-455kHzの有無切り替え
・sw3=1 -0kHz
・sw3=0 -455kHz
sw4:表示レンジの切り替え
・sw4=1 Hz表示
・sw4=0 kHz表示
*/
//**********************************************************************
/*
<PICのピンアサイン>
Pin-01 アナログデータ入力
Pin-02 未使用
Pin-03 信号入力
Pin-04 アナログデータの表示切替SW
Pin-05 Vss(GND)
PIN-06 プリスケーラの切替SW
Pin-07 ゲートタイムの切替SW
Pin-08 -455kHzの切替SW
Pin-09 表示レンジの切替SW
Pin-10 LCD:D7
Pin-11 LCD:D6
Pin-12 LCD:D5
Pin-13 LCD:D4
Pin-14 Vdd(+5V)
Pin-15 LCD:EN
Pin-16 クロック入力(16MHz入力)
Pin-17 LCD:WR
Pin-18 LCD:RS
*/
//**********************************************************************
#define sw0 PORTA.F5
#define sw1 PORTB.F0
#define sw2 PORTB.F1
#define sw3 PORTB.F2
#define sw4 PORTB.F3
#define GATETIME_100MSEC 10
#define GATETIME_1SEC 1
//**********************************************************************
static short MeasurementCnt;
void interrupt()
{
if (PIR1.TMR1IF == 1) {
PIR1.TMR1IF = 0;
//
MeasurementCnt--;
if (MeasurementCnt == 0) {
TRISA.F4 = 0; // ゲートを閉める。
PORTA.F4 = 0;
T1CON.TMR1ON = 0; // TIMER1を停止する。
}
}
}
//**********************************************************************
unsigned long FreqMeasurement(unsigned short gateTime)
{
unsigned long freq;
//
TRISA.F4 = 0; //ゲートを閉める。
PORTA.F4 = 0;
// TIMER0の設定
INTCON.T0IF = 0;
TMR0 = 0;
// TIMER1の設定
PIR1.TMR1IF = 0;
switch (gateTime) {
case GATETIME_1SEC:
MeasurementCnt = 8;
TMR1L = 0xE0; // 500000=(1/16000000) * 4 * 8
TMR1H = 0x5E; // 0x5EE0=65536-(500000-(65536*7))
break;
case GATETIME_100MSEC:
MeasurementCnt = 1;
TMR1L = 0xB0; // 50000=(0.11/16000000) * 4 * 8
TMR1H = 0x3C; // 0x3CB0=65536-50000
break;
}
//
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
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 = (freq * 256) + TMR0;
return (freq);
}
//**********************************************************************
void main()
{
static char* msg;
static unsigned long freq, temp; // 0...4294967295
static unsigned char buf[20], cnt, prescaler, gateTime;
static unsigned int ad;
// アナログの設定
ANSEL = 0b00000100; // ad2を使用する。
// ポートの設定
TRISA = 0b10111100;
TRISB = 0b00001111;
// TIMER0の設定
INTCON = 0b00000000;
OPTION_REG = 0b01101000;
// TIMER1の設定
PIE1.TMR1IE = 1;
PIR1.TMR1IF = 0;
T1CON.T1CKPS0 = 1;
T1CON.T1CKPS1 = 1;
T1CON.TMR1ON = 0;
//
prescaler = 1;
gateTime = GATETIME_1SEC;
//
Lcd_Custom_Config(&PORTB,4,5,6,7,&PORTA,1,0,6);
Lcd_Custom_Cmd(LCD_CURSOR_OFF);
Lcd_Custom_Cmd(LCD_CLEAR);
//
while (1) {
freq = FreqMeasurement(gateTime);
// 補正
freq *= prescaler * gateTime;
// アナログデータのバー表示
if (sw0 == 0) {
ad = Adc_Read(2) / 60;
for (cnt = 0; cnt < ad; cnt++)
buf[cnt] = 0xFF;
for (; cnt < 16; cnt++)
buf[cnt] = ' ';
buf[cnt] = 0x00;
Lcd_Custom_Out(2, 1, buf);
}
// プリスケーラの切り替え
if (sw1 == 1) {
OPTION_REG.PSA = 1;
OPTION_REG.PS1 = 0;
prescaler = 1;
msg = "1/1 ";
} else {
OPTION_REG.PSA = 0;
OPTION_REG.PS1 = 1;
prescaler = 8;
msg = "1/8 ";
}
if (sw0 == 1)
Lcd_Custom_Out(2, 1, msg);
// ゲートタイムの切り替え
if (sw2 == 1) {
gateTime = GATETIME_1SEC;
msg = "1sec ";
} else {
gateTime = GATETIME_100MSEC;
msg = "0.1sec ";
}
if (sw0 == 1)
Lcd_Custom_Out(2, 5, msg);
// -455kHzの有無
if (sw3 == 0) {
freq -= 455000;
msg = "-455k";
} else {
msg = " ";
}
if (sw0 == 1)
Lcd_Custom_Out(2, 12, msg);
// 表示レンジの切り替え
if (sw4 == 1) {
LongToStr(freq, buf);
msg = "Hz ";
} else {
temp = freq / 1000;
if ((freq - (temp * 1000)) > 500) {
temp++;
}
LongToStr(temp, buf);
msg = "kHz";
}
Lcd_Custom_Out(1, 9, msg);
// 周波数の表示
Lcd_Custom_Out(1, 1, &buf[3]);
}
}
//**********************************************************************
===== 動作確認 =====
プリスケーラ→1/1ゲートタイム→1秒
{{:imgpaste:202004:htmikan-20200429-181048.png?500}}
プリスケーラ→1/8ゲートタイム→1秒
{{:imgpaste:202004:htmikan-20200429-181105.png?500}}
プリスケーラ→1/1ゲートタイム→0.1秒
{{:imgpaste:202004:htmikan-20200429-181120.png?500}}
プリスケーラ→1/1ゲートタイム→1秒-455kHz
{{:imgpaste:202004:htmikan-20200429-181135.png?500}}
プリスケーラ→1/1ゲートタイム→1秒kHz表示
{{:imgpaste:202004:htmikan-20200429-181154.png?500}}
アナログデータのバー表示
{{:imgpaste:202004:htmikan-20200429-181208.png?500}}
このページは稲崎様の閉鎖した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]]