原创 基于52单片机的自动量程转换测频仪的设计

2008-11-14 20:55 4782 5 7 分类: MCU/ 嵌入式

  打开电脑发现以前曾经做过一个测频仪的东西!是大3时的单片机课程设计吧!翻出来回顾一下吧!


  总的来说这个东西主要难点是在于小信号的调理方面!在我认为在做一些系统项目中,其实小信号的系统前调理是一件非常麻烦的事。因为我们自己用的线性电源,或多或少是会给小信号带来干扰的,再经放大后,干扰是一件让人头疼的东西!!所以我现在个人觉得,自己做的电源是干扰的一大来源!在市场上买的一些廉价电源更是如此,自己用示波器测一下,纹波吓得死人了。还有一点就是元器件的选型。测频仪的测频范围当然是越广越好,所以放大器,一定要选比较高速的,而比较器也是如此,别用运放做比较器(工作在放大饱和区),它的速度(带宽)不如专门的比较器好。比较器一定要搭成迟滞比较电路,这样才能抗电源纹波干扰。至于测频的方法,可用低频侧周,高频测频的经典方法!


一下是具体的设计:


2.1 放大电路的设计 集成芯片选择:AD811
芯片特点:电流反馈型宽带运放,其单位增益带宽很宽,高达140MHZ。
注意要点:应注意电路中各电阻电容应紧密靠近AD811的相应引脚,去耦电容必不可少。特意加了两个隔直电容,以便滤除直流的影响。整个系统单电源供电,提高稳定性。
放大倍数计算公式:
Vin = Vout * R4 / (R13 + R4)
即 Vout / Vin = (R13 + R4) / R4 = (510 + 51) / 51 = 11。


点击看大图


2.2 整形电路的设计
单片机只能检测到方波信号,为了能测量方波以外的信号。我们设计了整形电路,通过比较器LM339对信号进行整形编程方波信号。整形电路的原理图如图5所示:
注意要点:加入正反馈电阻构成迟滞比较器。如果输入信号Uin在门限值附近有微小的干扰,则输出电压就会产生相应的抖动(起伏)。在电路中引入正反馈可以克服这一缺点。


d1ca7160-5a00-4e2c-b16e-f1f05636f20f.png


 


2.3分频电路的设计


为了能达到扩展部分的要求被测频率要达到10MHZ,故要对其进行分频,SN74HC390是高速分频器件,最高分频频率为50MHz。每片SN74HC390可实现100分频,采用两片串联,可实现对信号的1000分频,经分频后的数字信号频率较低,约8kHz以下,可由单片机直接计数。分频电路如图6示


点击看大图


 


 


 


2.4分频控制电路设计


单片机不能检测高频信号,为了满足设计要求中的能测量10MHZ的信号,我们设计了分频电路。并且为了满足自动换挡的要求,我们选用模拟开关CD4051对信号进行分频的倍数的控制。CD4051真值表如左图示,分频控制电路如右图示。


a0ac2369-d5b4-4ddd-8c57-d32bef21f6ff.png


2e6fe2b1-2e01-47d1-a68a-15dbaa82aa32.png


软件设计


 


通常采用的方法有低频端测周高频端测频和多周期同步测量频率。采用低频端测周高频端测频时存在中界频率测量误差很大即测量死区问题,也就是说不论低端和高端测量准确度有多高,中界频率测量误差总是最大。因此从理论上讲频率的测量准确度很难提高到某个数量级;多周期同步测频法则不存在这样的问题,只要周期数足够大,测量的准确度总可以提高到一定程度。
本次设计测频采用多周期同步测频法。被测信号接外部中断口INT0,外部信号在下降沿触发中断。此时计数器开始计时。如下图所示,若在中断中计得被测脉冲的个数为N。而定时器0计得的标准脉冲数为M。显然如下等式成立:
  M/fx=N/f0
得:fx=(M*f0)/N
这样便算出了被测信号的频率值。


点击看大图


4369c678-b6e9-4ee7-8468-94584bb6590b.png


47b39d76-f6c6-4c91-88be-909c6d134e1d.jpg


系统软件流程


