SE-FCNTR

100 MHz 주파수 카운터 / 펄스 카운터
8051을 이용한 8 디지트 100MHz 주파수 카운터입니다.
Crossware 8051 ANSI C 데모 컴파일러를 사용하였습니다.
디지털 논리 회로의 카운터 오차나 소프트웨어의 계산오차가 없습니다.
24MHz 의 오실레이터 주파수를 8051 XTAL1 클록과 카운터
디지털 입력으로 연결하여 24000000 이 표시됩니다. 1 카운트의 카운트 오차 또는
16진수를 10 진수로 변환할 때 12 ~ 48 클록 오차가 발생하지 않도록 설계하였습니다.
펄스 계수기로 사용할 수 있도록 8 자리의 FND 로 구성하였습니다.

8051 의 내부 16 비트 카운타와 외부 12비트(74F161에서 4 비트, 74HC393에서 8 비트)로 구성된 28 비트 카운터이며 8 자리표시 100MHz 주파수 카운터입니다.
게이트 타임을 1 초로하여 99.999999 의 8 자리 디스프레이합니다.
아나로그 100MHz 프리암프와 2.4G 고주파 64분주 프리스케일러
최소부품수로  카운터가 제작되었습니다.
TI사의 최대 120MHz 카운트 가능한 4비트 카운터 SN74F161을 사용하였습니다.
Hold 모드 선택, MHz/GHz 선택 스위치
FND를 수직으로 세울 수 있도록 하였습니다.
고주파 특성이 좋은 에폭시 양면 PCB입니다.
키트에 포함된 부품이며 쉽게 구할 수 있습니다.
하드웨어 구성: 

SE-FCNTR 은 8051마이크로 프로세서를 사용한 계측기 수준의 주파수 카운터 입니다. 100MHz 디지털 카운터, 아나로그 100MHz 프리암프, 2.4G 64분주 프리스케일러의 3 개 보드로 나누어 구성됩니다. 디지털 카운터 보드는 마이크로 프로세서로 ATMEL 사의 AT89C51을 사용하였습니다. AT89C51은 Intel 사의 표준 8051 과 동일하며 4K Bytes 의 Flash 메모리를 가지고 있으므로 사용하기 편하며 시중에서 구할 수 있는 가장 저렴한 마이크로 프로세서 입니다. 8051 프로세서는 2 개의 16 비트 내부 카운터를 가지고 있습니다. Timer0 는 외부 카운터와 같이 주파수 계수용으로 사용하며 Timer1 은 1 초의 게이트 타임을 만들기 위하여 사용합니다. 회로를 간단히 하기 위하여 숫자 표시용 FND 구동회로를 다이나믹 방식으로 구성하였습니다. 2mS 마다 1 개의 FND 가 순차적으로 점등됩니다. 카운터의 구성 부품수를 최소화 하기 위하여 8051의 내부 16 비트 카운터/타이머 레지스터를 주파수 카운트용 계수기의 일부로 사용합니다. 8051 의 Timer 입력은 최대 주파수가 Xtal1 입력 주파수의 1/4 입니다. 예를 들어 XTAL1 의 클록을 24MHz 주파수로 한다면 최대로 카운트 가능한 주파수는 6MHz 입니다. 주파수 카운터는 일반적으로 5~6 개의 디지트이면 충분합니다만 펄스 계수기로도 사용 가능하게 하기 위하여 8개의 디지트 표시를 목표로 설계하였습니다. 8 자리 카운트 정밀도를 확보하려면 최소 27 비트의 고속 카운터가 필요합니다. Timer0를 16 비트로 사용하고 외부에 8 비트(74HC393) 와 4 비트(74161)를 합하여 28 비트 카운터를 구성합니다. 2의 28 승은 268435456 이므로 99999999를 표시(8자리)하기 위하여 충분합니다. 디지털 펄스 100MHz 를 카운트 할 수 있는 IC로는 74시리즈 중에서 74F161 이 있습니다. 여러 제조사에서 74F161을 생산하지만 최고 카운트 주파수가 조금씩 다릅니다. 모두 100MHz 의 카운트가 가능합니다만 TI사의 SN74F161N 은 120MHz로 가장 빠른 카운트 특성을 가지고 있습니다. SN74F161은 4 비트 카운터 이므로 16 분주하게 되며 100MHz를 16 분주하면 6.25MHz 가 됩니다. 다시 이 주파수를 다른 카운터에서 카운트하여야 합니다.이 주파수는 대부분의 카운터 IC 에서 동작 가능한 낮은 주파수 입니다. 1 개의 패키지에 많은 비트수가 있는 카운터로 선택하며 74HC393 이 8 비트 이므로 적합합니다. 74HC393에서 8 비트 카운터를 거치면 25KHz의 아주 낮은 주파수가 되므로 AT89C51의 Timer0 가 동작하기에 문제없습니다. 8051을 주파수 카운터의 디스프레이 용도로만 사용한다면 관계없으나 1 Sec 의 기준 게이트 온타임을 만들기 위하여는 8051의 명령어 실행시간에 주의하여야 합니다. 8051은 1980년부터 생산된 아주 오래된 프로세서 입니다. 따라서 연산시간이 빠르지 않으며 명령어의 실행시간이 작은 것과 큰 것의 차이가 많이 납니다. 클록주파수를 결정하는 기준은 sjmp $ 명령이 실행되는 시간이 1 uS 의 1/2 또는 1/4 이 되도록 하여야 합니다. 8051은 12 개의 XTAL1 펄스수가 기본 명령어 실행단위 시간이 됩니다. 에를 들어 1바이트 명령 NOP과 INC R0 은 12개의 클록을 소비하며 SJMP $ 명령은 24개의 클록을 소비합니다. 24MHz 의 클록 주파수를 사용한다면 24개의 클록 시간은 1 uS 가 됩니다. 8051은 1 S 를 만들 수 있는 큰 비트의 카운터를 가지고 있지 않습니다. 그러므로 초당 500번의 인터럽트를 발생하여 1 S의 게이트 온 타임 펄스 발생용으로 사용합니다. 인터럽트는 어떤 경우에도 1uS 기준시간 단위로 발생하여야 합니다. 24개의 클록8051의 클록은 24MHz를 사용합니다. 8051은 12 클록을 머신사이클(명령실행 기본 단위시간)로 사용합니다. 최소명령어로 12 클록이 소요되며 시간으로 환산하면 500 nS 가 됩니다. 

소프트웨어 구성:

C 컴파일러를 사용하여 소프트웨어를 개발하였습니다. 영국 Crossware 사의 8051 ANSI C 컴파일러는 풍부한 데이터 타입과 32비트 마이크로프로세서에서 제공하는 IEEE695 디버깅 포맷을 지원합니다. 한국의 마케팅을 지원하기 위하여 0 번지부터 시작하는 4K Bytes 의 Free 버젼 컴파일러를 특별히 무료 공개하였습니다. (타사의 8051 데모 컴파일러는 스타트업 번지가 상위번지에 있으므로 반드시 외부 ROM 이 필요합니다). 
마이크로 프로세서를 이용하여 카운터를 구성할 때 정확한 1 Sec 의 게이트 타임을 만들 수 있느냐가 중요합니다. 주파수 카운터라는 것이 1 Sec 내에 발생한 펄수 수를 계수하는 것이므로 게이트 타임이 1 Sec 로 정확히 떨어지지 않는다면 정확한 카운터라고 볼 수 없습니다.1Sec 의 게이트 타임을 발생하기 위하여 8051의 내부 Timer1을 사용합니다. Xtal1 으로 부터 받은 주파수를 기준으로 초당 500 회의 타이머 인터럽트를 발생합니다. 8051은 CISC 형 프로세서로 명령어의 실행시간이 동일하지 않습니다. 그러므로 계산중에 인터럽트가 발생한다면 피할 수 없는 시간 편차가 발생하여 정확히 1Sec 의 게이트 타임 발생이 되지 않습니다. 28 비트의 바이너리 데이터를 10진수로 변경하여 FND 에 출력하여야 하므로 인터럽트시간 이내에서만 처리가 가능하도록 프로그램을 분산 처리하여야 합니다. 인터럽트 주기가 2 ms 이므로 이 시간 내에 16진수를 10 진수로 변경하는 계산 프로그램과 디스프레이를 처리하여야 합니다. 그런데 8051 printf 함수를 사용하여 2mS이내에 8 자리 진법 변환하는 것은 불가능합니다. 따라서 인터럽트 주기마다 1 자리씩 8 번으로 나누어 차례대로 진법변환을 실행하도록 구성하였습니다. Hold 는 FND 표시 숫자를 정지하는 기능입니다. 


소프트웨어 검증:

8051은 XTAL1 주파수를 24MHz 로 공급합니다. 그리고 74F161의 클록입력을 XTAL1 과 같은 24MHz 를 공급합니다. (하드웨어적으로 연결) 이때 FND 에 표시되는 숫자가 24000000 이 되도록 소프트웨어를 교정한 것입니다. 디스프레이에 2400000 이 표시된다면 소프트웨어적인 계산오차가 발생하지 않았다는 것을 의미합니다. (1 Sec 게이트 기준 클록과 측정 클록이 동일하므로)

100MHz / 1M Ohm 프리암프:

이번 카운터제작에서 가장 힘들었던 부분입니다. 프리암프란 낮은 교류전압을 TTL 레벨로 변경하기 위하여 신호를 증폭하는 회로입니다. 측정 주파수 범위를 100MHz 까지로 하였으므로 초 광대역 암프로 구성하여야 합니다. 그리고 Sine 파를 구형파로 정형하여야 합니다. 이 용도로 사용하는 것이 슈미트 트리거 입니다. 74 시리즈 중에서 74LS14 가 해당됩니다. 그러나 100MHz 이상의 주파수를 통과시키는 슈미트 트리거를 입수하기가 어렵습니다. 74F14 와 74AS14 도 데이터상으로는 고속이지만 임피던스 매칭이 되지않아 실험결과 65MHz 정도가 상한 주파수 였습니다. (이번 실험에서) TI 사의 SN74AHCT14 가 입력 임프던스가 높으며 120MHz 이상의 주파수 통과가 가능한 슈미트 트리거임이 확인되었습니다. 입력 주파수에 따라 최소전압이 다릅니다. 개략적으로 50MHz ~ 100MHz 는 약 1.5V 이상이며 50MHz 이하로는 0.5V 정도면 카운트가 가능합니다. 


2.4GHz / 50 Ohm / 64분주 프리스케일러:

프리스케일러는 카운터의 측정 주파수 상한을 높이는 역활을 합니다. 예를들어 30MHz 카운터에 10분주가 가능한 고속 프리스케일러가 있다면 300MHz 카운터가 되는 것입니다. TTL IC 로 카운터를 만들던 시절에는 10 분주 프리스케일러 IC 를 사용하였으나 현재 마이크로 프로세서에서 진법변환을 실행하므로 64/128/256 분주 프리 스케일러를 사용합니다. 이번 실험에 사용한 프리스케일러는 FUJITSU사의 MB506 입니다. 10MHz 부터 2.4GHz 까지 64분주 프리스케일 카운트가 가능합니다. 입력신호를 증폭하기 위하여 Mini Circuits사의 MAR-6 을 2 개 사용합니다. 0.1V의 작은 신호도 카운트가 가능합니다. 입력 임피던스는 50 Ohm 입니다.

SE-FCNTR 조립키트를 개발하면서 다량의 고주파 자료 수집, 프리암프/프리스케일러 회로설계, 부품선정 그리고 성능평가에 많은 도움을 주신 김 한구 사장님께 감사를 표합니다.

 

