Engineers Garage

  • Electronic Projects & Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Audio Electronics
      • Battery Management
      • Brainwave
      • Electric Vehicles
      • EMI/EMC/RFI
      • Hardware Filters
      • IoT tutorials
      • Power Tutorials
      • Python
      • Sensors
      • USB
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
    • DesignFast
  • Guest Post Guidelines
  • Advertise
  • Subscribe

Frequency and Pulse Width Measurement using microcontroller

By Ashutosh Bhatt May 24, 2012

The circuit designers and developers needs different measuring equipments like digital multimeter, CRO, DSO, frequency counter, logic analyser etc for testing their circuits. When they are designing any oscillator or PWM generator or they have generated any waveform, there is a need to measure either frequency or time period. Especially in case of PWM generator there is a need to measure frequency, ON & OFF time and the most required thing is duty cycle. And during testing and troubleshooting they have to measure all these parameters again and again.

 

Now if they are measuring these parameters using CRO then
·         1st they have to calculate no of horizontal divisions for ON period and for OFF period
·         Then multiply it with time/division factor. They will get Ton and Toff
·         Then after making some calculations they will find out frequency and duty cycle
·         And this they have to repeat every time as they change design
 
So this is tedious and time consuming process. Wrathers then using CRO if they use DSO (digital storage oscilloscope) then all the readouts are available directly. But they have to pay a lot more cost (at lest twice then CRO) for this. Also CRO and DSO are available only in well equipped laboratories because these are not much low cost tools such as digital multimeters. So the hobbyists may not have these tools in their personal home laboratories.
 
So here I have designed one such circuit that will give you direct readouts of four parameters (1) frequency (2) ON time (3) Off time & (4) duty cycle in a second with almost 99% accuracy. The circuit is very simple, easy to build with fewer components one micro-controller (AT89C51), one LCD and additional components like crystal, capacitors, resistors, transistors etc. some of the features of the circuits are
1.      Measures frequency from 50 Hz to 65 KHz (display it in Hz)
2.      Measures ON and OFF time periods from 25 µs to 65 ms (display it in µs)
3.      Measures and displays duty cycle in percentage
4.      Displays all four parameters on 20Ă—4 LCD panel
5.      Repeat mode of operation to continuously measure all four parameters
 
So let us see how to build this circuit
 

Hardware Section

Hardware section: –
The given figure illustrates hardware connections for frequency and pulse width measurement circuit. Major components are micro-controller AT89C51 and 20×4 LCD. The data pins D0-D7 of LCD are connected to port P2 of AT89C51. Control pins RS and E are connected with port P1 pins P1.0 and P1.1. RW pin is connected to ground. A 1 K Ohm pot is connected to VEE pin as shown to vary LCD brightness. One 12 MHz crystal along with two 33 pf capacitors (C2 and C3) are connected to XTAL1 and XTAL2 pins of micro controller to provide required internal clock. One 1 µF capacitor in parallel with one push button (reset) switch is connected in between Vcc and reset pin (no. 9) of micro controller to form “power on reset” circuit. Reset push button is used to manually reset micro controller. One RED LED is connected to pin P1.2 for indication. SPDT switch is connected to pin P1.7 as shown to select either repeat or no repeat operation modes. The signal is applied to pins P3.3 and P3.4 through transistor Q1 (2N2222 type) which is configured in switch mode. This small circuit with one transistor and two resistors will convert any incoming signal into square or rectangle shape and limit the amplitude of signal to Vcc (that is 5 V max)
Working and operation: –
PWM signal (or any other waveform) is applied at the base of transistor. Because transistor works as an invertor, the inverted wave is applied to pins P3.3 and P3.4. Negative edge on pin P3.3 will generate external interrupt. This interrupt will start counting pulses on pin P3.4. Pulses are counted for exactly 1 second period. This gives us directly value of frequency as number of pulses / second. Afterwards internal timer will measure the time (in micro sec) for which the amplitude of pulse remains high that gives Ton value and same for Toff value. At last duty cycle is calculated using equation

formula1

LED indicated counting and calculating process. At last all four values are displayed on LCD. Now if SPDT (or sliding) switch is on no repeat position then measurement process is finished but if it is on repeat position the same above process repeats and it measures all four parameters continuously. This complete operation is based on the program loaded into micro controller. So now let us understand the software program.
 

Software Section

