| 
 
 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;
 
 ===============================================================
 |