1、0单片机课程设计报告题 目:基于 89C52 单片机的数字频率计 院 (系): 信息与通信学院 专 业: 电子信息工程 学生姓名: - 学 号: - 指导教师: - 2012 年 11 月 15 日0摘 要该系统以 STC89S51 单片机为核心, 应用单片机的运算和控制功能并采用 LCD 显示器实时地将所测频率显示出来, 通过测量结果对比,分析了测量误差的来源,提出了减小误差应采取的措施。频率计具有电路结构简单、 成本低、 测量方便、 精度较高等特点,适合测量低频信号。关键词:单片机,频率测量AbstractThe paper introduces one cymometer system
2、Based on singlechip which applys the singlechips function of operation and control and displays the result by LCD. By comparing results, the source of measurement error is analysed, the measures are proposed for reducing errors. T he frequency meter has characteristics of simple circuit, low cost, e
3、asy measurement and high precision, it fits for measuring low frequency signals.Key words : Singlechip,frequency- measure1引言11 课程设 计概述11.1 课程设计任务及要求.11.2 主要仪器.11.3 数字频率计概述.11.4 测频基本设计原理.22 方案论证22.1 总体方案22.2 测频方案选择33 硬件设计.33.1 系统功能描述33.2 硬件电路设计框架33.3 单片机部分43.4 放大整形部分43.5 分频部分.53.6 LCD 显示和键盘部分.64 软件设计
4、.64.1 主程序流程图设计64.2 子程序流程图设计74.2.1 显示程序74.2.2 频率测量程序框图.84.2.3 中断服务流程图85 系统调试.95.1 显示调试.95.2 键盘调试.95.3 前置放大整形调试.95.4 软件调试.96 结果分析与结论.107 总结.10参考文献.11附录120引言:在工业生产、仪器仪表行业及实验教学中,经常会遇到频率的测量,我们经常使用的及目前市场上所售的频率测量装置,大多数是采用小规模集成电路及分离元件组成。在现代电子学的各个领域,要求频率计精度高且能够直接读出频率值。频率计由 89S52 单片机控制电路、信号处理电路、键盘电路以及测量数据的显示电
5、路还有系统软件所构成的,在信号处理电路当中包含了待测信号放大、限幅、波形变换、波形整形以及分频电路。信号的予处理电路当中的放大器所实现的是对待测信号的一个放大的功能,能够降低对待测信号的幅度的一个要求,波形的变换和整形电路实现将正弦波样的一个正负交替的号波形转换成为能够被单片机所接受的一个信号,分频电路所用于扩展的单片机的频率测量范围以及提高测量精度,并且通过实现单片机频率测量以及周期测量使用统一的一个输入的信号。系统的软件包括有测量初始化的模块、显示的模块以及信号频率测量的模块等等。1 课程设计概述1.1 课程设计任务及要求题目:数字频率计要求:LCD 显示,测量范围 0100KHZ,带前置
6、放大、整形电路,可测周期信号的频率。1.2 主要仪器设备函数信号发生器 1 台示波器 1 台直流稳压电源(030V) 1 台 数字万用表 1 块PC 机 1 台1.3 数字频率计概述数字频率计是计算机、通讯设备、音频视频等科研生产领域不可缺少的测量仪器。它是一种用十进制数字显示被测信号频率的数字测量仪器。它的基本功能是测量正弦信号,方波信号及其他各种单位时间内变化的物理量。在进行模拟、数字电路的设计、安装、调试过程中,由于其使用十进制数显示,测量迅速,精确度高,显示直观,经常要用到频率1计。1.4 测频基本设计原理所谓“频率”,就是周期性信号在单位时间(1s)内变化的次数。若在一定时间间隔 T
7、 内测得这个周期性信号的重复变化次数 N,则其频率可表示为 f=N/T(右图 1-1 所示)。其中脉冲形成电路的作用是将被测信号变成脉冲信号,其重复频率等于被测频率 fx。时间基准信号发生器提供标准的时间脉冲信号,若其周期为 1s,则门控电路的 图 1-1 输出信号持续时间亦准确地等于 1s。闸门电路由标准秒信号进行控制,当秒信号来到时,闸门开通,被测脉冲信号通过闸门送到计数译码显示电路。秒信号结束时闸门关闭,计数器停止计数。由于计数器计得的脉冲数 N 是在 1 秒时间内的累计数,所以被测频率fx=NHz。2 方案论证2.1 总体方案本次设计包含硬件设计与软件设计两部分,根据设计任务要求,采用
8、 AT89S52 单片机,配置时钟电路,复位电路构成单片机最小系统,配置前置放大电路,人机对话通道中的键盘,L CD 显示,从而构成设计要求的单片机应用测频系统,其结构框图如下图 2-1 所示:单片机前置放大整形复位电路时钟电路键盘电路LCD 显示电路2图 2-1 结构框图2.2 测频方案选择方案一:直接测频法。直接测频法是把被测频率信号经脉冲形成电路后加到闸门的一个输入端, 只有在闸门开通时间T ( 以秒计) 内, 被计数的脉冲被送到十进制计数器进行计数。设计数器的值为N , 由频率定义式可以计算得到被测信号频率为: f = N / T 。方案二:高精度恒误差测频法。通过对传统测量方法的研究
9、, 结合高精度恒误差测量原理, 设计一种测量精度与被测频率无关的硬件测频电路。本方法立足于快速的宽位数高精度浮点数字运算。方案三:倍频法。直接测频法在高频段有着很高的精度。可以把频率测量范围分成多个频段, 使用倍频技术, 根据频段设置倍频系数将经整形的低频信号进行倍频后再进行测量, 高频段则进行直接测量。从编程难易及单片机资源利用情况和测量误差角度考虑,选择方案一,尽管在测量低频段时的相对测量误差较大。但是可以通过增大 T 来提高测量精度。3 硬件设计3.1 系统功能描述本次课程设计主要完成功能有:(1)长按设置键可选择测量频率或者周期。(2)短按则是选择设置闸门时间(0.05s10s)。(3
10、)测量频率范围:0.1Hz4MHz。3.2 硬件电路设计框架根据设计要求,数字频率计整个系统硬件框架图如下 3-1图 3-1 整机硬件电路框图 待测信号信号放大 信号限幅 信号整形 分频电路AT89S52 单片机LCD 液晶显示键盘电路3本系统实用 LM318 对待测信号进行放大,在用稳压二极管 1N4733 对信号进行限幅,然后经 74LS14 反向器整形得到 TTL 信号,送 74LS161 分频,最后送单片机 P35 内部计数器进行计数,单片机处理数据后送 LCD 显示。3.3 单片机部分P0 口经上拉后做 LCD 数据接口P2.1P2.3 作为 LCD 控制端口P2.4-P2.5 作为
11、分频选择端口P1.6-P1.7 作为键盘设置端口P3.5 作为被测信号输入端口图 3-23.4 放大整形部分待测信号经过第一级放大后,进入第二级放大限幅电路,再由 7414 组成的施密特触发器整形,得到标准方波信号。LM318 是高数运放,工作电压 5-20V, 输入带宽 15MHZ,足够处理高频信号。放大倍数:n=RL2/RL1(RL2 用 50K,RL1 用 10K)。限幅原理:限幅电路的稳压管跨接在集成运放的输出端和反相输入端之间。假设稳压管截止,则集成运放必然工作在开环状态,输出电压不是+ UOM,就是- UOM。这样,必将导致稳压管击穿而工作在稳压状态,D Z构成负反馈通路,使反相输
12、入端为“虚地”,限流电阻4上的电流 iR等于稳压管的电流 iZ,输出电压 u O=UZ。图 3-33.5 分频部分74HC161 与 74ls161 功能兼容,是常用的四位二进制可预置的同步加法计数器,他可以灵活的运用在各种数字电路,以及单片机系统中实现分频器等很多重要的功能.其管脚图如图 3-4 所示: 图 3-4 74HC161 图 3-5 74HC153 管脚图74HC153 是一个双 4 选 1 数据选择器,其管脚图如图 3-5 所示:74LS161 对整形后的防波信号进行分频,Q1 为四分频输出,Q3 为 16 分频输出。未经分频、经过四分频和经过 16 分频的三路信号作为 74LS
13、153 的一个4 选 1 数据选择器低三位输入,由单片机控制选择分频数,然后再送单片机内部计数器 T1(如图 3-6) .5图 3-63.6 LCD 显示和键盘部分LCD 显示,通过调节变阻器调节 LCD 背光亮度,八位数据口接单片机 P0 口,读写控制端接 P2.0-P2.2 口。三个按键中,设置键接 P3.2 单片机按外部中断 0 接口,当按键按下后,置 P3.2 口低电平,单片机中断。S1、S2 为频率/周期、闸门时间加/减选择按键(如图 3-7)。图 3-74 软件设计4.1 主程序流程图设计本次程序设计采用的是 C 语言程序设计,其设计流程图 4-1 所示:6图-主程序流程图4.2
14、子程序流程图设计4.2.1 显示程序LCD 显示程序设计流程如图 4-2图 4-2 显示程序流程图开始LCD 初始化CPU 初始化频率周期测量量程自动转换LCD 显示结束定时中断服务初始化 LCD设置输入模式设置显示模式内部等待函数,等待有无信号LCD 显示YN74.2.2 频率测量程序框图频率测量程序的整体架构如图 4-3 所示:图 4-3 频率测量框架图4.2.3 中断服务流程图INT0 中断流程图如图 4-4图 4-4INT0 中断流程图延时子程序减按键、加按键89c52初始化显示闸门时间计数中断判断频率定时中断频率显示周期显示测试频率测试频率程序设置键按下进入中断长按?闸门时间加/减显
15、示闸门时间按键选择测频率/周期显示测量量,频率/周期设置键按下?退出中断YNYN85 系统调试5.1 显示调试调节变阻器改变 LCD 背光亮度,直到亮度合适且显示正常。去掉前置放大整形部分,送数据 LCD 显示看是否正常显示,能够正常显示,说明显示电路正常工作。5.2 键盘调试在显示正常情况下调试键盘,按设置键,看是否能正常进入中断,若能,进入中断后,按下频率/周期、闸门时间设置键,看是否能正常设置。在调试过程中遇到能够进入中断,但是不能进行设置,经检查电路、程序后发现两个选择按键之间短路,当其中一个按键按下,相当于两个同时按下,只是单片机 CPU 不能正常识别。消除短路后电路正常工作了。5.
16、3 前置放大整形调试去掉 LCD、单片机调试放大器是否正常工作。给定输入信号,用示波器分别测量各级输入输出信号,看是否和放大相应倍数,限幅在指定范围。调试结果:第一级放大五倍与符合预想要求。第二级限幅在 6.2V,与理论值 5.1伏有所出入,但仍然满足后面电路要求。5.4 软件调试单片机软件调试主要是调试本次课程设计的主程序。其调试过程如下:(1)新建一个工程。单击 Project 菜单,在弹出的下拉菜单中选 New Project。(2)然后选择你要保存的路径,输入工程文件的名字,保存。(3)新建一个工程后弹出一个对话框,根据你的需要选择你使用的单片机型号。然后点击确定。(4)单击“File
17、”,选择“New”,新建文件并在其中输入程序代码,然后保存为 c语言文件。(5)回到编辑界面后,单击“Target 1”前面的“+”号,然后在“Source Group 1”单击右键选择“Add File To Group Source Group 1”,选中 Test.c 文件。(6)单击“Project”菜单,选中“Built Target”,完成程序的编译,在工程文件夹中找到*.hex 文件即可96 结果分析与结论测量结果对比分析:输入频率 测量频率 误差12345结论:整个系统完成测试后,性能稳定,由于所用函数发生器输出最大频率为10KHz,没有测试更高频率;从测量结果对比分析可知本次
18、设计的频率计基本满足课程设计要,并且功能有所扩展。7 总结在整个课程设计的过程中每一步都是自己亲自做过的,遇到的问题也非常多,在经过遇到问题,思索问题到解决问题的过程中,收获是最多的。以往没有注意到的问题,都在这一次的课程设计中得以体现,这培养了我的细心,耐心和专心。我觉得能够在这次的课程设计中学到很多的东西,以往不注意的细节,在这一次中是必须让自己去注意的。对实际经验的不足在设计过程中出现了不少的问题,得到了老师的耐心指导,在此表示感谢。10参考文献1 张义和 . 例说 51 单片机 .人民邮电出版社2 马淑华. 王凤文等著 .单片机原理与接口技术. 北京邮电大学出版社3 华成英 .童诗白著
19、. 模拟电子技术基础 . 高等教育出版社4 阎石著.数字电子技术技术基础 . 高等教育出版社5 谭浩强. C 语言程序设计 . 清华大学出版社6 陈尚松等.电子测量与仪器(第二版).电子工业出版社11附录:PCB 图:程序清单:#include #include #include #include float f; /频率float p; /周期float sj; /闸门时间char idata buff20;char flag=0; /频率周期选择标志位char xs=0; /设置闸门时间结束后是否显示结果的标志位unsigned char m=0,n=0,yichu=0,fenpin; /
20、m 定时中断次数 n 计数中断次数 yichu 判断是定时器还是计数器溢出#define Key_Set P1#define K1 0xbf /1011_1111 P16#define K2 0x7f /0111_1111 P17#define NO_Set 0xff#define Freq 0#define Peri 1sbit B153=P24;sbit A153=P23;sbit P17=P17;sbit P16=P16;sbit P35=P35;sbit Set=P32;unsigned char LCD_Wait(void);void LCD_Write(bit style, uns
21、igned char input);void LCD_SetDisplay(unsigned char DisplayMode);void LCD_SetInput(unsigned char InputMode);void LCD_Initial();void GotoXY(unsigned char x, unsigned char y);void Print(unsigned char *str);12void C52_Initial();void Delay(unsigned int t);void display(float f);void cepin();void panduan(
22、);void timedisplay(float sj);void Time_Set1();void Time_Set2();void t0();void t1();/* 模块名称:LCD1602 显示程序 */*Port Definitions*/sbit LcdRs= P20;sbit LcdRw= P21;sbit LcdEn= P22;sfr DBPort= 0x80; /P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口/*内部等待函数*/unsigned char LCD_Wait(void)LcdRs=0; /寄存器选择输入端 1:数据 0:指令LcdRw=
23、1; _nop_(); /RW:为 0:写状态;为 1:读状态;LcdEn=1; _nop_(); /使能输入端,读状态,高电平有效;写状态,下降沿有效LcdEn=0;return DBPort;/*向 LCD 写入命令或数据*/#define LCD_COMMAND 0 / Command#define LCD_DATA 1 / Data#define LCD_CLEAR_SCREEN 0x01 / 清屏#define LCD_HOMING 0x02 / 光标返回原点void LCD_Write(bit style, unsigned char input)LcdEn=0;LcdRs=sty
24、le;LcdRw=0; _nop_();DBPort=input; _nop_();/注意顺序LcdEn=1; _nop_();/注意顺序LcdEn=0; _nop_();LCD_Wait();/*设置显示模式*/13#define LCD_SHOW 0x04 /显示开#define LCD_HIDE 0x00 /显示关 #define LCD_CURSOR 0x02 /显示光标#define LCD_NO_CURSOR 0x00 /无光标 #define LCD_FLASH 0x01 /光标闪动#define LCD_NO_FLASH 0x00 /光标不闪动void LCD_SetDispl
25、ay(unsigned char DisplayMode)LCD_Write(LCD_COMMAND, 0x08|DisplayMode);/*设置输入模式*/#define LCD_AC_UP 0x02#define LCD_AC_DOWN 0x00 / default#define LCD_MOVE 0x01 / 画面可平移#define LCD_NO_MOVE 0x00 /defaultvoid LCD_SetInput(unsigned char InputMode)LCD_Write(LCD_COMMAND, 0x04|InputMode);/*初始化 LCD*/void LCD_I
26、nitial()LcdEn=0;LCD_Write(LCD_COMMAND,0x38); /8 位数据端口,2 行显示,5*7 点阵LCD_Write(LCD_COMMAND,0x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); /开启显示, 无光标LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); /清屏LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); /AC 递增, 画面不动/*/void GotoXY(unsigned char x, unsigned char y)if(y=0)LCD_Writ
27、e(LCD_COMMAND,0x80|x);if(y=1)LCD_Write(LCD_COMMAND,0x80|(x-0x40);void Print(unsigned char *str)14while(*str!=0)LCD_Write(LCD_DATA,*str);str+; /* /* * 模块名称: 频率测量程序 * 主要技术指标: 测量范围:0.1Hz4M * 闸门时间:0.05s10s 可调。 * */*89c52 初始化*/ void C52_Initial()sj=1000000.00;Key_Set=0xff;TMOD=0x51; / 01010001 T1 为计数器,T0
28、 为定时器EA=1;ET0=1;ET1=1;EX0=1; PX0=1; /外部中断 0 设置为高优先级IT0=0; /电平触发方式/*ms 延时子程序*/void Delay(unsigned int t) /t 随着数值越大,误差趋于平衡.unsigned char i;while(t-)for(i=0;i999400.00)if(f1040.00)sprintf(buff,“ Freq:%4.2fkHz “,(f/1000.00);else if(f0.06)sprintf(buff,“ Freq:%3.2fHz “,f);GotoXY(0,1);Print(buff);/*周期显示*/v
29、oid Pdisplay(float p) if(p999400.00)if(p9950.00)sprintf(buff,“ Cycle:%4.2fms “,(p/1000.00);elseif(p0.248) sprintf(buff,“ Cycle:%3.3fus “,p);elsesprintf(buff,“error(Time or F)“,p);GotoXY(0,1);Print(buff);/*测试频率*/void cepin()unsigned char a;unsigned long js;m=0;n=0;TMOD=0x51;TH0=0x3c; /定时 50msTL0=0xb0
30、;TH1=0;TL1=0;a=sj/50000.00;TCON=0x50; /启动定时器和计数器while(m!=a); TCON=0;js=TH1*256+n*65536+TL1;f=(js/(sj/1000000.00)*fenpin;p=sj/(js*fenpin);if(xs=0) /设置结束后第一次不显示结果if(flag=Freq) Fdisplay(f);else Pdisplay(p);/*判断频率*/void panduan()xs=0; /设置结束后第二次循环显示结果17B153=1; /选择 16 分频A153=0; yichu=0;TMOD=0x51; TH0=0xff
31、; /定时器 0 200usTL0=0x38;TH1=0xff; /计数器 1 100 脉冲TL1=0x9c;TR0=1; /启动定时器 0 和计数器 1TR1=1;while(yichu=0); /如果没有溢出一直循环TR0=0; /已经溢出关闭定时器 0 和计数器 1TR1=0; if(yichu=1) /计数器先溢出:在 200ms 内测得的脉冲过多,说明频率较高(f500khz)fenpin=16; /转为测 16 分频后的频率 16cepin();else /定时器先溢出:100 个脉冲的时间比较短,即频率较低,可以减少分频数yichu=0;B153=0;A153=1; TH0=0x
32、fc; /定时器 0 1msTL0=0x18;TH1=0xff; /计数器 1 100 个脉冲TL1=0x9c;TR0=1; /启动定时器 0 和计数器 1TR1=1;while(yichu=0); /如果没溢出一直循环TR0=0; /已经溢出关闭定时器 0 和计数器 1TR1=0;if(yichu=1) /计数器先溢出:在 1ms 内测得的脉冲过多,说明频率较高(1khz50000.00) timedisplay(sj);else sj=50000.00;timedisplay(sj); else while(P17=0) Delay(500);sj=sj-500000.00;if(sj50
33、000.00) timedisplay(sj);else sj=50000.00;timedisplay(sj); /*加按键*/ void Time_Set1()Delay(1000);if(P16=1) sj=sj+50000.00;if(sj10000000.00) timedisplay(sj);else sj=10000000.00;timedisplay(sj);else while(P16=0)19 Delay(500);sj=sj+500000.00;if(sj10000000.00) timedisplay(sj);else sj=10000000.00;timedispla
34、y(sj); /按住 1s 快加 0.5s /*闸门时间设置*/void Time_Set() interrupt 0 EA=0; /防止无限中断Delay(100);if(Set=0)Delay(1000); /判断处于哪种设置状态if(Set=1)GotoXY(0,1);Print(“ Press Button.“);GotoXY(0,0);Print(“ T Settings “);while(Set=1)switch(Key_Set)case K1: Time_Set1();break;case K2: Time_Set2();break;default: break;else /选择
35、测试频率或周期GotoXY(0,1);Print(“ 1.Freq 2.Cycle“);GotoXY(0,0);Print(“ Slecting. “);while(Set=0); /等待设置按键松开while(Set=1) switch(Key_Set)20case K1: flag=Freq; GotoXY(0,1); Print(“ -Freq- “); break;case K2: flag=Peri; GotoXY(0,1); Print(“ -Cycle- “); break;default: break;GotoXY(0,0);Print(“ -Cymometer-“); GotoXY(0,1);Print(“ Waiting. “);while(Set=0); /防止再次进入中断EA=1;xs=1; /不显示此次结果./*主程序*/void main() LCD_Initial(); /LCD 初始化GotoXY(0,0);Print(“ -Cymometer-“);GotoXY(0,1);Print(“ designed by LZA“);Delay(1000);GotoXY(0,1);Print(“ Waiting. “);C52_Initial(); /89c52 初始化while(1)panduan();