1. 主程序详单
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit P24=P2^4;
uchar time=80;
uchar j=0; //显示位数
uint count=0; //计数值的高位
uchar putout[8]; //显示缓存
uchar FLAG; //测量方式标志
float temp; //数据处理时的中间结果
void delay_ms(uchar i) //延时10MS子程序
{
uchar j;
while(i--)
{for(j=0;j<125;j++);
}
return;
}
void out(void) using 3
{
ulong result;
uchar i;
if(FLAG) //测频方式的数据处理,计算1S的脉冲数
{ temp=(float)(count*65536+TH1*256+TL1)/4; //频率<10,则扩大1000倍后取整,即显示三位小数
if(temp<10)
result=(ulong)(temp*1000); //10<=频率<100。则扩大100倍后取整,即显示两位小数
else if(temp<100)
result=(ulong)(temp*100); //100<=频率=<1000,则扩大10倍后取整,即显示一位小数
else if(temp<1000)
result=(ulong)(temp*10);
else //频率>=10000,则直接取整,只显示整数
result=(ulong)temp;
}
else //测周方式的数据处理,计算1个脉冲的时间后取倒数
{temp=4e+6/(count*65536+TH0*256+TL0);
result=(ulong)(temp*1000); //一般在频率<10时测周方式,则总显示三位小数
}
i=0;
j=0;
while(result) //数据输出到显示缓冲区
{putout[i]=result%10;
result=result/10;
i++;
j++;
}
while(j<4)
putout[j++]=0; //所得结果只有小数位时补置显示缓冲区地位至putout[3]位为0
return;
}
void mea_freq(void) interrupt 0 using 0 //外中断0服务子程序
{FLAG=1; //测频方式置标志FLAG为1
P0=0; //灭数码管
TCON=0X05; //关TR0,TR1,置外中断触发方式为脉冲后沿负跳有效
TMOD=0X51; //定时器T0工作方式1,计数器T1工作方式1
TH0=0X3C;
TL0=0XB0;
TH1=0;
TL1=0;
TCON=0X55; //开TRO,TR1
return;
}
void mea_cycle(void) interrupt 2 using 0 //外中断1服务子程序
{
FLAG=0; //测周方式置标志FLAG为0
P0=0; //灭数码管
TCON=0x05; //关TR0,TR1,置外中断触发方式为脉冲后沿负跳有效
TMOD=0x61; //定时器T0工作方式1,计数器T1工作方式2
TH1=251;
TL1=251;
TH0=0;
TL0=0;
count=0;
TR1=1; //开计数器T1
while(252-TL1); //等待一个负跳变的到来
TR0=1; //来了一个负跳变,开始计时。计4个脉冲的时间
return;
}
void t0_service(void) interrupt 1 using 1 //定时器0中断服务子程序
{
P0=0; // 灭数码管
if(FLAG) //测频方式,定时器0溢出,判断是否时间到
{time--;
TH0=0X3C;
TL0=0XC8;
if(!time) //time=0,则定时时间到
{TCON=0X05; //关TR0,TR1
out();//数据处理 //下一次测量初始化
TH0=0X3C;
TL0=0XB0;
TH1=0;
TL1=0;
count=0;
time=80;
TCON=0X55; //开TR0,TR1,开始定时,计数
}
}
else//测周方式,计时器0溢出,计数高位加1
count++;
return;
}
void t1_service(void) interrupt 3 using 2 //计数器1中断服务子程序
{
P0=0; //灭数码管
if(FLAG) //测频方式,计数器1溢出,计数高位加1
count++;
else//测周方式,计4个脉冲到后溢出
{
TCON=0X05; //关TR0,TR1
out();//数据处理//下一次测量初始化
TH0=0;
TL0=0;
TH1=251;
TL1=251;
TR1=1;
count=0;
while(252-TL1);
TR0=1;
}
return;
}
void display(void) //显示子函数。
{
uchar n;
uchar bit_secl;
if(j<=4)
{bit_secl=0X08;
for(n=0;n<j;n++)//显示数字
{P0=bit_secl;
P2=putout[n];
bit_secl=bit_secl>>1;
delay_ms(1);
}
}
else//频率较高时,多于四位的显示。
{bit_secl=0X08;
for(n=0;n<4;n++)
{P0=bit_secl;
P2=putout[n];
bit_secl=bit_secl>>1;
delay_ms(1);
}
bit_secl=0X80;
for(n=4;n<j;n++)
{P0=bit_secl;
P2=putout[n];
bit_secl=bit_secl>>1;
delay_ms(1);
}
}//显示小数点,P2口P24选中数码管的小数点
if(temp<10)
{P0=0X01;
P24=1;
}//位选选中D3位的数码管
else if(temp<100)
{P0=0X02;
P24=1;
}//位选选中D2位数码管
else if(temp<1000)
{P0=0X04;
P24=1;
}//位选选中D1位数码管
delay_ms(1);
return;
}
void main(void)