基于AT89S52单片机的数字频率计课程设计

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第一章前言
频率测量是电子学测量中最为基本的测量之一。

由于频率信号抗干扰性强,易于传输,因此可以获得较高的测量精度。

随着数字电子技术的发展,频率测量成为一项越来越普遍的工作,测频原理和测频方法的研究正受到越来越多的关注。

1.1频率计概述
数字频率计是计算机、通讯设备、音频视频等科研生产领域不可缺少的测量仪器。

它是一种用十进制数字显示被测信号频率的数字测量仪器。

它的基本功能是测量正弦信号、方波信号及其他各种单位时间内变化的物理量。

在进行模拟、数字电路的设计、安装、调试过程中,由于其使用十进制数显示,测量迅速,精确度高,显示直观,经常要用到频率计。

传统的频率计采用测频法测量频率,通常由组合电路和时序电路等大量的硬件电路组成,产品不但体积大,运行速度慢而且测量低频信号不准确。

本次采用单片机技术设计一种数字显示的频率计,测量准确度高,响应速度快,体积小等优点[1]。

1.2频率计发展与应用
在我国,单片机已不是一个陌生的名词,它的出现是近代计算机技术的里程碑事件。

单片机作为最为典型的嵌入式系统,它的成功应用推动了嵌入式系统的发展。

单片机已成为电子系统的中最普遍的应用。

单片机作为微型计算机的一个重要分支,其应用范围很广,发展也很快,它已成为在现代电子技术、计算机应用、网络、通信、自动控制与计量测试、数据采集与信号处理等技术中日益普及的一项新兴技术,应用范围十分广泛。

其中以AT89S52为内核的单片机系列目前在世界上生产量最大,派生产品最多,基本可以满足大多数用户的需要[2]。

1.3频率计设计内容
利用电源、单片机、分频电路及数码管显示等模块,设计一个简易的频率计能够粗略的测量出被测信号的频率。

参数要求如下:
1.测量范围10HZ—2MHZ;
2.用四位数码管显示测量值;
第二章系统总体方案设计
2.1测频的原理
测频的原理归结成一句话,就是“在单位时间内对被测信号进行计数”。

被测信号,通过输入通道的放大器放大后,进入整形器加以整形变为矩形波,并送入主门的输入端[3]。

由晶体振荡器产生的基频,按十进制分频得出的分频脉冲,经过基选通门去触发主控电路,再通过主控电路以适当的编码逻辑便得到相应的控制指令,用以控制主门电路选通被测信号所产生的矩形波,至十进制计数电路进行直接计数和显示。

若在一定的时间间隔T内累计周期性的重复变化次数N,则频率的表达式为式:
N
f x=
T
(1)
图1说明了测频的原理及误差产生的原因。

0.x个脉冲)
图1 测频原理
在图1中,假设时基信号为1KHZ,则用此法测得的待测信号为1KHZ×5=5KHZ。

但从图中可以看出,待测信号应该在5.5KHZ左右,误差约有0.5/5.5≈9.1%。

这个误差是比较大的,实际上,测量的脉冲个数的误差会在±1之间。

假设所测得的脉冲个数为N,则所测频率的误差最大为δ=1/(N-1)*100%。

显然,减小误差的方法,就是增大N。

本频率计要求测频误差在1‰以下,则N应大于1000。

通过计算,对1KHZ以下的信号用测频法,反应的时间长于或等于10S,。

由此可以得出一个初步结论:测频法适合于测高频信号。

频率计数器严格地按照
N
f=
T
公式进行测频[4]。

由于数字测量的离散性,被测
频率在计数器中所记进的脉冲数可有正一个或负一个脉冲的1
量化误差,在不计其他误差影响的情况下,测量精度将为:
1
δ=
()
fA N
应当指出,测量频率时所产生的误差是由N和T俩个参数所决定的,一方面是单位时间内计数脉冲个数越多时,精度越高,另一方面T越稳定时,精度越高。

为了增加单位时间内计数脉冲的个数,一方面可在输入端将被测信号倍频,另一方面可增加T来满足,为了增加T的稳定度,只需提高晶体振荡器的稳定度和分频电路的可靠性就能达到。

上述表明,在频率测量时,被测信号频率越高,测量精度越高。

2.2总体思路
频率计是我们经常会用到的实验仪器之一,频率的测量实际上就是在单位时间内对信号进行计数,计数值就是信号频率。

