[PIC] how to measure the frequency of square wave using pic?

Status
Not open for further replies.

Deexith Hasan

Advanced Member level 4
Joined
Oct 24, 2014
Messages
111
Helped
4
Reputation
8
Reaction score
3
Trophy points
18
Visit site
Activity points
740
how to measure the frequency of square wave (time period=20us) and display the high and low period in lcd?
i tried using capture mode and using counter but failed.....
help me!!!
 

What MCU are you using ?
what is the FOSC ?
C compiler ?
What is the mini and maxi duty cycle of your signal
ie : 1µS ON 19µS off
or 19µS On and 1 µS off
What accuracy ?
is your signal enough stable .. ie to cumulate many periodes of elementary signal to increase time resolution (less than 1µS)
CCP mode with 16 edges counting ?

Post your schematic and code
 

PIC18F4520
20MHz crystal
hitech compiler
50% duty cycle
any accuracy is welcome.
stable using protues signal generator
ccp mode with single rising edge
 

This book "Embedded C Programming and the Microchip PIC" contains the solution but it is CCS C Code. You can convert it to Hi-Tech PICC code. Buy the book.
 

Code:
#include<htc.h>
#define lcd PORTD
#define rs RE0
#define en RE1
#define trrs TRISE0				   
#define tren TRISE1

unsigned char cal=0;
unsigned char lsb=0;
unsigned char msb=0;
unsigned char mmb=0;
unsigned int temp=0;
unsigned int tp=0;
unsigned char ton=0;
unsigned char toff=0;

lcd_delay()
{
unsigned char i;
for(i=0;i<252;i++);
}

void lcd_datawrite(unsigned char data)
{
rs=1;
lcd=data;
en=1;
lcd_delay();
en=0;
}

void lcd_cmdwrite(unsigned char data)
{
rs=0;
lcd=data;
en=1;
lcd_delay();
en=0;
}

void lcd_install()
{
TRISD=0x00;				   
trrs=0;				   
tren=0;
lcd_cmdwrite(0x38);  // 5x7 dots ini 
lcd_cmdwrite(0x0C);  // cursor on disp on
lcd_cmdwrite(0x80);  // move to 1st lint 1st loc
lcd_cmdwrite(0x01);  // clear disp
}

void lcd_stringwrite(unsigned char *ptr)
{
while(*ptr!='\0'){
lcd_datawrite(*ptr);
ptr++;
}
}

void main()
{
ADCON1=0x0F;
	
lcd_install();

CCP1CON=0X05;
T3CON=0X0;
T1CON=0X00;
TRISB=0;
TRISD=0;
TRISC2=1;
CCPR1L=0;
CCPR1H=0;
CCP1M0=1;
while(1)
{
TMR1H=0;
TMR1L=0;
CCP1M0=1;
CCP1IF=0;
while(CCP1IF==0);
TMR1ON=1;
CCP1IF=0;
while(CCP1IF==0);
TMR1ON=0;
temp=tp=((CCPR1L+2)*2);
lsb=temp%10;
temp=temp/10;
mmb=temp%10;
msb=temp/10;
lcd_cmdwrite(0x80);
lcd_stringwrite("TP=");
lcd_datawrite(0x30|msb);
lcd_datawrite(0x30|mmb);
lcd_datawrite('.');
lcd_datawrite(0x30|lsb);
TMR1H=0;
TMR1L=0;
CCP1IF=0;
while(CCP1IF==0);
TMR1ON=1;
CCP1M0=0;
CCP1IF=0;
while(CCP1IF==0);
TMR1ON=0;
temp=ton=((TMR1L-1)*2);
lsb=temp%10;
temp=temp/10;
mmb=temp%10;
msb=temp/10;
lcd_stringwrite(" TON=");
lcd_datawrite(0x30|msb);
lcd_datawrite(0x30|mmb);
lcd_datawrite('.');
lcd_datawrite(0x30|lsb);
temp=toff=tp-ton;
lsb=temp%10;
temp=temp/10;
mmb=temp%10;
msb=temp/10;
lcd_cmdwrite(0xC0);
lcd_stringwrite("TOff=");
lcd_datawrite(0x30|msb);
lcd_datawrite(0x30|mmb);
lcd_datawrite('.');
lcd_datawrite(0x30|lsb);
}
}
 

Do not turn on or off timer at ever risings or falling edge, keep timer running in automatic reloading mode and capture value of capture resistor at every rising or falling edge at CCP pin. use both timer and capture in interrupt mode. Timer value do't provide you frequency directly, it will provide you number of count. you have to perform calculation over number of count to get frequency.

some think like this .

if your timer take 8us to get increment by 1 and if you get 10 count, means rising or falling edge striking after each 80us.
Take inverse of it you will get frequency.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…