The circuit designers and developers needs different measuring equipment like digital multi-meter, CRO, DSO, frequency counter, logic analyse 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.
- 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
- 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
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
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
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 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.
The program is written in embedded C language and compiled through KEIL 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.
1. write cmd function sends command byte to LCD. It takes one argument byte and sends it
to P2
2. write data function sends data byte to be displayed on LCD. It also takes one argument
2. write data function sends data byte to be displayed on LCD. It also takes one argument
byte and sends it to P2
3. write str function writes whole string 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
4. busy function generated delay every time before any byte is sent to LCD
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
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.
· 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, duty cycle 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.
Source Code
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;
TL 1 = 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
{
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
}
No comments:
Post a Comment