简易频率计Word文件下载.docx
《简易频率计Word文件下载.docx》由会员分享,可在线阅读,更多相关《简易频率计Word文件下载.docx(18页珍藏版)》请在冰豆网上搜索。
2.1频率计简介
频率计又称为频率计数器,是一种专门对被测信号频率进行测量的电子测量仪器。
频率计主要由四个部分构成:
时基(T)电路、输入电路、计数显示电路以及控制电路。
频率计最基本的工作原理为:
当被测信号在特定时间段T内的周期个数为N时,则被测信号的频率f=N/T(如右图所示)。
在一个测量周期过程中,被测周期信号在输入电路中经过放大、整形、微分操作之后形成特定周期的窄脉冲,送到主门的一个输入端。
主门的另外一个输入端为时基电路产生电路产生的闸门脉冲。
在闸门脉冲开启主门的期间,特定周期的窄脉冲才能通过主门,从而进入计数器进行计数,计数器的显示电路则用来显示被测信号的频率值,内部控制电路则用来完成各种测量功能之间的切换并实现测量设置。
2.3方案描述:
分析设计任务,本次系统设计如下:
图一总体框架图
经老师推荐选用以下器件:
表一可用实验芯片表
器件
功用
LM324
构成过零比较器和运放
74LS14
施密特触发器
整形电路设计:
使用同相比例运放放大信号,用施密特触发器来整形,电路如下所示
图二过零比较器加施密特
3.1电路设计
选择好电路后就确定了实验器材。
器材表如下:
表二实际使用实验器材表
器件型号
单片机
C8051F360
运放
整形
显示
LCD显示器
器件介绍:
单片机C8051F360(在MUC模块中)
1.SiliconLaboratories在2007年推出的100MHzSoC单片机
2.高性能51内核指令系统与传统51单片机完全兼容
3.1组双周期16×
16乘加器(MAC)
4.1个精准度2%的内部振荡器和32kBFlashROM,可配置式I/O引脚和各种通讯外设
5.包括UART、SPI和I2C,10位200kspsSARA/D转换器和10位D/A转换器。
图三MCU模块
其引脚图如下:
图四LM324的引脚图
它有四个运放器,用它构建运算对输入信号进行过零。
其中此次实验中,我们使用了1、2、3三角构成的过零比较器。
施密特触发器,引脚如下所示:
图七L4LS14引脚图波形
其各极限值
电源电压7V
输入电压7V
工作环境温度0~70℃
存储温度-65~150℃
用它做施密特触发器,对波形起整形作用,使输入的包含正负的波形变为只有高低两种信号的TTL电平。
这样的电平输入到MCU模块中,即输入单片机中。
用以显示所测信号频率。
在IN口输入待测信号,再有74LS14输出至单片机输入口。
实际电路如下图所示:
图九实际硬件电路接线图
3.2程序设计
采用C语言来编写控制测试程序。
程序源文件代码见附录
本次实验的测试环境如下:
图十测试流程框架图D
使用数字信号发生器发出待测信号,信号经过放大整形电路被放大、整理成为TTL波形,然后输入单片机,经程序处理,在LCD显示频率。
单片机可测得的频率范围为100~9999Hz,测量误差为±
1Hz,测量时间≤1s,可连续测量。
测试过程:
本次实验需要分别测试正弦波和方波的频率。
测量方波时需将信号发生器输出的信号直接从单片机的P3.2引脚,在频率范围1~3MHz的范围内进行调试;
测量正弦波时需要使用放大整形电路,同样在频率范围1~3MHz的范围内进行调试。
4.2测试结果:
方波频率测量结果
输入频率/Hz
LCD显示频率/Hz
误差%
10
1000
1003
0.3
10K
9974
0.26.
100K
99.34K
0.66
1000K
997.6K
0.24
1M
9984K
0.16
正弦波频率测量结果
1004
0.4
9952
0.48
991.6K
0.84
9911K
0.89
经过3周的课程设计,我们完成了一个简易的频率计。
刚开始的时候,有点无从下手的感觉,经过老师一周的分析讲解,知道了该怎么去做。
在老师给的初始化程序的基础上,加上了定时、计数和主函数之后,基本完成了方波频率的测量程序。
这是基本要求,比较简单。
对于发挥部分,要求测量正弦波的频率并扩大了测量频率的范围。
正弦波的处理:
从信号发生器中输出的正弦波要先经过一个过零比较器之后才能测量,由于做板子比较麻烦,就用了数电的实验箱,在实验箱上搭建电路,效果同板子一样。
量程自动切换处理:
这个是在程序中完成,在请教了别人之后,写出了量程自动切换的程序部分
通过本次实验设计,不但加深我们对在课程上所学到的单片机理论知识的认识和理解,重新让自己认识到了这门学科的在应用方面的广阔前景,并且通过知识与应用于实践的结合更加丰富了自己的知识,扩展了知识面,不但掌握了本专业的相关知识,而且对其他专业的知识也有所了解,并且较系统的掌握单片机应用系统的开发应用过程,从而使自身的综合素质有了较全面的提高。
另外,我们也注意到电路工艺的重要性。
经过这次一个较完整的产品设计和制作过程,对于认识到自己在知识方面存在的不足,明确今后的学习方向是非常有益的,为将来的更近一步的学习打了下扎实的基础。
附录:
C语言源程序代码
#include<
c8051f360.h>
stdio.h>
absacc.h>
#defineWDATADDRXBYTE[0XC009]//LCD写数据地址
#defineRDATADDRXBYTE[0XC00B]//LCD读数据地址
#defineWCOMADDRXBYTE[0XC008]//LCD写命令地址
#defineRCOMADDRXBYTE[0XC00A]//LCD读命令地址
#defineKEYCSXBYTE[0XC00C]//键盘片选地址
#defineT_C40
sbitLCD_RST=P3^0;
unsignedcharCHINESE1[]={"
简易频率计"
};
unsignedcharCHINESE2[]={"
设置输入波形"
unsignedcharCHINESE3[]={"
"
unsignedcharCHINESE4[]={"
unsignedcharkey_num=0xff;
//存键号
unsignedcharff_flag[]={"
频率:
unsignedcharff[]={"
"
unsignedcharfp=0;
unsignedlongf;
unsignedcharf1;
/*****************LCD12864液晶显示程序******************/
voidLCD_REST(void)
{inti;
LCD_RST=0;
for(i=0;
i<
255;
i++);
LCD_RST=1;
}
//*********************************************************
voidLCD_WC(unsignedcharcommand)//LCD写命令
{
while(RCOMADDR&
0X80);
WCOMADDR=command;
voidLCD_INIT(void)//LCD初始化
LCD_WC(0X30);
//设为基本命令集
LCD_WC(0X01);
LCD_WC(0X02);
//将DDRAM填满20H,并设定DDRAM地址计数器为0
LCD_WC(0X0C);
//开整体显示
//********************************************************
voidLCD_WD(unsignedchard)//LCD写数据
WDATADDR=d;
voidLCD_HZ(unsignedcharx,unsignedchartemp[])//显示一行字符
inti=0;
LCD_WC(x);
//x代表位置,=0x80对应左上角
while(temp[i]!
=0)
{
LCD_WD(temp[i]);
i++;
}
voidLCD_BYTE(unsignedcharx,unsignedchartemp)//显示一行字符
LCD_WD(temp);
voidLCD_CLR(void)//LCD清屏
voidOSC_INIT(void)
SFRPAGE=0X0F;
OSCICL=OSCICL+4;
OSCICN=0XC3;
CLKSEL=0X30;
SFRPAGE=0;
voidIO_INIT(void)
P0MDIN=0Xe7;
P0MDOUT=0X83;
P0SKIP=0XF9;
P1MDIN=0XFF;
P1MDOUT=0XFF;
P1SKIP=0XFF;
P2MDIN=0XFE;
P2MDOUT=0XFF;
P2SKIP=0XFF;
P3MDIN=0XFF;
P3MDOUT=0XFF;
P3SKIP=0XF9;
//0xfd,增加P3.2作T1输入
P4MDOUT=0XFF;
XBR0=0X09;
XBR1=0Xe0;
//0xc0,增加T1
SFRPAGE=0X0;
voidXRAM_INIT(void)
EMI0CF=0X07;
voidSMB_INIT(void)
SMB0CF=0XC1;
voidUART_INIT(void)
SCON0=0X0;
voidDAC_INIT(void)
IDA0CN=0XF2;
voidADC_INIT(void)
REF0CN=0;
//VDD为基准
AMX0P=0X08;
//正端接P20
AMX0N=0X1F;
//负端接GND
ADC0CF=0X2C;
//左对齐,转换时钟2MHZ
ADC0CN=0X80;
//写ADOBUSY启动AD
voidINT0_INIT(void)
IT01CF=0X05;
//P0.5为INT0
IT0=1;
//下降沿触发
voidTIMER_INIT(void)
TMOD=0x51;
//T0、T1方式1,T1计数方式
CKCON=0;
//系统时钟12分频
TL0=0xdC;
TH0=0x3c;
TL1=0X0;
TH1=0X0;
//计数器清0
fp=T_C;
TMR2CN=0X04;
//16位自动重装
TMR2RLL=0XF0;
//10MS
TMR2RLH=0XD8;
TMR3CN=0X0C;
//双8位自动重装入,系统时钟1/12
TMR3RLL=0XE0;
//定时100us
TMR3RLH=0XFF;
TR0=1;
TR1=1;
voidPCA_INIT(void)
PCA0CN=0X40;
//允许PCA计数器、定时器
PCA0MD=0;
//禁止看门狗定时器
voidINT_INIT(void)
EX0=1;
//INIT0,键盘
PX0=0;
//INT0为低优先级
ET0=1;
//T0
ET1=1;
//T1
ET2=0;
//T2
EIE1=0X0;
//0X08,允许ADC中断
ES0=0;
//uart
EA=1;
voidInit_device(void)
OSC_INIT();
IO_INIT();
XRAM_INIT();
SMB_INIT();
UART_INIT();
DAC_INIT();
ADC_INIT();
INT0_INIT();
TIMER_INIT();
PCA_INIT();
INT_INIT();
voidKEY_INIT0(void)interrupt0
key_num=KEYCS&
0x0f;
}
voidT0(void)interrupt1
TL0=0xDB;
TH0=0x3C;
fp++;
if(fp==40)
TR1=0;
fp=0;
f=65536*f1+256*TH1+TL1;
flag=1;
TH1=0;
TL1=0;
f1=0;
voidT1(void)interrupt3
f1++;
voidGf(void)
if((0<
=f)&
&
(f<
10000))
{
ff[0]=f/1000%10+0x30;
ff[1]=f/100%10+0x30;
ff[2]=f/10%10+0x30;
ff[3]=f%10+0x30;
ff[4]='
H'
;
ff[5]='
z'
ff[6]='
'
ff[7]='
elseif((10000<
100000))
ff[0]=f/10000%10+0x30;
ff[1]=f/1000%10+0x30;
ff[2]='
.'
ff[3]=f/100%10+0x30;
ff[4]=f/10%10+0x30;
K'
elseif((100000<
1000000))
ff[0]=f/100000%10+0x30;
ff[1]=f/10000%10+0x30;
ff[2]=f/1000%10+0x30;
ff[3]='
ff[4]=f/100%10+0x30;
elseif((1000000<
10000000))
ff[0]=f/1000000%10+0x30;
ff[1]=f/100000%10+0x30;
ff[2]=f/10000%10+0x30;
ff[3]=f/1000%10+0x30;
main()
Init_device();
LCD_REST();
LCD_INIT();
LCD_HZ(0x80,CHINESE1);
LCD_HZ(0x90,CHINESE2);
LCD_HZ(0x88,CHINESE3);
LCD_HZ(0x98,CHINESE4);
f=0;
while((key_num&
0xf0)!
=0);
while
(1)
/*unsignedchartemp;
emp=key_num&
if(temp==0x01)
LCD_BYTE(0x88,temp);
key_num=0xff;
}*/
Gf();
LCD_HZ(0x80,ff_flag);
LCD_HZ(0x90,ff);