Software section: –
The program is written in embedded C language and compiled through KEIL (IDE) cross compiler. Complete program is divided in 9 different functions with one main function. Out of these nine functions, five functions are for LCD handling, one to measure ON time and OFF time, one to measure duty cycle one interrupt function to measure frequency and the last one is delay function.
 
LCD handling functions: –
1. writecmd function sends command byte to LCD. It takes one argument byte and sends it to P2

2. writedata function sends data byte to be displayed on LCD. It also takes one argument byte and sends it to P2 

  1. 3. writestr function writes whole string (message) on LCD. It takes pointer as an argument that points address of first character of string. then through pointer it sends all the character one by one to P2
  2. 4. busy function generated delay every time before any byte is sent to LCD
  3. 5. display function takes two arguments. It converts HEX numbers into decimal and then decimal to ASCII so that they can be displayed on screen
 
Measuring functions: –
1.      Period function measures ON time and OFF time. It measures the actual time for which pulse amplitude remains high and remains low using timer 1. It first waits for one cycle (ON time and OFF time) to complete. Then starts timer and measures time in micro second till pulse is high. This will measure OFF time because we are measuring inverted pulse width. Then again it waits for one cycle. Again timer will run till pulse is low. This will measure ON time. Both ON time and OFF time values are stored in four different variables.
2.      Frequency function is an interrupt function. It measures number of pulses per second. It starts as soon as a negative edge arrives on external interrupt pin P3.3. It first clears count in TH0 and TL0 and then start counting external pulses arriving on pin P3.4. It stops counter after exact 1 second time. The count in TH0 and TL0 are stored in 2 variables that give’s directly the value of no. of pulses / second.
3.      Dutycycle function calculates duty cycle of wave. It gets the values of Ton and Toff from period function and calculates duty cycle using formula. It also scales down Ton and Toff values if they are out of 16 bit (integer variable) range.
Last one is the delay function that generates exact 1 second delay using timer 1. It generates 50 ms delay using timer and rotates it in a loop for 20 times. So finely we get 50Ă—20 = 1000 ms = 1 sec.
 
The main function performs following tasks
·         First initializes ports and pins as input or output.
·         Next it initializes LCD and displays message “frequency & pulse width measurement”.
·         Then to calculate frequency it initializes timer 0 as counter to count external pulses and timer 1 as timer to generate 1 sec delay.
·         Then it will wait for an external interrupt. Interrupt is generated by negative edge of incoming signal. As frequency is calculated it is displayed as Hz in 5 digits.
·         After that, period function will measure ON time and OFF time and they are displayed on LCD. 
·         After that, dutycycle function will calculate duty cycle and it is also displayed
·         Finely, it reset flag and checks the status of pin P1.7. If its 0, repeat the same operation and if its 1 then programs enters into continuous loop.

 

 

 

Project Source Code

###


#include<reg51.h>

#include<string.h>

sbit rs = P1^0; // rs pin of LCD

sbit en = P1^1; // en pin of LCD  

sbit led= P1^2; // indication LED connected to P0.2

sbit sw = P1^7; // SPDT switch is connected to P1.7

sbit pin = P3^4; // input signal is applied to P3.4

unsigned int flag=0;

unsigned char offtim1, offtim2, ontim1, ontim2,f1,f2;

unsigned int ton,toff,z;

void delay() // generates 1 sec delay  

 {    

int k;

TL1 = 0xBF; // load value in timer 1

TH1 = 0x3C;TR1 = 1; // start timer

for(k=0;k<20;k++) // rotate loop 20 times

 {

while(TF1==0);

TF1 = 0;

TL1 = 0xBF;

TH1 = 0x3C;

 }

TR1 = 0; // stop timer

   }

void busy()     // wait until LCD is busy

  {

int x;

for(x=0;x<1500;x++);

  }

void writecmd(unsigned char a) // send command byte to LCD

  {

busy();

rs = 0;

P2 = a;

en = 1;

en = 0;

  }

void writedata(unsigned char b) // send data byte to LCD

  {

busy();

rs = 1;

P2 = b;

en = 1;

en = 0;

  }

void writestr(unsigned char *s) // write string / message to LCD

  {

unsigned char l,i;

l = strlen(s);

for(i=0;i<l;i++)

{

writedata(*s); // display all the characters

s++; // one by one

}

  }