本文介绍了一种基于单片机AT89S52 制作的频率计的设计方法,所制作的频率计测量比较高的频率采用外部十分频,测量较低频率值时采用单片机直接计数,不进行外部分频。

该频率计实现10HZ~2MHZ的频率测量,而且可以实现量程自动切换功能,四位共阳极动态显示测量结果,可以测量正弦波、三角波及方波等各种波形的频率值。

第三章硬件电路具体设计
根据系统设计的要求,频率计实际需要设计的硬件系统主要包括以下几个部分:AT89S52单片机最小系统模块、电源模块、放大整形模块、分频模块及显示模块,下面将分别给予介绍。

3.1 AT89S52主控制器模块
3.1.1 AT89S52的介绍
8位单片机是MSC-51系列产品升级版[5],有世界著名半导体公司ATMEL在购买MSC-51设计结构后,利用自身优势技术——(掉电不丢数据)闪存生产技术对旧技术进行改进和扩展,同时使用新的半导体生产工艺,最终得到成型产品。

AT89S52片内集成256字节程序运行空间、8K字节Flash存储空间,支持最大64K外部存储扩展。

根据不同的运行速度和功耗的要求,时钟频率可以设置在0-33M之间。

片内资源有4组I/O控制端口、3个定时器、8个中断、软件设置低能耗模式、看门狗和断电保护。

可以在4V到5.5V宽电压范围内正常工作。

不断发展的半导体工艺也让该单片机的功耗不断降低。

使用双列直插DIP-40的封装。

AT89S52引脚如下图3所示。

3.2 引脚功能
VCC:电源电压;
GND:地;
P0口:P0口是一个8位漏极开路的双向I/O口。

作为输出口,每位能驱动8个TTL逻辑电平。

对P0端口写“1”时,引脚用作高阻抗输入。

当访问外部程序和数据存储器时,P0口也被作为低8位地址/数据复用。

在这种模式下,P0具有内部上拉电阻。

在 flash编程时,P0口用来接收指令字节;在程序校验时,输出指令字节。

程序校验时,需要外部上拉电阻[7]。

P1口:P1口是一个具有内部上拉电阻的8位双向I/O口,P1 输出缓冲器能驱动4个TTL 逻辑电平。

对 P1 端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。

作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流。

此外,P1.0和P1.2分别作定时器/计数器2的外部计数输入和定时器/计数器2的触发输入,P1口功能具体如表1所示。

在flash编程和校验时,P1口接收低8位地址字节。

表1 P1口的第二种功能说明表
P2口:P2口是一个具有内部上拉电阻的8位双向I/O口,P2输出缓冲器能驱动4 个TTL逻辑电平。

对P2端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。

作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流。

在访问外部程序存储器或用16位地址读取外部数据存储器时,P2口送出高八位地址。

在这种应用中,P2口使用很强的内部上拉发送1。

第四章系统的软件设计
系统软件设计主要采用模块化设计,叙述了各个模块的程序流程图,并介绍了软件Keil和Proteus的使用方法和调试仿真。

4.1 软件模块设计
系统软件设计采用模块化设计方法。

整个系统由初始化模块,信号频率测量模块,自动量程转换和显示模块等模块组成。

系统软件流程如图19所示。

频率计开始工作或者完成一次频率测量,系统软件都进行测量初始化。

测量初始化模块设置堆栈指针(SP)、工作寄存器、中断控制和定时/计数器的工作方式。

定时/计数器的工作首先被设置为计数器方式,即用来测量信号频率[15]。

图19 系统软件流程总图
首先定时/计数器的计数寄存器清0,运行控制位TR置1,启动对待测信号的计数。

计数闸门由软件延时程序实现,从计数闸门的最小值(即测量频率的高量程)开始测量,计数闸门结束时TR清0,停止计数。

计数寄存器中的数值经过数制转换程序从十六进制数转换为十进制数。

判断该数的最高位,若该位不为0,满足测量数据有效位数的要求,测量值和量程信息一起送到显示模块;若该位为0,将计数闸门的宽度扩大10倍。

4.2 应用软件简介
此设计需要在Keil软件平台上完成程序的调试,在Proteus软件平台上完成仿真显示。

因此介绍如何使用Keil和Proteus进行软件的仿真。

Keil简介
Keil软件是目前最流行开发系列单片机的软件,Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部份组合在一起。

而Proteus与其它单片机仿真软件不同的是,它不仅能仿真单片机CPU的工作情况,也能仿真单片机外围电路或没有单片机参与的其它电路的工作情况。

因此在仿真和程序调试时,关心的不再是某些语句执行时单片机寄存器和存储器内容的改变,而是从工程的角度直接看程序运行和电路工作的过程和结果。

对于这样的仿真实验,从某种意义上讲,是弥补了实验和工程应用间脱节的矛盾和现象[16]。

(1)建立工程文件
点击“Project->New project”菜单,出现一个对话框,要求给将要建立的工程起一个名字,你可以在编缉框中输入一个名字,点击“保存”按钮,出现第二个对话框,按要求选择目标器件片。

建立新文件并增加到组。

分别设置“target1”中的“Target,output,debug”各项,使程序汇编后产生HEX文件。

(2)汇编,调试系统程序
Keil 单片机模拟调试软件内集成了一个文本编辑器,用该文本编辑器可以编辑源程序。

在集成开发环境中选择菜单“File → New...”、单击对应的工具按钮或者快捷键Ctrl +N 将打开一个新的文本编辑窗口,完成汇编语言源文件的输入,并且完成源程序向当前工程的添加。

然后在集成开发环境中选择菜单“File→Save As...”可以完成文件的第一次存储。

注意,汇编语言源文件的扩展名应该是“ASM”,它应该与工程文件存储在同一文件夹之内。

在完成文件的第一次存储以后,当对汇编语言源文件又进行了修改,再次存储文件则应该选择菜单“File→Save”、单击对应的工具按钮或者快捷键Ctrl +S 实现文件的保存。

接着的工作需要把汇编语言源文件加入工程之中。

选择工程管理器窗口的子目“Source Group 1”,再单击鼠标右键打开快捷菜单。

在快捷菜单中选择“Add File to Group ‘Source Group 1’”,加入文件对话框被打开。

在这个对话框
的“查找范围(I)”下拉列表框中选择存储汇编语言源文件的文件夹,在“文件类型(T)”下拉列表框选择“Asm Source file(*.a*;*.src)”,这时存储的汇编语言源文件将显示出来。

双击要加入的文件名或者选择要加入的文件名再单击“Add”按钮即可完成把汇编语言源文件加入工程。

文件加入以后,加入文件对话框并不消失,更多的文件也可以利用它加入工程。

如果不需要加入其它文件,单击“Close”按钮可以关闭加入文件对话框。

这时工程管理窗口的文件选项卡中子目录“Source Group 1”下出现一个汇编语言源文件。

需要注意,当把汇编语言源文件加入工程但还没有关闭加入文件对话框,这时有可能被误认为文件没有成功地加入工程而再次进行加入操作,系统将显示所需的文件已经加入的提示。

在这种情况下,单击提示框中的“确定”按钮,再单击“Close”按钮可以关闭加入文件对话框。

(3)编译源程序,出现错误时,返回上一级对错误更改后重新编译,直到没有错误为止。

protues简介
protues是Labcenter公司出品的电路分析、实物仿真系统,而KEIL是目前世界上最好的51单片机汇编和C语言的集成开发环境。

他支持汇编和C的混合编程,同时具备强大的软件仿真和硬件仿真功能[17]。

Protues能够很方便的和KEIL、Matlab IDE等编译模拟软件结合。

Proteus提供了大量的元件库有RAM,ROM,键盘,马达,LED,LCD,AD/DA,部分SPI器件,部分IIC器件,它可以仿真单片机和周边设备,可以仿真51系列、AVR,PIC等常用的MCU,与keil和MPLAB不同的是它还提供了周边设备的仿真,只要给出电路图就可以仿真。

这里我将keil和 Protues两个软件的快速集成起来使用。

(1)首先将keil和 Protues两个软件安装好。

(2)然后在C:\Program Files\Labcenter Eletronics\Protues 6 Professional\MODELS(我的Protues是安装C盘里面的)目录下的VDM51.DLL 动态连接库文件复制到C:KEIL\C51\BIN 目录下面(我的keil 也安装在C盘)这个文件将在keil的debug设置时用到。

(3)打开protues软件,新建一文件将硬件原理图绘入图中。

(4)将KEIL生成的HEX文件下载入单片机中,点击“开始”进行仿真。

(5)在keil中进行debug,同时在proteus中查看直观的结果(如LCD显示⋯⋯)。

这样就可以像使用仿真器一样调试程序。

利用Proteus与Keil整合进行
第五章频率计的系统调试
常见的数码管由七个条状和一个点状发光二极管管芯制成,叫七段数码管,根据其结构的不同,可分为共阳极数码管和共阴极数码管两种。

根据管脚资料,可以判断使用的是何种接口类型[14].两种数码管内部原理如图16所示。

图16 两种数码管内部原理图
LED数码管中各段发光二极管的伏安特性和普通二极管类似,只是正向压降较大,正向电阻也较大。

在一定范围内,其正向电流与发光亮度成正比。

所以它的输入端在5 V电源或高于TTL高电平(3.5 V)的电路信号相接时,一定要串加限流电阻,以免损坏器件。

频率值显示电路
数码管电路设计不加三极管驱动时,使用4位数码管进行频率值显示,如果选择共阴极数码管显示,则需要8个三极管进行驱动,因此选用共阳极数码管进行动态显示,具体数码管设计电路如图17所示。

图17 数码管显示电路
5.2 软件调试
Pouteus软件调试
根据系统设计要求,进行Keil和Proteus系统仿真,不断调试程序,直到符合功能要求。

Proteus总体仿真图29所示。

图29 频率计整体仿真图
功能调试
当测量频率值小于1KHz以下时,数码管显示频率值,并红色LED灯亮,作为Hz档单位指示。

例如输入信号123Hz,仿真显示如图30所示。

图30 HZ档频率仿真
5.3 误差分析
从记录的数据可以看出,系统软件仿真误差很小,在10Hz-2MHz范围内测量出来的频率基本上就是输入信号的频率,在超出这个范围后,才出现很小的误差。

但是在硬件调试中,可能是由于标准元器件本身误差,如随着时间的延长,其值相比出厂时产生误差;造成测量结果没有软件仿真精确。

同时手工焊接单片机最小系统、分频整形电路等也会带来一定的干扰,造成信号的失真,从而导致测量精度下降,测量范围有所缩小,但是可以看出,误差在允许范围内,所设计的电路基本符合要求。

第六章总结
课程设计已经结束,通过这次设计,我受益匪浅。

课程设计是一次综合性的实践,它将各种知识结合到一起综合运用到实践上来扩展、弥补、串联所学的知识。

通过本次课程设计我得到了很多收获。

首先,了解了单片机的基本知识和在控制领域的作用和地位。

其次掌握了C语言的编写程序,学会了使用PROTUTES 和KEIL的仿真来实现,同时掌握了如何收集、查阅、应用文献资料,如何根据实际需要有选择的阅读书籍和正确确定系统所要使用的元器件的类型。

再次,在精神方面锻炼了思想、磨练了意志。

面对存在的困难首先分析问题根据目的要求确定可实现的部分,定出那不准的方面找同学和老师讨论研究,再完善、再修改、再发现问题、再解决培养了自己的耐心、恒心及遇事不乱的精神。

总之,我明白了理论和实践之间存在的距离只有靠不断的思考不断的动手才能将所学的知识真正运用到实践上来。

在课程设计中我的很多方面的能力都得到了提高,尤其在单片机软件编程方面让我感触颇深。

我个人认为软件设计是个即灵活又细腻的工作,它要求耐心和细心去不断完善,同时还需要有良好的逻辑思维能力。

通过这次毕业设计,我分析问题和解决问题的能力有所提高,也巩固了所学的知识,加深了对理论知识的理解,更重要的是锻炼自己的独立性,为我今后的工作和学习打下坚实的基础。

