51单片机定时器及其应用(3)(测量脉冲频率)
?????前面介绍了定时器的一般应用以及定时器GATE位的应用,还有一个位没有介绍,那就是定时器
C
/
T
ˉ
C/\bar{T}
C/Tˉ位。前面讲解定时器时总是写作定时器/计数器。这一位便是控制单片机这一功能是作为定时器还是计数器,其实本质都是计数器,作为定时器时候,对内部的1us脉冲进行计数,作为计数器的时候,对外部的脉冲进行计数,也就是来自T1引脚的脉冲,我们只要测量1s中之内有多少个脉冲,也就可以得到输入信号的频率了。 ?????给定一个门限时间T,在这段时间里面对脉冲进行计数,如上图,恰好有N个脉冲,那么可以得到N
T
s
i
g
n
a
l
T_{signal}
Tsignal?=T,假设门限时间为1s,则信号频率
f
s
i
g
n
a
l
f_{signal}
fsignal?=N。这便是简单频率测量的原理。注意上面分析是恰好,加入当T开始的时候,先来的是脉冲的下降沿,那么也就可能少记了一个脉冲,这也是频率测量误差的来源之一。下面附上代码:
#include <reg52.h>
unsigned int count_1s=0;
unsigned long Frequency=0;
unsigned long Count=0;
unsigned char Flag=0;
sbit LED1=P1^0;
sbit LED2=P1^1;
sbit LED3=P1^2;
sfr16 DPTR=0x82;
sbit Wei_Select=P2^6;
sbit Duan_Select=P2^5;
char Display_Code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
char Wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
void delay_ms(unsigned int Xms)
{
unsigned int i=0,j=0;
for(i=Xms;i>0;i--)
for(j=110;j>0;j--);
}
void display(unsigned int position,unsigned long number)
{
Duan_Select=0;
Wei_Select=1;
P0=Wei[position-1];
Wei_Select=0;
Duan_Select=1;
P0=Display_Code[number];
delay_ms(3);
}
void InitTimer(void)
{
TMOD = 0x51;
TH0 = 0xDC;
TL0 = 0;
EA = 1;
ET0 = 1;
TR0=1;
TH1=0;
TL1=0;
ET1=1;
TR1=1;
}
void Timer0() interrupt 1
{
TH0 = 0xDC;
TL0 = 0;
count_1s++;
if(count_1s==100)
{
LED1=~LED1;
count_1s=0;
EA=0;
Flag=1;
}
}
void Timer1() interrupt 3
{
TH1=0;
TL1=0;
LED2=~LED2;
Count++;
}
void Show_Frequency(unsigned long X)
{
unsigned int ge=0,shi=0,bai=0,qian=0,wan=0;
ge=X%10;
shi=X/10%10;
bai=X/100%10;
qian=X/1000%10;
wan=X/10000%10;
display(8,ge);
display(7,shi);
display(6,bai);
display(5,qian);
display(4,wan);
}
void main()
{
InitTimer();
while(1)
{
if(Flag==1)
{
DPL=TL1;
DPH=TH1;
Frequency=Count*65535+DPTR;
TH1=0;
TL1=0;
Flag=0;
Count=0;
EA=1;
}
Show_Frequency(Frequency);
}
}
|