void frequency() interrupt 2 // external interrupt 1 function

  {

EA=0;  // first disable interrupts

led=0; // indicate on LED

TH0=0x00; // clear count

TL0=0x00;

TR0=1; // start timer 0

delay(); // give 1 sec delay

TR0=0; // stop timer

f1=TL0; // save count

f2=TH0;

flag=1; // set the flag

led=1; // indication off

   }

void period()

    {

   while(pin==1); // wait to complete one 

while(pin==0); // cycle

    TR1=1; // start timer 1

while(pin==1); // wait until pulse amplitude is high

TR1=0; // stop timer

offtim1=TL1; // save the content

offtim2=TH1;

TH1=0x00;   // clear timer again

TL1=0x00;

while(pin==0); // wait again to complete one

while(pin==1); // cycle

TR1=1; // start timer 1 again

while(pin==0); // wait until pulse amplitude is low

TR1=0; // stop timer

ontim1=TL1; // save the content

ontim2=TH1;

  }

void dutycycle()

    {

   int d,d1;

if((ton>100) || (toff>100)) // scales down values of Ton and Toff

 {

ton=ton/10;

toff=toff/10;

 }

else if((ton>1000) || (toff>1000))

 {

  ton=ton/100;

toff=toff/100;

 }

d = ton*100/(ton+toff); // calculate duty cycle

d1 = d%10; // separate two digits and convert

d1=d1+0x30; // in to ascii

d=d/10;

d=d+0x30;

writedata(d); // display them

writedata(d1);

writedata(0x25); // display %

     }

 void display(unsigned char time1, time2)  // convert hex to decimal and 

    {  // decimal to ascii

   unsigned int tmp1,tmp2,tmp3,tmp4,t,t1,i,j;

unsigned char asci[5];

tmp1 = (time1 & 0x0F);  // tmp1 as lower nibble of lower byte

tmp2 = time1 >> 4; // tmp2 as upper nibble of lower byte

tmp3 = (time2 & 0x0F); // same for tmp3 and tmp4 for

tmp4 = time2 >> 4; // upper byte

tmp2 = tmp2*16; // convert them into decimal

tmp3 = tmp3*256;

tmp4 = tmp4*4096;

t = tmp1+tmp2+tmp3+tmp4; // get the final value in t

if(z==1) ton=t; // for z=1 its Ton and 

else toff=t; // vice versa

i=4;

if(t>=10000) // convert all digits into ASCII

 {

while(t>=10)

 {

t1=t%10; // separate all digits

asci[i]=t1+0x30; // add 30h in all digits to get ASCII value

t=t/10;

i--;

 }

asci[0]=t+0x30;

 }

else if (t>=1000)

 {

while(t>=10)

 {

t1=t%10;

asci[i]=t1+0x30;

t=t/10;

i--;

 }

asci[1]=t+0x30;

asci[0]=0x20; // mask all leading values with space

 }

else if (t>=100)

 {

  while(t>=10)

 {

t1=t%10;

asci[i]=t1+0x30;

t=t/10;

i--;

 }

asci[2]=t+0x30;

asci[0]=0x20; // mask all leading values with space

asci[1]=0x20;  

 }

else

 {

t1=t%10;

asci[4]=t1+0x30;

t=t/10;

asci[3]=t+0x30;

asci[2]=0x20;

asci[1]=0x20;

asci[0]=0x20;

 }

for(j=0;j<5;j++) // display

writedata(asci[j]); // all four digits one by one   

  }

  void main()

    {

P2 = 0x00;   // P2 as output port

rs=0;   // clear all LCD control pins

en=0;

sw=1; // sw as input

led=0;

led=1;  

writecmd(0x3C);   // initialize LCD

writecmd(0x0E);

writecmd(0x01);

writecmd(0x84);

writestr("Frequency &          Measurement"); //display message in 1st and 3rd line of LCD

writecmd(0xC4); // move to 2nd line

writestr("Pulse Width"); // and display message

TH0=0x00; // clear count in T0

TL0=0x00;

IT1=1; // edge trigger interrupt

IE=0x84;  // enable external interrupt 1

    TMOD=0x15;     // timer 0 in 16 bit counter and timer 1 in 16 bit timer

next:     while(flag==0);    // remain within loop till flag is clear

writecmd(0x01); // clear LCD 

writestr("Frequency:"); // display frequency

display(f1,f2);

writestr(" Hz  ");

TH1=0x00; // clear T1

TL1=0x00;

period(); // measure time periods

z=0; // for Toff clear flag

     writestr("Toff:"); // display Toff

display(offtim1,offtim2);

writestr(" microsec");   

z=1; // for Ton set flag

writecmd(0xC0);

     writestr("Ton:"); // display Ton

display(ontim1,ontim2);

writestr(" microsec  ");

writestr("duty cycle:");

dutycycle(); // calculate and display duty cycle

flag=0;  // reset the flag to 0 again

EA=1;   // again enable interrupts

if(sw==1) goto next;    // if repeat mode again go for next measurement

while(1); // otherwise continuous loop

}

 

 

 

