📄 51
字号:
#include<reg51.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
uchar t=0,yichu=0,fenpin;
sbit B153=P2^0; //74153输出B端
sbit A153=P2^1; //74153输出A端
sbit GATE=P2^6; //门端
sbit CLR=P2^7; //清除端
sbit P33=P3^3; //中断输入
void delay(void); //1s软件延时
uchar table(uchar x); //字形代码查表输出
void display(float f); //以测出的频率串行输出显示
void cepin(void); //频率测试
void panduan(void); //频率判断
void main(void) //主函数
{
IE=0x8a;
while(1)
{
panduan(); //判断原频率属于哪个范围,并调用相应函数测其频率
delay();
}
}
void panduan(void) //频率判断
{
float zhouqi;
B153=1;
A153=1;
TMOD=0x51;
TH0=0xce; //定时器0=12.8ms
TL0=0;
TH1=0xff; //计数器1=100个脉冲
TL1=0x9c;
TCON=0x50;
while(yichu==0);
TCON=0;
if(yichu==1) //计数器先溢出:在12.8ms内测得的脉冲过多,说明频率较高
{
fenpin=128; //转为测128分频后的频率
cepin();
}
else //计时器先溢出:100个脉冲的时间比较短,即频率较低,可以减少分频数
{
yichu=0;
B153=1;
A153=0;
TH0=0xc1; //定时器0=16ms
TL0=0x80;
TH1=0xff; //计数器1=100个脉冲
TL1=0x9c;
TCON=0x50;
while(yichu==0);
TCON=0;
if(yichu==1) //计数器先溢出:在16ms内测得的脉冲过多,说明频率较高
{
fenpin=16; //转为测16分频后的频率
cepin();
}
else //计时器先溢出:100个脉冲的时间比较短,即频率较低,用2分频测周期
{
B153=0; //以下是测周期部分
A153=0;
TH0=0;
TL0=0;
t=0;
TMOD=0x09;
TR0=1;
GATE=1;
while(P33==0);
GATE=0;
while(P33==1);
TR0=0;
zhouqi=(TH0*256+t*65536+TL0)/1000000.0;
if(zhouqi<0.001) //若周期太小,则转为测原频率
{
fenpin=1;
B153=0;
A153=0;
cepin();
}
else
{
display((1.0/zhouqi));
}
}
}
}
void cepin(void) //频率测试
{
uchar i;
float sj;
ulong js; //时间、计数的拼音首字母
float f; //f为频率
TMOD=0xd9;
t=0;
TH0=0;
TL0=0;
TH1=0;
TL1=0;
GATE=0;
TCON=0x50;
GATE=1;
delay();
GATE=0;
for(i=0;i<250;i++); //延时1ms
sj=((float)(TH0*256+t*65536+TL0))/1000000.0;//时间
js=(long)TH1*256+TL1+1; //脉冲数
f=(js/sj)*fenpin; //频率
display(f); //显示
}
void t0(void) interrupt 1 //T0中断服务程序
{
t++; //t加1
yichu=2; //定时器0溢出,yichu=2
}
void t1(void) interrupt 3 //计数器1溢出,yichu=1
{
TCON=0;
yichu=1;
TH1=0xff;
TL1=0xff;
}
void display(float f) //以测出的频率串行输出显示
{
ulong x;
uchar i=0,j,a[5]={0,0,0,0,0};
if(f!=0) //频率不为0
{
if((f<10000)&&(f>1)) //正常显示1~9999
{
if(f>1000)
f=f-1; //软件修正频率偏差
while(f<1000) //数据小时 扩大 并记录指数
{
f=f*10;
i++;
}
x=f*10; //再扩大10后 取原来的小数
a[4]=x%10;
if(a[4]>=5) //小数 四舍五入
f=f+1;
x=f;
a[1]=x%10; //个
a[2]=(x/10)%10; //十
a[3]=(x/100)%10; //百
a[4]=(x/1000)%10; //千
for(j=0;j<5;j++) //查字形代码
{
a[j]=table(a[j]);
}
a[i+1]++; //
a[0]=0; //指数为0
}
else if(f>=10000) //以科学计数法显示
{
while(f>=1000) //大于1千
{
f=f/10; //除10 缩小10倍 记录指数
i++;
}
x=f;
a[4]=(uchar)((float)((f-x))*10);
if(a[4]>=5)
x++; //四舍五入
a[2]=x%10; //个
a[3]=(x/10)%10; //十
a[4]=(x/100)%10; //百
a[0]=i+2; //指数
for(j=0;j<5;j++)
{
a[j]=table(a[j]);
}
a[4]++;
a[1]=0x7c;
}
else
{
x=f*10000; //频率值小于1
if((x%10)>=5)
x=x+10; //四舍五入
x=x/10;
a[1]=x%10;
a[2]=(x/10)%10;
a[3]=(x/100)%10;
a[4]=(x/1000)%10;
for(j=0;j<5;j++)
{
a[j]=table(a[j]);
}
a[4]++;
a[0]=0;
}
}
for(j=0;j<5;j++) //串行发送显示
{
SBUF=a[j];
while(TI==0);
}
}
void delay(void) //1s软件延时
{
uint i=500,j;
while(i)
{
i--;
j=250;
while(j)
{
j--;
}
}
}
uchar table(uchar x) //字形代码查表输出
{
uchar code n[10]={0xee,0x82,0xdc,0xd6,0xb2,0x76,0x7e,0xc2,0xfe,0xf6};
return(n[x]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -