原创 频率计0.1~10MHZ

2010-4-19 18:25 1426 3 3 分类: MCU/ 嵌入式


#include<reg52.h>
#include<math.h>
unsigned char t="0",yichu=0,fenpin;
#define uchar unsigned char
#define uint unsigned int
sbit s0=P2^0;
sbit s1=P2^1;
sbit s2=P2^2;
sbit GATE="P2"^4;
//sbit CLR="P2"^7;
sbit P33=P3^3;
sbit led_wei=P2^7;
sbit led_duan=P2^6;
uchar bin="0";
//uchar code table_wei[]={0x01,0x02,0x04,0x08,0x10,0x20};
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9的共阳极代码
//unsigned char a[5]={0,0,0,0,0};



void delay1(uint z)
{
 uint x,y;
 for(x=100;x>0;x--)
  for(y=z;y>0;y--);


}
//定时器0
void t0(void)interrupt 1
{
 t++;
 yichu=2;        //定时器0溢出,yichu=2
       



}


//计数器1
void t1(void)interrupt 3    //计数器1溢出,yichu=1
{
 TCON=0;
 yichu=1;
 TH1=0xff;
 TL1=0xff;
 P0=0xff;
  
}


 



void delay(void)      //1s软件延时
{
 unsigned int i="500",j;
 while(i)
 {
  i--;
  j=249;
  while(j)
  {
   j--;
  }
 }
}