###

 


Circuit Diagrams

Frequency-and-Pulse-Width-Modulation-measurement


Filed Under: Electronic Projects
Tagged With: at89c51, frequency, microcontroller, pwm
 

Next Article

← Previous Article
Next Article →

Questions related to this article?
👉Ask and discuss on Electro-Tech-Online.com and EDAboard.com forums.



Tell Us What You Think!! Cancel reply

You must be logged in to post a comment.

EE TECH TOOLBOX

“ee
Tech Toolbox: Internet of Things
Explore practical strategies for minimizing attack surfaces, managing memory efficiently, and securing firmware. Download now to ensure your IoT implementations remain secure, efficient, and future-ready.

EE Learning Center

EE Learning Center
“engineers
EXPAND YOUR KNOWLEDGE AND STAY CONNECTED
Get the latest info on technologies, tools and strategies for EE professionals.

HAVE A QUESTION?

Have a technical question about an article or other engineering questions? Check out our engineering forums EDABoard.com and Electro-Tech-Online.com where you can get those questions asked and answered by your peers!


RSS EDABOARD.com Discussions

  • ADS optimization cockpit window does not open
  • Voltage mode pushpull is a nonsense SMPS?
  • Will this TL084C based current clamp circuit work?
  • How to determine the maximum PAD frequency ?
  • Xiaomi Mijia 1C Robot problem of going backwards while working

RSS Electro-Tech-Online.com Discussions

  • Siemens large industrial PLC parts
  • Parts required for a personal project
  • Cant log in to Easy PC forum
  • Failure of polypropylene motor-run capacitors
  • Wideband matching an electrically short bowtie antenna; 50 ohm, 434 MHz

Featured – RPi Python Programming (27 Part)

  • RPi Python Programming 21: The SIM900A AT commands
  • RPi Python Programming 22: Calls & SMS using a SIM900A GSM-GPRS modem
  • RPi Python Programming 23: Interfacing a NEO-6MV2 GPS module with Raspberry Pi
  • RPi Python Programming 24: I2C explained
  • RPi Python Programming 25 – Synchronous serial communication in Raspberry Pi using I2C protocol
  • RPi Python Programming 26 – Interfacing ADXL345 accelerometer sensor with Raspberry Pi

Recent Articles

  • AC-DC power supply extends voltage range to 800 V DC
  • Infineon’s inductive sensor integrates coil system driver, signal conditioning circuits and DSP
  • Arm Cortex-M23 MCU delivers 87.5 µA/MHz active mode
  • STMicroelectronics releases automotive amplifiers with in-play open-load detection
  • Convection-cooled power controller integrates EtherCat connectivity

EE ENGINEERING TRAINING DAYS

engineering

Submit a Guest Post

submit a guest post
Engineers Garage
  • Analog IC TIps
  • Connector Tips
  • Battery Power Tips
  • DesignFast
  • EDABoard Forums
  • EE World Online
  • Electro-Tech-Online Forums
  • EV Engineering
  • Microcontroller Tips
  • Power Electronic Tips
  • Sensor Tips
  • Test and Measurement Tips
  • 5G Technology World
  • Subscribe to our newsletter
  • About Us
  • Contact Us
  • Advertise

Copyright © 2025 WTWH Media LLC. All Rights Reserved. The material on this site may not be reproduced, distributed, transmitted, cached or otherwise used, except with the prior written permission of WTWH Media
Privacy Policy

Search Engineers Garage

  • Electronic Projects & Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Audio Electronics
      • Battery Management
      • Brainwave
      • Electric Vehicles
      • EMI/EMC/RFI
      • Hardware Filters
      • IoT tutorials
      • Power Tutorials
      • Python
      • Sensors
      • USB
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
    • DesignFast
  • Guest Post Guidelines
  • Advertise
  • Subscribe