120MHz 89C2051 頻率計 Frequency Meter 很多網友對 PIC 蕊片不太熟悉, 很多人看了前面的 16F84 頻率計 文章,對其計頻功能保持懷疑, 4MHz 的晶振, 1us 的指令時間,為什么可計頻到 50 MHz, 也有很多人對 PIC16C5x 的蕊片,批評的一文不值,堆疊只有兩個,暫存器才 24個 (c57 有 72個),指令只有 35 個,又沒中斷,雖然后期產品已都加入中斷、串列、A/D、..., 但后期產品的堆疊只有8個,還是繼續被批評的體無完膚,大多公認 C51 系列功能強,容量大,介面支援多,似乎 PIC 系列沒有一樣比得上。我在此替 pic 系列說句公道話, 它有很多功能是 C51 比不上的, 只是真正會利用的人并不多,就好像 前面刊出的 50MHz 頻率計 文章,在別的 CPU 來做,似乎無法以那么少個 IC 就可達成, 大家嫌 16C5x 沒中斷,當計時器一定很爛, 很多 PIC 的玩家也都這樣認為, 其實說來, PIC 的 RTCC 計時方式,精準度很高,用來當計時電路時的準確度,不是 C51 所能比得上的,它可作到與 晶振 的準確率一樣,但非常多的玩家大多不會 RTCC 的技巧,形成說 PIC 的計時功能是最差的.(是你不會技巧,而不是功能太差). 大家對 C51 系列比較熟悉, 所以再轉貼一個 89C2051 的 120 MHz 頻率計 供大家參考.(沒有 PCB 圖) 電路圖:

點此處看清晰電路圖 ============= measure.c51 ==================================================
/************************************************************************/ /* */ /* Frequency Meter 5Hz ... 125MHz Test Program */ /* */ /* Author: Peter Dannegger */ /* danni@specs.de */ /* */ /************************************************************************/ #include "main.h" #include "measure.h" #include "display.h" #include <stdio.h>
#define BAUD 9600
void main( void ) { uchar idata s[DISPLAYMEM]; PCON |= SMOD_; // initialization UART SCON = TI_ + REN_ + SM1_; TMOD = T1_M1_ + T0_M0_ + T0_M1_; // T0: splitt timer // T1: baud rate TH1 = (uchar) -(0.5 + XTAL / 12.0 / 16 / BAUD); TL1 = -1;
for(;;){ measure_start(); while( measure_poll() == 0 ); display( measure_read(), s ); puts( s ); } }
============= measure.h ==================================================
void measure_start( void );
bit measure_poll( void );
float measure_read( void );
========== display.c51 =====================================================
/************************************************************************/ /* */ /* Display 5 digit floating point number */ /* */ /* Author: Peter Dannegger */ /* danni@specs.de */ /* */ /************************************************************************/ #include "main.h"
void display ( float val, uchar idata *ptr ) { uchar hz, num, i, dp;
for( dp = 1; val >= 10; dp++ ) // normalize (x.xxxx) val *= 0.1; // 3 times faster as "val /= 10;"
hz = 0; if( dp > 6 ){ // MHz ? dp -= 6; hz = "M"; } if( dp > 3 ){ // kHz ? dp -= 3; hz = "k"; }
for( i = DIGITS;; ){ // 5 digits *ptr++ = (num = val) + "0"; // get digit if( --dp == 0 ){ // set decimal point *ptr++ = "."; } if( --i == 0 ) break; val = (val - num) * 10; // next digit } if( hz ) *ptr++ = hz; *ptr++ = "H"; *ptr++ = "z"; *ptr = 0; }
========== display.h =====================================================
void display ( float val, uchar idata *ptr );
========== main.c51 =====================================================
/************************************************************************/ /* */ /* Frequency Meter 5Hz ... 125MHz Test Program */ /* */ /* Author: Peter Dannegger */ /* danni@specs.de */ /* */ /************************************************************************/ #include "main.h" #include "measure.h" #include "display.h" #include <stdio.h>
#define BAUD 9600
void main( void ) { uchar idata s[DISPLAYMEM]; PCON |= SMOD_; // initialization UART SCON = TI_ + REN_ + SM1_; TMOD = T1_M1_ + T0_M0_ + T0_M1_; // T0: splitt timer // T1: baud rate TH1 = (uchar) -(0.5 + XTAL / 12.0 / 16 / BAUD); TL1 = -1;
for(;;){ measure_start(); while( measure_poll() == 0 ); display( measure_read(), s ); puts( s ); } }
========== main.h =====================================================
#pragma cd pl(9999) #include<reg2051.h> #include<types.h>
#define DIGITS 5 // 123.45 #define DISPLAYMEM DIGITS + 5 // "123.45MHz", 0
#define XTAL 24e6 #define BAUD 9600
#define TB2_1SEC XTAL / 12 / 256 / 256 // value 2.byte
#define TIMEOUT1 (uchar)( TB2_1SEC * 0.5 ) // wait for start: 0.5sec #define TIMEOUT2 (uchar)( TB2_1SEC * 0.5 ) // collect counts: 0.5sec #define TIMEOUT3 (uchar)( TB2_1SEC * 0.5 ) // wait for stop: 0.5sec
sbit DISDAT = P1^3; sbit DISCLK = P1^4; sbit DISSTB = P1^5;
sbit SET_CT0 = P1^6; sbit SET_CT1 = P1^7;
===============================================================
|