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