⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 liulei.c

📁 我暑假课程设计做的题目,电子频率计的设计 包括源码和电路图 还有实物照片
💻 C
字号:
/*本程序显示的结果和实验室里信号发生器的显示一致,
  根据频率的不同分别显示到小数点后一位,两位,或三位。*/
#include <reg51.h>
#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long

sbit P24=P2^4;
uchar time=80;//测频时定时时间4S(80*0.05)
uchar j=0;//显示位数
uint count=0;//计数值的高位
uchar putout[8];//显示缓存
uchar FLAG;//测量方式标志
float temp;//数据处理时的中间结果
void out(void);

void mea_freq(void) interrupt 0 using 0  //外中断0服务子程序
{FLAG=1;//测频方式置标志FLAG为1
 P0=0;//灭数码管 
 IE1=0;IT1=1;IE0=0;IT0=1;//关TRO,TR1,置外中断请求触发方式为脉冲后沿负跳有效 
 TMOD=0X51;//定时器T0工作方式1,计数器T1工作方式1
 TH0=0X3C; TL0=0XB0;
 TH1=0;    TL1=0;
 //TCON=0X55;//开TR0,TR1
  TR0=1;TR1=1;
 return;
}

void mea_cycle(void) interrupt 2 using 0  //外中断1服务子程序
{FLAG=0;//测周方式置标志FLAG为0
 P0=0;//灭数码管
// TCON=0X05;//关TRO,TR1,置外中断请求触发方式为脉冲后沿负跳有效
  IE1=0;IT1=1;IE0=0;IT0=1;
 TMOD=0X61;//计时器T0工作方式1,计数器T1工作方式2
 TH0=0;   TL0=0;
 TH1=251; TL1=251;
 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)//tiem=0则定时时间到
    {//TCON=0X05;//关TR0,TR1
	TR0=0;TR1=0;
     out();//数据处理
     //下一次测量初始化
     TH0=0X3C; TL0=0XB0;
     TH1=0;    TL1=0;
     count=0;  time=80;
     //TCON=0X55;//开TR0,TR1,开始定时,计数
	 TR0=1;TR1=1;
    }
  }
 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
  TR0=0;TR1=0;
   out();//数据处理
   //下一次测量初始化
   TH0=0;   TL0=0;
   TH1=251; TL1=251;
   TR1=1;   count=0;
   while(252-TL1) ;
   TR0=1;
  }
 return;
}

void delay_ms(uchar i)  //延时子程序 
{uchar k;
 while(i--)
  {for(k=0;k<125;k++) ; }
 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);
   //频率>=1000,则直接取整,只显示整数
   else result=(ulong)temp;
  }
 else //测周方式的数据处理,计算1个脉冲的时间后取倒数	
  {temp=4e+6/(count*65536+TH0*256+TL0);
   if(temp<10)  result=(ulong)(temp*1000);//一般在频率<10时用测周方式,则总显示三位小数
   else if(temp<100)   result=(ulong)(temp*100);
   else if(temp<1000)   result=(ulong)(temp*10);
   else result=(ulong)temp;
  }
 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 display(void)
{uchar n;
 uint bit_secl[8]={0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10};
 for(n=0;n<j;n++) //显示数字
  {
   P0=bit_secl[n];
   P2=putout[n];
   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)
{
 FLAG=1;//默认测量方式为测频
 //TCON=0X05;//关TRO,TR1,置外中断请求触发方式为脉冲后沿负跳有效
 TR0=0;TR1=0; 
 TMOD=0X51;//定时器0方式1,计数器1方式1
 count=0;//计数值的高位初始化
 TH0=0X3C;  TL0=0XB0;
 TH1=0;     TL1=0;
 EA=1;ET1=1;ET0=1; EX1=1;EX0=1;//允许中断
 TR0=1;TR1=1; IT1=1;IT0=1; //开始定时记数
 for(;;)
  {display();}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -