Design of Frequency Counter Based on AT89C51 Microcontroller

In the fields of electronic engineering and automation, frequency measurement is a fundamental and important task. Whether in signal processing, communication systems, or industrial automation, accurately measuring signal frequency is an indispensable part. Traditional frequency measurement devices are often expensive and bulky, making them impractical for small projects or individual enthusiasts. The frequency counter design based on the 51 microcontroller not only has a low cost but also offers high precision and flexibility, making it very suitable for beginners and small project needs. This article will detail the design of a frequency counter based on the 51 microcontroller, including hardware circuit design, software programming, and test results, along with complete source code to help readers quickly implement this practical tool.

A frequency counter is an instrument used to measure signal frequency, widely applied in electronic experiments, communication system debugging, audio processing, and other fields. With the development of electronic technology, there are higher demands for the accuracy and convenience of frequency measurement. Traditional frequency counters usually employ complex analog circuits or dedicated frequency counter chips, which are costly and difficult to integrate into small projects. The 51 microcontroller, as a classic microcontroller, has advantages such as low cost, powerful functionality, and ease of programming, making it very suitable for implementing low-cost frequency counter designs. Hardware Circuit Design (1) Microcontroller Selection This design uses the STC89C52 microcontroller as the core control unit. The STC89C52 is a classic 8-bit microcontroller with rich I/O resources, high operating speed, and low power consumption. It has built-in timer and interrupt system modules that can meet the basic needs of frequency measurement. (2) Signal Input Circuit The frequency counter needs to receive external signals for measurement, so the design of the signal input circuit is crucial. To ensure signal stability and compatibility, we adopted a simple RC filter circuit to filter out high-frequency noise and used a voltage comparator to convert the input signal into a square wave signal for counting by the microcontroller. The voltage comparator uses the LM393 chip, which has a wide input signal range and fast response speed, making it well-suited for different amplitude input signals. Display Circuit The results of frequency measurement need to be presented to the user through a display device. This design uses a four-digit common anode seven-segment display, driven by the microcontroller’s I/O ports to show the frequency value. To save I/O port resources, we employed dynamic scanning display technology, controlling the display content of the seven-segment display through software while ensuring display stability and clarity. Power Supply Circuit The power supply circuit provides a stable power supply for the entire frequency counter. We used a simple linear voltage regulator circuit to convert the external power supply into the 5V power supply required by the microcontroller and the seven-segment display. The design of the power supply circuit needs to consider factors such as power stability, ripple, and noise to ensure the measurement accuracy of the frequency counter. Software Design (1) Main Program Design The main program is the core control logic of the frequency counter, responsible for initializing hardware devices, starting frequency measurement, updating display content, and other tasks. The flow of the main program is as follows: 1. Initialize the microcontroller’s I/O ports, timer, and interrupt system. 2. Start the timer and begin timing. 3. Wait for interrupt trigger to calculate signal frequency. 4. Update the seven-segment display content. 5. Repeat the above steps to continuously measure frequency. (2) Interrupt Service Routine The interrupt service routine is key to achieving high-precision measurement in the frequency counter. We use the external interrupt 0 of the microcontroller to capture the rising edge of the input signal, while using the timer interrupt to establish a time reference. When the external interrupt is triggered, the microcontroller records the current timestamp, and by calculating the time difference between two adjacent interrupts, we can obtain the signal period and subsequently calculate the frequency value. (3) Display Program The display program is responsible for showing the measured frequency value on the seven-segment display. Due to the use of dynamic scanning display technology, we need to periodically update the display content of the seven-segment display in the main program. The display program controls the scanning speed of the seven-segment display through software delays to ensure display stability and clarity. Four, Testing and Result Analysis (1) Testing Method To verify the performance of the frequency counter, we used a signal generator as the test signal source to measure sine wave and square wave signals of different frequencies. By comparing the frequency values displayed by the signal generator with the results measured by the frequency counter, we evaluate the measurement accuracy and stability of the frequency counter. (2) Testing Results After multiple tests, the frequency counter achieved an accuracy of 0.1% within the measurement range, accurately measuring signal frequencies from tens of hertz to tens of kilohertz. During the testing process, the frequency counter’s display was stable, with a fast response speed, capable of real-time updating of frequency values. The test results indicate that the frequency counter design based on the 51 microcontroller can meet the needs of general engineering applications.

The source code is as follows:

#include <<reg51.h>>//<reg52.h> includes the header file for STC89C51 microcontroller#define uchar unsigned char#define uint unsigned int// Define seven-segment display segment codesuchar code DIGIT_CODE[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};// Define seven-segment display digit selection signalsbit DIGIT1 = P2^0;sbit DIGIT2 = P2^1;sbit DIGIT3 = P2^2;sbit DIGIT4 = P2^3;// Define signal input pin sbit SIGNAL_IN = P3^2;// Define timer interrupt flag bit TIMER_FLAG = 0;// Define frequency measurement variablesuint count = 0; // Signal countuint freq = 0; // Measured frequency// Seven-segment display dynamic scanning functionvoid Display(uint num) {    uchar digit[4] = {0}; // Store four digits    uchar i;    // Decompose frequency value into four digits    digit[3] = num % 10;    num /= 10;    digit[2] = num % 10;    num /= 10;    digit[1] = num % 10;    num /= 10;    digit[0] = num % 10;    // Dynamic scanning display    for (i = 0; i < 4; i++) {        switch (i) {            case 0:                DIGIT1 = 0;                DIGIT2 = 1;                DIGIT3 = 1;                DIGIT4 = 1;                P0 = DIGIT_CODE[digit[0]];                break;            case 1:                DIGIT1 = 1;                DIGIT2 = 0;                DIGIT3 = 1;                DIGIT4 = 1;                P0 = DIGIT_CODE[digit[1]];                break;            case 2:                DIGIT1 = 1;                DIGIT2 = 1;                DIGIT3 = 0;                DIGIT4 = 1;                P0 = DIGIT_CODE[digit[2]];                break;            case 3:                DIGIT1 = 1;                DIGIT2 = 1;                DIGIT3 = 1;                DIGIT4 = 0;                P0 = DIGIT_CODE[digit[3]];                break;        }        delay(1); // Delay    }}// Delay functionvoid delay(uint z) {    uint x, y;    for (x = z; x > 0; x--)        for (y = 110; y > 0; y--);}// Timer initialization functionvoid Timer_Init() {    TMOD = 0x01; // Timer 0 works in mode 1    TH0 = (65536 - 50000) / 256; // Set timer initial value    TL0 = (65536 - 50000) % 256;    ET0 = 1; // Enable timer 0 interrupt    EA = 1; // Enable global interrupt    TR0 = 1; // Start timer 0}// External interrupt 0 initialization functionvoid External_Interrupt_Init() {    IT0 = 1; // Edge-triggered mode    EX0 = 1; // Enable external interrupt 0}// Timer interrupt service routinevoid Timer0_ISR() interrupt 1 {    TH0 = (65536 - 50000) / 256; // Reload timer initial value    TL0 = (65536 - 50000) % 256;    TIMER_FLAG = 1; // Set timer interrupt flag}// External interrupt 0 service routinevoid External_Interrupt0_ISR() interrupt 0 {    count++; </reg52.h>

Leave a Comment