display(float f)      //以测出的频率串行输出
{
unsigned long x;
unsigned char a[5]={0,0,0,0,0},i=0,j;
if(f!=0)
{
 if((f<=99999)&&(f>1))     //正常显示
 {
  if(f>10000) f="f"+2;     //软件修正频率偏差
  if(f>30000) f="f"+10;
  if(f>40000) f="f"+10;


  while(f<9999)
  {
   f=f*10;
   i++;
  }
   x=f*100;
   a[4]=x%10;
   if(a[4]>=5)f=f+1;                //软件修正频率偏差
       x=f;
   a[0]=x%10;
   a[1]=(x/10)%10;
   a[2]=(x/100)%10;
   a[3]=(x/1000)%10;
   a[4]=(x/10000)%10;
   for(j=0;j<5;j++)
   {
    a[j]=table[a[j]];
   }
   
  // a[i+1]++;
   //a[0]=0;
  // a[0]=0xc0;
 }
  else
   if(f>=100000)      //以科学计数法显示
   {   
    f=f+8;
    while(f>=99999)
     {
      f=f/10;
      i++;
     }
    x=f;
    a[4]=(unsigned char)((float)((f-x))*10);
    if(a[4]>=5)   x++;                    //四舍五入


    //x=(x<<6)+(x<<5)+(x<<2);
    //x=x*100;
    a[0]=x%10+2;
    a[1]=(x/10)%10;
    a[2]=(x/100)%10;
    a[3]=(x/1000)%10;
    a[4]=(x/10000)%10;
    //a[0]=i+2;
    for(j=0;j<5;j++)
    {
     a[j]=table[a[j]];
    }
    //a[4]++;
    //a[1]=0x80;
   }
   else
    {
     x=f*10000;       //频率值小于1
     if((x%10)>=5)x=x+10; //四舍五入
     a[0]=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]=0xc0;
    }
}
   for(j=0;j<5;j++)   //串行
    {
     SBUF=a[j];
     while(TI==0);
     //TI=0;
     
    }
}
void cepin()
{
 unsigned char i;
 float sj;
 unsigned long js;//时间、计数的拼音首字母
 float f;  //f为频率
 TMOD=0xd9;      //开外部中断   方式3时T1停止工作  T0工作在方式1
 t=0;
 TH0=0;
 TL0=0;
 TH1=0;
 TL1=0;
 GATE=0;
 TCON=0x50;//开T0
 GATE=1;
 delay();    //开通1S  
 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 panduan()

 float zhouqi;
 s0=1; //256分频
 s1=1;
 s2=1;
 TMOD=0x51;  //T1计数,方式1.   T0定时,方式1  
 TH0=0xce;  //定时器0=12.8ms ce00H=(65536-12800)h
 TL0=0;
 TH1=0xff;  //计数器1=100个脉冲
 TL1=0x9c;
 TCON=0x50;        //启动T0,T1
 while(yichu==0);
     TCON=0;
 if(yichu==1) //计数器先溢出:在12.8ms内测得的脉冲过多,说明频率较高  f>2M
  {
           fenpin="256";//转为测256分频后的频率,
     cepin();
  }
 else    //计时器先溢出:100个脉冲的时间比较短,即频率较低,可以减少分频数,即12.8ms中测得脉冲过少.f<2M
  {
   yichu=0;
   s0=0;   //128分频
   s1=1;
   s2=1;
   TH0=0xc1; //定时器0=16ms
   TL0=0x80;
   TH1=0xff; //计数器1=100个脉冲
   TL1=0x9c;
   TCON=0x50;
   while(yichu==0);
   TCON=0;
   if(yichu==1)   //计数器先溢出:在16ms内测得的脉冲过多,说明频率较高,800k<f<2M
   {
    fenpin=128;//转为测64分频后的频率
    cepin();
   }
    else
    {
       yichu=0;
      s0=1;   //64分频
      s1=0;
      s2=1;
      TH0=0xc1; //定时器0=16ms
      TL0=0x80;
      TH1=0xff; //计数器1=100个脉冲
      TL1=0x9c;
      TCON=0x50;
      while(yichu==0);
      TCON=0;
      if(yichu==1)     //f>400kHZ
      {
       fenpin=64;
       cepin();
      } 
         else   //计时器先溢出:100个脉冲的时间比较短,即频率较低,用2分频测周期,f<400kHZ.
       {
         yichu=0;
         s0=0;   //32分频
         s1=0;
         s2=1;
         TH0=0xb1; //定时器0=20ms
         TL0=0xe0;
         TH1=0xff; //计数器1=100个脉冲
         TL1=0x9c;
         TCON=0x50;
         while(yichu==0);
         TCON=0;
         if(yichu==1)   //计数器先溢出:在16ms内测得的脉冲过多,说明频率较高400k>f>160k
         {
          fenpin=32;//转为测32分频后的频率
          cepin();
         }
          else                       //f<160k
          {
             yichu=0;
            s0=1;   //16分频
            s1=1;
            s2=0;
            TH0=0xc1; //定时器0=16ms
            TL0=0x80;
            TH1=0xff; //计数器1=100个脉冲
            TL1=0x9c;
            TCON=0x50;
            while(yichu==0);
            TCON=0;
            if(yichu==1)     //160k>f>100kHZ
            {  
             fenpin=16;
             cepin();
           
            }  
              else                       //f<100k
             {
                yichu=0;
               s0=1;   //2分频
               s1=0;
               s2=0;
               TH0=0xc1; //定时器0=16ms
               TL0=0x80;
               TH1=0xff; //计数器1=100个脉冲
               TL1=0x9c;
               TCON=0x50;
               while(yichu==0);
               TCON=0;
               if(yichu==1)     //160k>f>12kHZ
               {  
                fenpin=2;
                cepin();
              
               } 
                  else   //计时器先溢出:100个脉冲的时间比较短,即频率较低,用1分频测周期,f<1kHZ.
                {
                    s0=0; //以下是测周期部分
                 s1=0;
                 s2=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) //若周期太小,则转为测原频率,即频率大于1kHZ
                 {
                  fenpin=1;
                  s0=0;
                  s1=0;
                  s2=0;
                  cepin();
                 }
                  else
                  {
                   display((1.0/zhouqi));
                  }
                    }
              }
                }
        }


     }
 
 }
}
main()
{
IE=0x8a;
while(1)
 {
 panduan(); //判断原频率属于哪个范围,并调用相应函数测其频率
// delay1(100);
 }
}


 


 


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条