基于单片机的高精度频率计的设计--课程设计.doc_第1页
基于单片机的高精度频率计的设计--课程设计.doc_第2页
基于单片机的高精度频率计的设计--课程设计.doc_第3页
基于单片机的高精度频率计的设计--课程设计.doc_第4页
基于单片机的高精度频率计的设计--课程设计.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

数字频率计的设计姓名:任琼琳 学号:070102050039一、课程设计的目的通过本课程设计使学生进一步巩固光纤通信、单片机原理与技术的基本概念、基本理论、分析问题的基本方法;增强学生的软件编程实现能力和解决实际问题的能力,使学生能有效地将理论和实际紧密结合,拓展学生在工程实践方面的专业知识和相关技能。二、课程设计的内容和要求1课程设计内容(硬件类)频率测量仪的设计 2课程设计要求频率测量仪的设计 要求学生能够熟练地用单片机中定时/计数、中断等技术,针对周期性信号的特点,采用不同的算法,编程实现对信号频率的测量,将测量的结果显示在lcd 1602上,并运用proteus软件绘制电路原理图,进行仿真验证。三实验原理可用两种方法测待测信号的频率方法一:(定时1s测信号脉冲次数)用一个定时计数器做定时中断,定时1s,另一定时计数器仅做计数器使用,初始化完毕后同时开启两个定时计数器,直到产生1s中断,产生1s中断后立即关闭t0和t1(起保护程序和数据的作用)取出计数器寄存器内的值就是1s内待测信号的下跳沿次数即待测信号的频率。用相关函数显示完毕后再开启t0和t1这样即可进入下一轮测量。原理示意图如下:实验原理分析:1 根据该实验原理待测信号的频率不应该大于计数器的最大值65535,也就是说待测信号应小于65535hz。2 实验的误差应当是均与的与待测信号的频率无关。方法二(测信号正半周期)对于1:1占空比的方波,仅用一个定时计数器做计数器,外部中断引脚作待测信号输入口,置计数器为外部中断引脚控制(外部中断引脚为“1”切trx=1计数器开始计数)。单片机初始化完毕后程序等待半个正半周期(以便准确打开trx)打开trx,这时只要intx(外部中断引脚)为高电平计数器即不断计数,低电平则不计数,待信号从高电平后计数器终止计数,关闭trx保护计数器寄存器的值,该值即为待测信号一个正半周期的单片机机器周期数,即可求出待测信号的周期:待测信号周期t=2*cnt/(12/fsoc) cnt为测得待测信号的一个正半周期机器周期数;fsoc为单片机的晶振。所以待测信号的频率f=1/t。原理示意图如下:实验原理分析:1 根据该实验原理该方法只适用于1:1占空比的方波信号,要测非1:1占空比的方波信号2 由于有执行f=1/(2*cnt/(12/fsoc))的浮点运算,而数据类型转换时未用lcd浮点显示,故测得的频率将会被取整,如1234.893hz理论显示为1234hz,测得结果会有一定程度的偏小。也就是说测量结果与信号频率的奇偶有一定关系。3 由于计数器的寄存器取值在165535之间,用该原理时,待测信号的频率小于单片机周期的1/12时,单片机方可较标准的测得待测信号的正半周期。故用该原理测得信号的最高频率理论应为fsoc/12 如12mhz的单片机为1mhz。而最小频率为f=1/(2*65535/(12/fsoc)) 如12mhz的单片机为8hz。四实验内容及步骤1. 仿真模型的构建数字方波频率计的设计总体可分为两个模块。一是信号频率测量,二是将测得的频率数据显示在1602液晶显示模块上。因此可搭建单片机最小系统构建构建频率计的仿真模型。原理图,仿真模型的总原理图如下:2. 液晶显示部分功能与原理分析由于此部分并非课程的主要部分,故仅作简要原理分析a1602硬件接口及功能接口/硬件接口部分*sbit lcdrs= p20;sbit lcdrw= p21;sbit lcden = p22;sfr dbport = 0x80;/p0=0x80,p1=0x90,p2=0xa0,p3=0xb0.数据端口/向lcd写入命令或数据*#define lcd_command0 / command#define lcd_data1 / data#define lcd_clear_screen0x01 / 清屏#define lcd_homing 0x02 / 光标返回原点/设置显示模式*#define lcd_show0x04 /显示开#define lcd_hide0x00 /显示关 #define lcd_cursor0x02 /显示光标#define lcd_no_cursor0x00 /无光标 #define lcd_flash0x01 /光标闪动#define lcd_no_flash0x00 /光标不闪动/设置输入模式*#define lcd_ac_up0x02/将光标返回0x00#define lcd_ac_down0x00 / default#define lcd_move0x01 / 画面可平移#define lcd_no_move0x00 /defaultb1602初始化流程和原理框图void lcd_initial()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递增, 画面不动开始清使能端写命令:8位数据端口,2行显示,5*7点阵重写控制命令写命令:开启显示, 无光标写命令:清屏写命令:ac递增, 画面不动结束初始化流程开始y=0?x,yyn写命令(80h+x)写命令(80h+40h+x)初始化结束写ddram地址,ddram地址与屏幕相对应开始*str=0?字符串首地址stryn写写数据*strstr地址加1结束写字符串c 写ddram地址(原理框图如上)void gotoxy(unsigned char x, bit y)if(y=0)lcd_write(lcd_command,0x80|x);if(y=1)lcd_write(lcd_command,0x80|(x-0x40);d写字符串(原理框图如上)void print(unsigned char *str)while(*str!=0)lcd_write(lcd_data,*str);str+;3.程序机原理框图(关于显示函数部分不列出,只分析算法函数)方法一:用定时计数器t0做脉冲计数器(下跳沿有效),开始与暂停由t1控制定时计数器t1做定时中断,定时1s,定时开启置t0开始计数,定时完毕,置t0为暂停,关闭t1,读取计数数据并清空计数器,将计数数据装换为有效规范的字符串显示后再开启t0和t1,进入下一轮测量。以下是程序的核心部分:(定时1s,取计数数,并将其转换显示出来)原理框图如下void timer1() interrupt 3 /定时50msth1=thclk;tl1=tlclk;if(-cnt=0)/cnt初值为20tr0=0;tr1=0;cnt=cntnum;tmp=th0*256+tl0;th0=tl0=0;dynamic_lcd_print();tr0=1;tr1=1;方法二:用一个定时计数器做计数器,外部中断引脚作待测信号输入口,置计数器为外部中断引脚控制(外部中断引脚为“1”切trx=1计数器开始计数)。单片机初始化完毕后程序等待半个正半周期(以便准确打开trx)打开trx,这时只要intx(外部中断引脚)为高电平计数器即不断计数,低电平则不计数,待信号从高电平后计数器终止计数,关闭trx保护计数器寄存器的值,该值即为待测信号一个正半周期的单片机机器周期数,即可求出待测信号的周期:待测信号周期t=2*cnt/(12/fsoc) cnt为测得待测信号的一个正半周期机器周期数;fsoc为单片机的晶振。所以待测信号的频率f=1/t。以下是程序的核心部分:(原理框图如下) void chkfreq() /while(freqin=0);while(freqin=1);tr0=1;while(freqin=0);while(freqin=1);tr0=0;cnttime=500000/(th0*256+tl0);th0=tl0=0;tmp=(int)cnttime;dynamic_lcd_print();4.原理框图如下产生50ms中,进入中断服务程序断服务程序计满20次即产生完1s?yn关闭t0,t1保护数据从置中断次数结束取计数器计数值,将其转换为int型清计数器值调用函数,将数据装换有效字符串,并将其显示出来在屏幕上显示出来开t0,t1进入下一轮测量方法一流程图开始等待一个负半周期直到遇到高电平,以便于精确测量等待到遇到低电平开启tr0等待到遇到高电平等待到遇到低电平关闭tr0取计数器计数值,将其运算转行为信号频率的int类型清计数器值调用函数,将数据装换有效字符串,并将其显示出来在屏幕上显示出来结束方法二流程图五课程设计结果及结论1.通过程序调试,用protues用两种方法均可测得小于6mhz的频率,以下是用方法一测量1000hz频率的仿真图:2.实验结果及误差分析对于用原理一a待测信号的频率小于65535hz。b实验的误差2000hz时为0.05%; 10000hz时为0.07% ;5000060000hz时为0.073%。对于用原理二 c在频率8-10000hz时测得的值相当精确,频率为奇数时有1-2的误差。 d超过频率8-10000hz测得值完全错误由此可见实验结果符合之前的原理分析,验证成功。3。实验优化及改进建议a) 方法一可将计数器0更改为中断扩展数据位数并延长定时时间,数据处理后和测量大于65535hz的频率,但由t0中断不确定性,加大了测量范围会加大测量误差b) 方法二可将硬件待测信号取反接入剩余的外部中断接口,用于测量待测信号的负半周期,将正半周期和负半周期数相加即为待测信号的周期。这样即可测量非均衡占空比的方波信号。c) 方法二还可计多次正半周期取平均值,可大大提高精度,但这样会提高实验的最低量程4 两算法的对比a) 方法一误差均衡,切易于扩大量程,且可测量任意占空比的方波信号,但由于单片机的限制频率越高误差将表现更明显。b) 方法二在量程内误差比方法一稍小,占用cpu资源较小,但量程比方法一小,切不能测量非均衡占空比的频率信号,超过量程测量结果完全错误。c) 由此可见方法一较方法二有明显的优势六课程设计的心得体会通过这次综合实验,不仅加深了我对单片接的认识而却还学会了设计,开发以及实际测试,锻炼了我们的实际动手能力。在课程设计中通过两种原理与算法是我更清晰的认识了单片机对数据的处理,进行程序调试。在此期间我们遇到很多麻烦,但通过仔细分析,我一次又一次品尝到了解决问题的喜悦,最终完成了实验,在测试中我们发现了自己知识的不足,通过几天的奋斗,我们学到了很多东西,最重要的是我们学会了一种精神永不放弃。在以后的时间里面我们会用这种精神去学习,更上一层楼。附录(完整的源程序)一1602_drive.h完整的库函数/* the 1602 char lcd lib copyright (c) 2008 by wanxun file name: 1602_drive.h author: wanxun created: 2008/12/1 */#ifndef lcd_char_1602#define lcd_char_1602#include /硬件接口部分*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;lcdrw=1;_nop_();lcden=1;_nop_();/while(dbport&0x80);/在用proteus仿真时,注意用屏蔽此语句,在调用gotoxy()时,会进入死循环, /可能在写该控制字时,该模块没有返回写入完备命令,即dbport&0x80=0x80 /实际硬件时打开此语句lcden=0;return dbport;/向lcd写入命令或数据*#define lcd_command0 / command#define lcd_data1 / data#define lcd_clear_screen0x01 / 清屏#define lcd_homing 0x02 / 光标返回原点void lcd_write(bit style, unsigned char input)lcden=0;lcdrs=style;lcdrw=0;_nop_();dbport=input;_nop_();/注意顺序lcden=1;_nop_();/注意顺序lcden=0;_nop_();lcd_wait();/设置显示模式*#define lcd_show0x04 /显示开#define lcd_hide0x00 /显示关 #define lcd_cursor0x02 /显示光标#define lcd_no_cursor0x00 /无光标 #define lcd_flash0x01 /光标闪动#define lcd_no_flash0x00 /光标不闪动void lcd_setdisplay(unsigned char displaymode)lcd_write(lcd_command, 0x08|displaymode);/设置输入模式*#define lcd_ac_up0x02#define lcd_ac_down0x00 / default#define lcd_move0x01 / 画面可平移#define lcd_no_move0x00 /defaultvoid lcd_setinput(unsigned char inputmode)lcd_write(lcd_command, 0x04|inputmode);/移动光标或屏幕*/*#define lcd_cursor0x02 #define lcd_screen0x08#define lcd_left0x00#define lcd_right0x04void lcd_move(unsigned char object, unsigned char direction)if(object=lcd_cursor)lcd_write(lcd_command,0x10|direction);if(object=lcd_screen)lcd_write(lcd_command,0x18|direction);*/初始化lcd*void lcd_initial()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, bit y)if(y=0)lcd_write(lcd_command,0x80|x);if(y=1)lcd_write(lcd_command,0x80|(x-0x40);void print(unsigned char *str)while(*str!=0)lcd_write(lcd_data,*str);str+;/*void lcd_loadchar(unsigned char user8, unsigned char place)unsigned char i;lcd_write(lcd_command,0x40|(place*8);for(i=0; i8; i+)lcd_write(lcd_data,useri);*/*#endif二方法一的源程序#include #include /*定义接口: *液晶显示器的接口“1602_drive.h”库函数中已经定义 *定义待测方波频率的接口: *p35(t0口)做时钟输入接口; */=/用测量脉冲次数的方法时定义的定时1s的参数#define thclk 0x3c#define tlclk 0xb0#define cntnum 20 /=/定义中间变量unsigned int cnt;unsigned int tmp;unsigned char outcnt8;/=/将测量的整数装换为标准有效的字符串void numtochar(void) unsigned char i;outcnt0=tmp/10000+48;tmp%=10000;outcnt1=tmp/1000+48;tmp%=1000;outcnt2=tmp/100+48;tmp%=100;outcnt3=tmp/10+48;tmp%=10;outcnt4=tmp+48;outcnt5=h;outcnt6=z;outcnt7=0;for(i=0;i4;i+)/将字符中数字的最高有效位之前的0清空为 。if(outcnti=0)outcnti= ;else break;/=/静态显示文本void static_lcd_print()gotoxy(0,0);print(freq is:);gotoxy(1,1);print(made by wanxun);/=/动态显示数据void dynamic_lcd_print() numtochar();gotoxy(9,0);print(outcnt);/=/*用定时计数器t0做脉冲计数器(下跳沿有效),开始与暂停由t1控制 *定时计数器t1做定时中断,定时1s,定时开启置t0开始计数,定时完毕置 *t0为暂停,关闭t1,读取计数数据并清空计数器,将计数数据装换为有效 *规范的字符串显示后再开启t0和t1,进入下一轮测量 */void initial_c51()th0=tl0=0; th1=thclk;tl1=tlclk;tr0=0;tmod=0x15;ie=0x88;tr1=0;cnt=cntnum;void timer1() interrupt 3 /定时50msth1=thclk;tl1=tlclk;if(-cnt=0)tr0=0;tr1=0;cnt=cntnum;tmp=th0*256+tl0;th0=tl0=0;dynamic_lcd_print();tr0=1;tr1=1;void main(void)initial_c51();lcd_initial();static_lcd_print();tr0=1;tr1=1;do/空循环用于执行其他任务while(1);三方法二源程序#include #include /*定义接口: *液晶显示器的接口“1602_drive.h”库函数中已经定义 *定义

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论