参考文献
[1]邹大挺.频率计的设计[J]. 《电子产品世界》出版社. 2006. 第193期. 4-7. [2]雷玉堂.光电检测技术[M]. 中国计量出版社. 1995.
[3]季建华. 智能仪表原理[M]. 山东教育出版社. 2004.
[4]王永生. 电子测量学[M]. 西北工业大学出版社. 2003.
[5]李华.单片机实用接口技术[M]. 航空航天大学出版社. 2006.
[6]张鹏.王雪梅. 单片机原理与应用实例教程[M]. 海军出版社. 2007.
[7]赫建国等. 单片机在电子电路设计中的应用[M]. 清华大学出版社. 2005.
[8]康华光.电子技术基础(模拟部分)[M]. 高等教育出版社. 1998.
[9]/s_LM7805.html.LM7805英文参考手册[Z]
[10]谢自美.电子线路设计与实验[M]. 华中科技大学出版社. 2006.
[11] /s_74LS00. html.74LS00英文参考手册[Z]. [12]/s_74LS161.html.74LS161英文参考手册[Z]. [13]/s_74LS151.html.74LS151英文参考手册[Z]. [14]康华光.电子技术基础(数字部分)[M]. 高等教育出版社. 1998.
[15]赖麒文. 8051单片机C语言软件设计的艺术[M]. 科学出版社. 2004.
[16]徐波. Keil的使用技巧[J]. 《电子产品世界》出版社. 2006. 第224期. 6-9. [17]吴清平. 单片机原理与应用实例教程[M]. 海军出版社. 2008.
【简要说明】
一、尺寸:长128mm宽87mm高18mm
二、支持芯片:AT89S51/S52/S53 支持STC89C51/C52/C53(加转换板可使用ATMEGA8/48、ATMEGA16/32)
三、工作电压:直流4.5~5.5伏
四、单片机标准十针下载接口。

(可使用并口下载线和USB下载线下载)
五、特点:
1、具有电源指示。

2、所以I/O口以引出并有LED灯指示。

3、四位数码管显示、四位按键输入、32位LED发光二极管显示。

4、标准的11.0592M晶振。

(晶振可以插拔更换)
5、具有上电复位和手动复位。

6、四种供电接口(USB供电、端子引入供电、排针引入供电、电源头接口供电)
7、串口通信使用MAX232接口,同时可以下载STC单片机程序。

8、带有蜂鸣器,可以输出音调
频率计源程序:
#include<reg52.h> //库文件
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int //宏定义无符号整型
/********************************************************************
初始定义
*********************************************************************/
code uchar seg7code[10]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //显示段码数码管字跟不加code,默认在数据存储器256b
uchar wei[4]={0XEf,0XDf,0XBf,0X7f}; //位的控制端(四位数码管)
sbit key1=P2^0;
uint tcnt=0; //计中断
int th0,t0,val=0;
sbit sound=P3^7; //蜂鸣器
/********************************************************************
延时函数
*********************************************************************/
void delay(uchar t)
{
uchar i,j;
for(i=0;i<t;i++)
for(j=13;j>0;j--);}
void delay_2ms()
{
uchar l,k;
for(l=0;l<0;l++)
for(k=0;k<254;k++);}
/********************************************************************
显示函数
*********************************************************************/
void Led(int date) //显示函数
{
/*****************数据转换*****************************/
uint z,x,c,v;
z=date/1000; //求千位
x=date%1000/100; //求百位
c=date%100/10; //求十位
v=date%10; //求个位
P2=0XFF;
P0=seg7code[z];
P2=wei[0];
delay(80);
P2=0XFF;
P0=seg7code[x];
P2=wei[1];
delay(80);
P2=0XFF;
P0=seg7code[c];
P2=wei[2];
delay(80);
P2=0XFF;
P0=seg7code[v];
P2=wei[3];
delay(80);
P2=0XFF;
}
/********************************************************************
定时中断服务函数
*********************************************************************/ void t1(void) interrupt 3 using 0 //定时中断服务函数p23 ,p46
{ tcnt++; //每过50ms tcnt 加一
if(tcnt==20) //计满20 次(1 秒)时
{ th0=TH0; //读计数值
t0=TL0;
val=th0*256+t0; //换算计数值
tcnt=0;//重新再计
TH0=0; //计数器归零
TL0=0;}
TH1=(65535-50000)/256; //对TH1 TL1 赋值
TL1=(65535-50000)%256;
}
void T0() interrupt 1 //计数中断
{ sound=~sound;}//计数溢出中断
void init()
{
TMOD=0x15; //定时器1工作方式1,计数器0工作方式1
IE=0X8A;
TR1=1; //开始计时
TR0=1; //开始计数
TH0=(65535-50000)/256; //对TH1 TL1 赋值
TL0=(65535-50000)%256;
}
/********************************************************************
主函数
*********************************************************************/ void main()
{ if(!key1)
delay_2ms();
if(!key1)
{ init();
while(1)
{Led(val);
} }
}
/********************************************************************
结束
********************************************************************。

相关文档
最新文档