//
// 100MHz / 2.4GHz Universal Counter
//
// SAMPLE Electronics co. 25. Nov. 2003
//
// Crossware Embedded Development Studio V 3.3.1.2
//
//
// 
// 74F161 의 4 Bit, 74HC393의 8 Bit 그리고 8051 내부 카운터 T0 16 Bit 로 
// 28 비트의 카운터를 구성한다.
// 펄스 계수시간을 1 Sec 가 되도록 하여 8 디지트표시100 MHz 카운터를 만든다.
// 64 분주 프리스케일러를 사용하기 위하여 펄스 계수 시간을 0.64 S 가
// 되도록 한다. 
//
//
// 8051 Initial C Source File
//
#include <sfr.h>
#include <os.h>
#include <stdlib.h>
#include <stdio.h>

_sfrbit P36_o_74f161_clr_n = _p3^6; // 외부 카운터 F161 리세트 
_sfrbit P35_o_74f161_enp = _p3^5; // 외부 카운터 F161 인에이블 
_sfrbit P30_io_74hc393_clr_hold = _p3^0; // 외부 카운터 HC393 리세트 / HOLD입력 
_sfrbit P37_i_prescaler = _p3^7; // 64 분주 Pre Scaler 
//
// 7 Segment LED 패턴 데이터
// hgfedcba
#define DIG0 0xC0 // 11000000b ; 0 P2.0
#define DIG1 0xF9 // 11111001b ; 1 +-----a-----+
#define DIG2 0xA4 // 10100100b ; 2 | |
#define DIG3 0xB0 // 10110000b ; 3 P2.5 f b P2.1
#define DIG4 0x99 // 10011001b ; 4 | |
#define DIG5 0x92 // 10010010b ; 5 | P2.6 |
#define DIG6 0x82 // 10000010b ; 6 +-----g-----+
#define DIG7 0xD8 // 11011000b ; 7 | |
#define DIG8 0x80 // 10000000b ; 8 P2.4 e c P2.2
#define DIG9 0x98 // 10011000b ; 9 | |
// ; | P2.3 |
#define DIGM 0xBF // 10111111b ; - +-----d-----+ * h P2.7
#define DIGP 0x7F // 01111111b ; .
#define DIGB 0xFF // 11111111b ; "Blank"
//
const char segment_pattern[] = { DIG0, DIG1, DIG2,\
DIG3, DIG4, DIG5, DIG6, DIG7, DIG8, DIG9 };
//
const char segment_select[] = { 0xFE, 0xFD, 0xFB, \
0xF7, 0xEF, 0xDF, 0xBF, 0x7F };
//
unsigned long trailer;
unsigned long task;
unsigned int trimer;
unsigned char fnd[8];
unsigned char mfnd[8];
unsigned int int_state;
unsigned char fnd_state;
unsigned char boat;
bit hold;
//
//
void _interrupt IVN_TIMER1 time_base() {
//////////////////////////////////////////////
_tl1 = 0x60; _th1 = 0xF0; // 4000 2 M Sec 500 Times
//////////////////////////////////////////////
_p0 = 0xff;
_p2 = segment_select[fnd_state];
_p0 = fnd[fnd_state++];
fnd_state &= 0x07;
//////////////////////////////////////////////
if(int_state == 0) { // 

P35_o_74f161_enp = 0; // 외부 카운터 F161 카운터 동작 금지 
//
P30_io_74hc393_clr_hold = 1; // 외부 카운터 HC393 카운터 리세트 
P36_o_74f161_clr_n = 0; // 외부 카운터 F161 카운터 리세트 
_tl0 = 0x00; _th0 = 0x00; // 내부 카운터 리세트 
//
hold = P30_io_74hc393_clr_hold; // Hold Key 상태 입력 

P36_o_74f161_clr_n = 1; // 외부 카운터 F161 카운터 인에이블
P30_io_74hc393_clr_hold = 0; // 외부 카운터 HC393 카운터 인에니블
//

P35_o_74f161_enp = 1; // 외부 카운터 F161 카운터 동작 개시 
}
//////////////////////////////////////////////
if(int_state == 316) { // 10 GHz Mode(64 Divide Prescaler) 
if (!P37_i_prescaler) { // 0.64 Sec Gate Time

for (trimer = 0; trimer<202; trimer++) ; // 15 Machine Cycle 단위
// 테스트 신호원을 24 MHz 로 입력하고
boat++; // 15360000 이 표시되도록 조정한다. 
boat++; // 1 Machine Cycle (12 Clock) Delay
boat++; // 15359988
boat++; // 15360000
// boat++; // 15360012

P35_o_74f161_enp = 0; // 외부 카운터를 멈춘다. 

trailer = _th0;
trailer = (trailer << 20) & 0x0ff00000;
task = _tl0;
task = (task << 12) & 0x000ff000;
trailer |= task;
task = _p3;
task = (task << 7) & 0x00000f00;
trailer |= task;
task = _p1 & 0x000000ff;
trailer |= task; 

P35_o_74f161_enp = 1; // 소비 전류가 일정하게 하기위하여 
// 외부 카운터를 다시 시작한다. 
}

}
//////////////////////////////////////////////
if(int_state == 494) { // 100 MHz Mode 1 Sec Gate Time
if (P37_i_prescaler) { // 1 Sec Gate Time

for (trimer = 0; trimer<248; trimer++) ; // 15 Machine Cycle 단위 
// 테스트 신호원을 24 MHz 로 입력하고 
boat++; // 24000000 이 표시되도록 조정한다. 
boat++; // 
boat++; // 
boat++; // 
boat++; // 1 Machine Cycle (12 Clock) Delay
boat++; // 23999988
boat++; // 24000000
// boat++; // 24000012


P35_o_74f161_enp = 0; // 외부 카운터를 멈춘다. 

trailer = _th0;
trailer = (trailer << 20) & 0x0ff00000;
task = _tl0;
task = (task << 12) & 0x000ff000;
trailer |= task;
task = _p3;
task = (task << 7) & 0x00000f00;
trailer |= task;
task = _p1 & 0x000000ff;
trailer |= task; 

P35_o_74f161_enp = 1; // 소비 전류가 일정하게 하기위하여 
// 외부 카운터를 다시 시작한다. 
}

}
//////////////////////////////////////////////
if(int_state == 506) { // 1Hz 표시 디지트 
boat = trailer % 10; 
mfnd[7] = segment_pattern[boat & 0xf];
trailer /= 10;

//////////////////////////////////////////////
if(int_state == 507) {
boat = trailer % 10;
mfnd[6] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 508) {
boat = trailer % 10;
mfnd[5] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 509) {
boat = trailer % 10;
mfnd[4] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 510) {
boat = trailer % 10;
mfnd[3] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 511) {
boat = trailer % 10;
mfnd[2] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 512) {
boat = trailer % 10;
mfnd[1] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
if(int_state == 513) {
boat = trailer % 10;
mfnd[0] = segment_pattern[boat & 0xf];
trailer /= 10;
}
//////////////////////////////////////////////
int_state++;
//////////////////////////////////////////////
if(int_state >= 514) {
int_state = 0;
if (hold) {
fnd[0] = mfnd[0];
fnd[1] = mfnd[1];
fnd[2] = mfnd[2];
fnd[3] = mfnd[3];
fnd[4] = mfnd[4];
fnd[5] = mfnd[5];
fnd[6] = mfnd[6];
fnd[7] = mfnd[7];

if (P37_i_prescaler) {
fnd[1] &= 0x7F; // MHz Point
} else {
fnd[0] &= 0x7F; // GHz Point
}
}
}
//////////////////////////////////////////////
}

main()
{
_tmod = 0x15; // 0b00010101 Timer0 = Mode1, Counter, use TR0
// Timer1 = Mode1, Timer, use TR1
_tl0 = 0X0; _th0 = 0X0;
_tl1 = 0X0; _th1 = 0X0;
_tr0 = 1; // Timer 0 동작시작
_tr1 = 1; // Timer 1 동작시작 

_et1 = 1; // 타이머 1 인터럽트 가능상태 설정
_ea = 1; // 글로벌 인터럽트 가능상태 설정

while(1) ;

}






(1) Crossware 8051 C 데모컴파일러를 설치한후
c:\estudio_demo\Projects\fcntr4 폴더를 만든 후 압축을 풉니다.
(2) Crossware 의 File 메뉴에서 Project Open 을 클릭하고
c:\estudio_demo\Projects\fcntr4 \fcntr4.xmk 를 선택합니다.
(3) Crossware의 Build 메뉴에서 Rebuild All 을 선택하면 소스 컴파일 하기시작하며 fcntr4.hex 가 만들어집니다. 
(5) 8051 프로그래밍이 가능한 프로그래머 또는 샘플전자에서 제작한 SE-516SP를 사용하여 fcntr4를 AT89C51 에 라이팅합니다. 

Crossware 8051 C 컴파일러 데모버젼을 다운받으세요. HEX 파일 스타트 어드레스가 0000H 부터이며 4K Hex 코드 출력이 가능합니다. Flash 메모리가 4K 인 AT89C51, AT89S51 과 AT89C1051/2051/4051 을 사용할 수 있습니다. Crossware 8051 C 컴파일러는 한국산업인력공단 시행 기사 시험용 컴파일러로 선정되었습니다. 
Crossware 8051 C 컴파일러 한글매뉴얼

 

SE-PAMP

100 MHz 프리암프
입력임피던스 1M Ohm

 

저주파에서 100mV , 50MHz~ 100MHz 에서 2V 의 신호를 증폭하여 TTL 레벨로 변환하는 프리암프입니다. 
10Hz ~ 100MHz 대역이며 1M Ohm 입력임피던스 입니다.
100 MHz의 SINE파를 TTL로  펄스정형이 가능한 슈미트 트리거 SN74AHCT14
초고주파용 FET 2SK241
NEC사의 5 GHz 대역폭 고속 트랜지스터 2SC2570

프리암프 구성 부품

 

SE-PRSC

2.4 GHz 프리암프
입력임피던스 50 Ohm

10MHz ~ 2.4GHz 까지 측정되는 64분주 프리스케일러 입니다. 
입력감도는 100mV 입니다. 
Mini circuits사의 모노리딕 초광대역 고주파 증폭 IC 를 사용하였습니다.
50 Ohm 입력임피던스 입니다.
Mini Circuits 사의 광대역 고주파 증폭기 MAR-6
FUJITSU사의 2.4 GHz 프리스케일러 (64, 128, 256 분주 선택가능) MB506
프리 스케일러 구성 부품

Dip 메터를 이용한 카운터 테스트

100Mhz 아나로그 프리암프 테스트
전파로 유도되어 카운터가 동작합니다.
비 접촉식으로 측정이 가능합니다.
80MHz (G 눈금)의 주파수를 발진하여 카운터에 입력합니다.
2.4G 프리스케일러 테스트
카운터 시험에 사용한 딥 메터(Dip Meter)

가 격 정 보

품목 사양  
SE-FCNTR 100MHz 디지털 TTL입력 카운터 (DC - 100MHz) 
SE-PAMP 100MHz / 1M Ohm 프리암프 (10Hz ~ 100MHz)
SE-PRSCR 2.4G / 50 Ohm 64분주 프리 스케일러 ( 10MHz ~ 2.4GHz)
*** 주의 ***

(1) SE-FCNTR 은 케이스, 아답터가 없습니다.
(2) SE-FCNTR 에는 일반형 24MHz 오실레이터가 포함되어 있습니다.
(2) FND 의 색상은 적색(Red)입니다.
(3) SE-FCNTR, SE-PAMP, SE-PRSCR 은 개별 포장되어 있으며 필요한 품목만 선택적으로 구입 할 수 있습니다.
(4) 카운터에 포함된 IC , 수동 부품은 개별적으로 판매하지 않습니다.
(5) 카운터에 포함된 CPU(AT89C51)에 카운터 HEX 파일이 라이팅되어 있습니다.