PDA

View Full Version : cho mình hỏi về cách đo tần số dùng vdk pic


van_vkthq
06-03-2010, 01:57 PM
Chào các bạn!mình có 1 bài toán mà chưa tìm được hướng giải quyết, mong được sự giúp đỡ của các bạn:
mình muốn đo tần số của 2 tín hiệu(là xung vuông) sau đó tính hiệu của 2 tần số đó rồi hiển thị trên LCD.

robotden
04-04-2010, 02:39 AM
Chào bạn
để đo đuợc tần số của 1 tín hiệu xung vuông bạn cần đo đuợc số xung / 1 giây của tín hiệu đó.
như thế ta cần 2 tác vụ:
1/ đếm xung
2/ định thời gian 1s
như thế bạn chỉ cần đếm xung trong 1s thì đó là tần số tín hiệu xung vuông
cụ thể hơn nữa thì bạn dùng 1 timer để định thì 1s, tín hiệu xung vuông đưa vào ngắt EXT chặng hạn, hoặc vào đầu vào bộ Counter
chúc vui

robotden
04-04-2010, 02:39 AM
Chào bạn
để đo đuợc tần số của 1 tín hiệu xung vuông bạn cần đo đuợc số xung / 1 giây của tín hiệu đó.
như thế ta cần 2 tác vụ:
1/ đếm xung
2/ định thời gian 1s
như thế bạn chỉ cần đếm xung trong 1s thì đó là tần số tín hiệu xung vuông
cụ thể hơn nữa thì bạn dùng 1 timer để định thì 1s, tín hiệu xung vuông đưa vào ngắt EXT chặng hạn, hoặc vào đầu vào bộ Counter
chúc vui

pucapuca123
06-09-2011, 07:03 PM
Chào các bạn!mình có 1 bài toán mà chưa tìm được hướng giải quyết, mong được sự giúp đỡ của các bạn:
mình muốn đo tần số của 2 tín hiệu(là xung vuông) sau đó tính hiệu của 2 tần số đó rồi hiển thị trên LCD.

đây là code đo tần số của anh linhnc308
#include <16F877A.h>
#include <def_877a.h>
#use delay(clock=20000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=9)

#bit TMR1IF = 0x0C.0

#include <LCD_lib_4bit.c>

int16 CCP1Value; // Gia tri CCP hien tai
int16 CCP1OldValue; // Gia tri CCP truoc do
BOOLEAN CCP1Captured;
float Freq;
int8 char1,char2,char3,char4,char5,char6,mode;
int8 count,count1,count2,count3;
#int_CCP1
CCP1_isr()
{

if(TMR1IF)
{
CCP1Value = CCP_1 +(65535-CCP1OldValue);
CCP1OldValue = CCP_1;
TMR1IF=0;

}
else
{
CCP1Value = CCP_1 - CCP1OldValue;
CCP1OldValue = CCP_1;
}
CCP1Captured = TRUE;

}
//--------------------------------------------------------------------------
#INT_TIMER0
Timer0_isr()
{
}
//----------------------------------------
void Init_ccp(void)
{
setup_ccp1(CCP_CAPTURE_RE);
setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_64);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_timer0(0);
CCP1Value = 0;
CCP1OldValue = 0;
CCP1Captured = TRUE;
enable_interrupts(INT_CCP1);
//enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
}
//--------------------------------------------------------------------------
void Convert_CCP1()
{
int32 temp;
//Freq = (1.0/((float)CCP1Value*2e-7)); // For Time_Div_1
Freq = (1.0/((float)CCP1Value*16e-7)); //For_Time_Div_8
if (Freq >= 1000 )
{
mode = 1;
temp = freq;
char1 = (temp / 100000) + 0x30;
temp = temp % 100000;
char2 = (temp / 10000) + 0x30;
temp = (temp % 10000);
char3 = (temp / 1000) + 0x30;
temp = (temp % 1000);
char4 = (temp / 100) + 0x30;
temp = temp % 100;
char5= (temp/10 ) + 0x30;
char6 = (temp % 10) + 0x30;
goto exit;
}
else
if (Freq >= 1000000 )
{
mode = 2;
temp = freq;
char1 = (temp / 100000) + 0x30;
temp = temp % 100000;
char2 = (temp / 10000) + 0x30;
temp = (temp % 10000);
char3 = (temp / 1000) + 0x30;
temp = (temp % 1000);
char4 = (temp / 100) + 0x30;
temp = temp % 100;
char5= (temp/10 ) + 0x30;
char6 = (temp % 10) + 0x30;
goto exit;
}
else
{
mode = 0;
temp = (int32)(freq * 1000);
char1 = (temp / 100000) + 0x30;
temp = temp % 100000;
char2 = (temp / 10000) + 0x30;
temp = (temp % 10000);
char3 = (temp / 1000) + 0x30;
temp = (temp % 1000);
char4 = (temp / 100) + 0x30;
temp = temp % 100;
char5= (temp/10 ) + 0x30;
char6 = (temp % 10) + 0x30;
goto exit;
}
exit:
temp = 0;
}
//--------------------------------------------
void convert_timer0_value()
{
count = get_timer0();
count1 = count/100 + 0x30;
count = count%100;
count2 = count/10 + 0x30;
count3 = count%10 + 0x30;
}
//---------------------------------------------------------------
void main()
{
TRISB = 0; // F = 1/T
Init_ccp(); // Timer1 prescaler DIV_BY_1
LCD_init(); // PIC16f877a 20MHz -> 0.0000002 = 200nS
//printf("Frequence test:\r\n"); // Pic16F877A 4MHz -> 0.000001 = 1uS
LCD_putcmd(0xC0);
Printf(LCD_putchar,"Counter = ");
LCD_putcmd(0x80);
Printf(LCD_putchar,"Freq = ");

while (TRUE)
{
if (CCP1Captured)
{
Convert_CCP1();
LCD_putcmd(0x87);
if (char1 != 0x30) LCD_putchar(char1);
if (((char1 != 0x30) && (char2 == 0x30)) || (char2 != 0))
LCD_putchar(char2);
LCD_putchar(char3);
LCD_putchar(".");
LCD_putchar(char4);
LCD_putchar(char5);
switch (mode)
{
case 0: {LCD_putchar(char6);lcd_putcmd(0x8F);Printf(LCD_pu tchar," Hz");} break;
case 1: {LCD_putchar(char6);lcd_putcmd(0x8F);Printf(LCD_pu tchar,"KHz");} break;
case 2: {LCD_putchar(char6);lcd_putcmd(0x8F);Printf(LCD_pu tchar,"MHz");} break;
}
printf("Freq:%f\r\n",Freq);
CCP1Captured = FALSE;
}
convert_timer0_value();
LCD_putcmd(0xCa);
LCD_putchar(count1);
LCD_putchar(count2);
LCD_putchar(count3);
}
}

nhưng mình chưa hiểu dòng này:Freq = (1.0/((float)CCP1Value*16e-7));
*16e-7 là gì vậy?
bạn nào là về cái này rùi giúp mình tý!
cám ơn!

thaitu_mechatro
25-11-2011, 10:56 PM
Chào các bạn!mình có 1 bài toán mà chưa tìm được hướng giải quyết, mong được sự giúp đỡ của các bạn:
mình muốn đo tần số của 2 tín hiệu(là xung vuông) sau đó tính hiệu của 2 tần số đó rồi hiển thị trên LCD.

bạn cũng có thể sử dụng 2 module CCP1 và CCP2 để đo chu kỳ của từng xung rồi từ đó suy ra tần số ...