📄 frequency.c
字号:
# include<reg52.h>
# include<stdio.h>
# include<intrins.h>
# define uchar unsigned char
# define uint unsigned int
uint n0; //计数次数
uint n1;
uint n2;
uint n3;
uint n4;
uint n5;
uchar n6; //产生0.4S阀门
float s;
uchar a[2]; //装整数
uchar b[6]; //装小数
uchar cmd;
uchar state; //模式信号
bit flag0; //测频段信号
bit flag1; //占空比模式下测脉宽信号
//*********************************************************//
// 延时子程序 //
//*********************************************************//
void delay(unsigned char n)
{unsigned char i;
for(i=0;i<n;i++);
}
//*********************************************************//
// 按键子程序 //
//*********************************************************//
void key()
{
unsigned char key;
key=(P2&&0X0F);
delay(711);
delay(711);
switch(key)
{case 0X0E: state=1;
break;
case 0X0D: state=2;
break;
case 0X0B: state=3;
break;
case 0X07: state=4;
break;
default: state=0;
}
}
//*********************************************************//
// 数据处理子程序 //
//*********************************************************//
void data_process()
{float tcy=12/10*1000000;
switch(state)
{case 1: if(cmd==0X40)
s=1/(2*tcy*n3/2); //HZ
else if(cmd==0X20)
s=1/(2*tcy*n3/1024*1000); //KHZ
else if(cmd==0X10)
s=1/(2*tcy*n3/131072*1000000); //MHZ
break;
case 2: if(P1==0X40)
s=2*tcy*n3/2; //s
else if(P1==0X20)
s=2*tcy*n3/1024*1000; //ms
else if(P1==0X10)
s=2*tcy*n3/131072*1000000; //us
break;
case 3: s=tcy*n5;
break;
case 4: if(cmd==0X40)
s=n5/n3;
else if(cmd==0x20)
s=512*n5/n3;
else if(cmd==0x10)
s=65536*n5/n3;
}
}
//*********************************************************//
// 数据转换子程序 //
//*********************************************************//
void zhuan_huan()
{a[0]=s/10;
a[1]=s/1-a[0]*10;
s=(s-a[0]*10-a[1])*1000000;
b[0]=s/100000;
b[1]=s/10000-b[0]*10;
b[2]=s/1000-b[1]*10-b[0]*100;
b[3]=s/100-b[2]*10-b[1]*100-b[0]*1000;
b[4]=s/10-b[3]*10-b[2]*100-b[1]*1000-b[0]*10000;
b[5]=s/1-b[4]*10-b[3]*100-b[2]*1000-b[1]*10000-b[0]*100000;
}
//*********************************************************//
// LCD显示子程序 //
//*********************************************************//
sbit dc=P1^4; //RS
sbit rw=P1^5; //RW
sbit cs=P1^6; //E
sfr lcdbus=0x80; //D0--D7
void soft_nop(){}
/****************检查LCD忙*******************/
bit lcd_checkbusy() /*检查LCD 忙*/
{register lcdstate;
dc=0; /*dc=1为数据,=0 为命令.*/
rw=1; /*rw=1为读,=0为写.*/
cs=1; /*cs=1选通.*/
soft_nop();
lcdstate=lcdbus;
cs=0;
return((bit)(lcdstate&0x80));
}
/***************写LCD命令*******************/
void lcd_wrcmd(uchar lcdcmd)
{while(lcd_checkbusy());
dc=0; /*dc=1为数据,=0 为命令.*/
rw=0; /*rw=1为读,=0为写.*/
cs=1; /*cs=1选通.*/
lcdbus=lcdcmd;
soft_nop();
cs=0;
}
/**************在当前显示位置显示数据********************/
void lcd_wrdata(char lcddata)
{while(lcd_checkbusy());
dc=1; /*dc=1为数据,=0 为命令.*/
rw=0; /*rw=1为读,=0为写.*/
cs=1; /*cs=1选通.*/
lcdbus=lcddata;
soft_nop();
cs=0;
}
/*************在当前显示位置显示LCD 字符串***************/
void lcd_string(char *strpoint)
{ register i=0;
while(strpoint[i]!=0)
{lcd_wrdata(strpoint[i]);
i++;
}
}
/**********************初始化************************/
void lcd_init()
{lcd_wrcmd(0x38); /*设置8 位格式,2行,5*7*/
lcd_wrcmd(0x0c); /*整体显示,关光标,不闪烁*/
lcd_wrcmd(0x06); /*设定输入方式,增量不移位*/
lcd_wrcmd(0x01); /*清除显示*/
}
/***********************主函数***********************/
void lcd()
{uchar i;
lcd_init();
delay(711);
delay(711);
switch(state) //送模式和单位
{
case 1: lcd_string("FREQUENCY");
lcd_wrcmd(0X8C);
if(cmd==0X40)
lcd_string("HZ");
else if(cmd==0X20)
lcd_string("KHZ");
else
lcd_string("MHZ");
break;
case 2: lcd_string("PERIOD");
lcd_wrcmd(0X8C);
if(cmd==0X40)
lcd_string("S");
else if(cmd==0X20)
lcd_string("MS");
else
lcd_string("US");
break;
case 3: lcd_string("MAIKUAN");
lcd_wrcmd(0X8C);
lcd_string("s");
break;
case 4: lcd_string("ZHANKONGBI");
}
lcd_wrcmd(0XC3); //送整数
for(i=0;i<2;i++)
{a[i]=a[i]+0X30;
lcd_wrdata(a[i]);
}
lcd_wrdata(46); //送小数点
for(i=0;i<6;i++) //送小数位
{b[i]=b[i]+0X30;
lcd_wrdata(b[i]);
}
}
//*********************************************************//
// 定时器0中断 //
//*********************************************************//
void timer0() interrupt 1
{
n0+=1;
}
//*********************************************************//
// 定时器1中断 //
//*********************************************************//
void timer1() interrupt 3
{if(flag0==1)
{ n6+=1;
if(n6==50)
{TR0=0;TR1=0;
flag0=0;
}
}
else if(flag1==1)
{n4+=1;
flag1=0;
}
else
n2+=1;
}
//*********************************************************//
// 主函数 //
//*********************************************************//
void main()
{
IE=0XBF; //中断全开
IP=0X08; //定时器1优先级最高
P1=0; //关控制位
for(;;)
{
P1=0;
state=0;
flag0=0;flag1=0;
n0=0;n2=0;n4=0;n6=0;
do{
key();
}while(state==0);
if(state!=3)
{flag0=1;
TMOD=0X26; //T0工作在计数器方式2下,T1工作在定时器方式2下
TH1=0X05; //产生8MS*50的阀门,未算
TL1=0XF5;
TH0=0;
TL0=0;
TR1=1;
TR0=1;
do{}while(flag1==1);
n1=n0*8192+TL0;
TMOD=0XA0; //T1做定时器测高电平宽度,由INT1控制
TH1=0;
TL1=0;
TR1=1;
if(n1<=1) //送控制信号
P1=0X40;
else if(n1<=1000)
P1=0X20;
else
P1=0X10;
cmd=P1;
} //否则为测脉宽方式
else
{TMOD=0XA0; //T1做定时器测高电平宽度,由INT1控制
TH1=0;
TL1=0;
TR1=1;
P1=0X80;
}
do{}while(INT1==1);
n3=n2*8192+TL0;
if(state==4) //在占空比下,先测周期,再测脉宽
{flag1=1;
TMOD=0XA0;
TH1=0;
TL1=0;
TR1=1;
P1=0X80;
do{}while(INT1==1);
flag1=0;
n5=n4*8192+TL0;
}
data_process();
zhuan_huan();
lcd();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -