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