void main(void)
{
  unsigned char key_value;
  CD4051_slect(0);//CDCO51初始化
  Clr_Scr();
  init_lcd();//液晶初始化
  welcome();//欢迎界面
  while(1)
  {
  key_value=scan_key();//键盘扫描
 if(key_value==0x03)//等待开始键
 break;
 }
 Clr_Scr();
 Msg();
 while(1)//数据实时采集
 {}
  }


41a83eda-ea5e-43ec-addf-2f3723bc59bb.png


附件:源代码


#include <reg52.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include<intrins.h>
#include"Port_Config.h"
#include"data.h"
/******************************lcd引脚定义*****************/
/* Define the register command code */
#define Disp_On  0x3f
#define Disp_Off 0x3e
#define Col_Add  0x40
#define Page_Add 0xb8
#define Start_Line 0xc0



unsigned char col,row;    //全局变量,在输出字符窜是有用
int  Num="0";
double const const_num=1000000;
unsigned flg_int0=0;
int flag_div=0,flag_div100=0,flag_khz=0,flag_mhz=0,flag_kkhz=0,flag_mmhz=0;
double fre_value ; //测的频率值
unsigned char code str_hz[]="( HZ)";
unsigned char code str_khz[]="(KHZ)";
unsigned char code str_mhz[]="(MHZ)";
unsigned char dis[8];


/*------------------CD4051选择通道------------------------------*/
void CD4051_slect(int v)
{
  switch(v)
  {
   case 0:CD4015_0=0;CD4015_1=0;CD4015_2=0;break;//通道0 
   case 1:CD4015_0=1;CD4015_1=0;CD4015_2=0;break;//通道1 
    case 2:CD4015_0=0;CD4015_1=1;CD4015_2=0;break;//通道2 
   }
}



/********************************lcd部分***************************************************/



/*------------------延时子程序-----------------------------*/
void delay(unsigned int t)
{
unsigned int i,j;
for(i=0;i<t;i++)
for(j=0;j<10;j++)
;
}


/*------------------写命令到LCD------------------------------*/
void write_com(unsigned char cmdcode)
{


Di=0;
RW=0;


Lcd_Bus=cmdcode;
delay(0);
Enable=1;
delay(0);
Enable=0;
}


/*-------------------写数据到LCD----------------------------*/


void write_data(unsigned char Dispdata)
{


Di=1;
RW=0;


Lcd_Bus=Dispdata;
delay(0);
Enable=1;
delay(0);
Enable=0;
}


/*-------------------读LCD数据----------------------------*/


unsigned char read_data()
{
unsigned char tmpin;


Di=1;
RW=1;
delay(0);
Enable=1;
delay(0);
Enable=0;


tmpin=Lcd_Bus;


return tmpin;
}


/*------------------清除内存---------------*/
void Clr_Scr()
{
unsigned char j,k;
Mcs=1;Scs=1;
 write_com(Page_Add+0);
 write_com(Col_Add+0);


 for(k=0;k<8;k++){
write_com(Page_Add+k);
  for(j=0;j<64;j++)write_data(0x00);
 }
}



/*---------------------指定位置显示汉字8*16-----------------------*/


void hz_disp8(unsigned char pag,unsigned char col, unsigned char code *hzk)
{
unsigned char j="0",i=0;
for(j=0;j<2;j++){
write_com(Page_Add+pag+j);
write_com(Col_Add+col);
for(i=0;i<8;i++) write_data(hzk[8*j+i]);
}
}
/*---------------------指定位置显示汉字16*16-----------------------*/


void hz_disp16(unsigned char pag,unsigned char col, unsigned char code *hzk)
{
unsigned char j="0",i=0;
for(j=0;j<2;j++){
write_com(Page_Add+pag+j);
write_com(Col_Add+col);
for(i=0;i<16;i++) write_data(hzk[16*j+i]);
}
}
/*---------------------指定位置显示汉字32*16-----------------------*/


void hz_disp32(unsigned char pag,unsigned char col, unsigned char code *hzk)
{
unsigned char j="0",i=0;
for(j=0;j<2;j++){
write_com(Page_Add+pag+j);
write_com(Col_Add+col);
for(i=0;i<32;i++) write_data(hzk[32*j+i]);
}
}


/*------------------初始化LCD屏--------------------------*/
void init_lcd()
{
Lcd_Rst=0;
delay(100);
Lcd_Rst=1;
delay(100);


Mcs=1;
Scs=1;


delay(100);
write_com(Disp_Off);
write_com(Page_Add+0);
write_com(Start_Line+0);
write_com(Col_Add+0);
write_com(Disp_On);
}


 


/*-------------------------半角字符点阵码数据输出-----------------------------------*/
void Putedot(unsigned char Order)
{
 unsigned char cbyte, j="0",i=0;
 int x;
 x=Order * 0x10; 
 for(j=0;j<2;j++)
        {
         write_com(Page_Add+row+j);
         write_com(Col_Add+col);
      for(i=0;i<8;i++)
    {
     cbyte = Ezk[x]; 
     write_data(cbyte);   //写输出一字节
     x++;
    }
      }
}


/*---------------------------一个字串的输出-------------------------------------*/
void Putstr( unsigned char *str   , unsigned char i , unsigned char lie, unsigned char hang)
{
 unsigned char j,X;
    for (j=0;j<i;j++)
  {
   col="lie"+8*j;               //换列。。。。。肖注释
   row="hang";
      X = str[j];
   Putedot(X-0x20);  /*ascii码表从0x20开始*/
   }
}


 /**********************************键盘扫描部分***********************************************************/
 /*-------------------------delay---------------------------------*/
 void mdelay(unsigned  int N) 
  {
  int i;
  for(i=0;i<N;i++);
  }
/*-----------------------------------1列3行的键盘扫描----------------*/
 unsigned char scan_key()
{
 P2=P2|0x07;
 P2_4=0;
 if((P2&0x07)!=0x07) 
  {
   mdelay(100);
   if((P2&0x07)!=0x07)
    return (P2&0x07);
  }
 }


 
 /*--------------------外部中断0服务程序-------------------------------*/
 void int0() interrupt 0 
  {
   unsigned char T0H,T0L;
   //unsigned temp="0";


 if(flg_int0==0)
  {
       TH0=0;
      TL0=0;
      TR0=1;    //定时器0开始计时
  }
 if(flag_div==1)
   {
    CD4051_slect(1);
    flag_div=0;
   }
 if(flag_div100==1)
   {
         CD4051_slect(2);
    flag_div100=0;
    }


   if(Num>10)
     {
 
    EA="0";    //关中断
    TR0=0;
       T0H=TH0;
    T0L=TL0;
    //temp= (Num*65535+T0H*256+T0L);
    fre_value=(const_num*flg_int0)/(Num*65535+T0H*256+T0L);
    if(fre_value>=1000)
         flag_khz=1;
    else
         flag_khz=0;


   if(fre_value>5000)  //超出11khz则分频
       {
     if(flag_kkhz)
       {
    flag_div100=1;  //100分频标志
      flag_mmhz=1;   // 100fenpin单位标志
      }
   else
   {
       flag_div=1;  //分频标志
       flag_kkhz=1;   //10分频后单位标志
   }
     TH0=0;
     TL0=0;
       T0H=0;
     T0L=0;
     Num="0";
     flg_int0=0;
     EA="1";
    }
   else{


     if(flag_div==0&&flag_div100==0)    //显示部分
   {
      Mcs=0;Scs=1;
   if(flag_mmhz)
    {
     fre_value=fre_value/10.0;
     Putstr(str_khz,5,0,4);
    // flag_mhz=0;
      }
    else if(flag_kkhz)
    {
     fre_value=fre_value/100.0 ;
      Putstr(str_khz,5,0,4);
    }
   else if(flag_khz)
       {
        
    fre_value=fre_value/1000.0 ;
     Putstr(str_khz,5,0,4);
    }
   else    
    Putstr(str_hz,5,0,4);  
    sprintf(dis,"%f",fre_value);
    Putstr(dis,8,0,2);  //测周法显示
   }


   CD4051_slect(0) ;
   TH0=0;
    TL0=0;
       T0H=0;
   T0L=0;
   Num="0";
   flg_int0=0;
   flag_div=0;  //分频标志
      flag_div100=0;
         flag_kkhz=0;
   flag_mmhz=0;
   EA="1";
     }
   }
  else
     flg_int0++; 
   }
 
 void Timer0() interrupt 1//定时器0的中断服务程序
 {
   TH0=0;
   TL0=0;
   Num++;
   }
 
void welcome(void)
{
 unsigned char str1[]="www.hnrk";
    unsigned char str2[]="u.net.cn";
    unsigned char str3[]="Welcome";
    unsigned char str4[]="To";
 Mcs=1;Scs=0;
 Putstr(str3,7,1,0); 
 hz_disp32(2,32,cp);
 Putstr(str1,8,0,6); 


 Mcs=0;Scs=1;
 Putstr(str4,2,0,0); 
 Putstr(str2,8,0,6);
 hz_disp32(2,0,xt);



  


void Msg( void)

 
    Mcs="1";Scs=0;
      hz_disp16(0,0,p);
      hz_disp16(0,16,l);
      hz_disp32(0,32,dx);
   Mcs="0";Scs=1;
   hz_disp16(0,0,wei);
   hz_disp8(0,16,mh);
    Putstr(str_hz,5,0,4);
            
   TMOD="0x01";   //定时器0工作为定时方式
   IP="0X06";//int1 最高 T0优先级高于INT0
   IT0=1;   //外部中断为下降沿触发方式
   EX0=1;    //允许外部中断0,接待测方波
      ET0=1;   //允许t0中断
      EA="1"; 


 
   
    } 
      
    //////////////////////////////////////main()
#include<reg52.h>
#include <stdio.h>
#include "Fren_Test.h"
#include"Port_Config.h"
#include"data.h"
unsigned char key;
extern double fre_value ;



void main(void)
{
  unsigned char key_value;
  CD4051_slect(0) ;
  Clr_Scr();
  init_lcd();
  welcome();
  while(1)
  {
   
 key_value=scan_key();
 if(key_value==0x03)
 break;
 }
 Clr_Scr();
 Msg();
 while(1)
  {}
  } 

文章评论2条评论)

登录后参与讨论

用户1588142 2011-6-20 21:28

mark!!!!

用户158894 2009-4-19 16:51

不错!

用户1144279 2008-11-27 15:54

写得很详细。
相关推荐阅读
用户161601 2013-06-06 11:27
AT91LINUX编译试验 SAMA5DX cortex A5
atmel官方网站www.at91.com中对基于DTB的linux内核编译流程如下:   本文档为本人在ubuntu 10.04下实验流程,红色文字为本人添加的记录; by Jevon...
用户161601 2013-04-21 10:54
ubuntu10.04 vm6.5 hgfs 共享实现
以前用的VMWARE6.5+FC12安装好VM TOOL后 就可以在/mnt/hgfs 访问window中的共享文件夹了; 如今把FC12抛弃了,改装了ubuntu10.04但发现hgfs目录...
用户161601 2012-11-29 09:46
芯片制造工艺流程(转)
  芯片制造工艺流程   芯片制作完整过程包括 芯片设计、晶片制作、封装制作、成本测试等几个环节,其中晶片片制作过程尤为...
用户161601 2011-12-13 14:28
摄像头的组成以及红外摄像头
摄像头的工作原理大致为:景物通过镜头(LENS)生成的光学图像投射到图像传感器表面上,然后转为电信号,经过A/D(模数转换)转换后变为数字图像信号,再送到数字信号处理芯片(DSP)中加工处理,再通...
用户161601 2011-11-01 10:50
KEIL MDK生成 bin 文件 for nxp MCU
说明:本文的实践是基于lpc1343; 要想在keil中直接生成bin文件一般需要加用户命令调用fromelf工具: 如下图在Options for Target 中 加上编译后的命令; ...
用户161601 2011-10-09 11:52
基于新唐DMX512帧头的判断
DMX 512协议是Digital Multiplex的缩写,是灯光行业数字化设备的通用信号控制协议,同时也是是一种国际协议;由美国剧场技术协会(United State Institute for...
我要评论
2
5
关闭 站长推荐上一条 /2 下一条