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) ;
}
se-fcntr 소스 :
(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 에 라이팅합니다.
se-fcntr hex file
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) 33,000 원
se-pamp 100mhz / 1m ohm 프리암프 (10hz ~ 100mhz) 16,500 원
se-prscr 2.4g / 50 ohm 64분주 프리 스케일러 ( 10mhz ~ 2.4ghz) 27,500 원
*** 주의 ***
(1) se-fcntr 은 케이스, 아답터가 없습니다.
(2) se-fcntr 에는 일반형 24mhz 오실레이터가 포함되어 있습니다.
(2) fnd 의 색상은 적색(red)입니다.
(3) se-fcntr, se-pamp, se-prscr 은 개별 포장되어 있으며 필요한 품목만 선택적으로 구입 할 수 있습니다.
(4) 카운터에 포함된 ic , 수동 부품은 개별적으로 판매하지 않습니다.
(5) 카운터에 포함된 cpu(at89c51)에 카운터 hex 파일이 라이팅되어 있습니다.




来源:韩国
http://www.sample.co.kr/sefcntr/