单片机课程设计报告——智能数字频率计_单片机数字频率计设计
单片机课程设计报告——智能数字频率计由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“单片机数字频率计设计”。
单片机原理课程设计报告
题目:智能数字频率计设计
专业: 信息工程 班级:信息111 学号:*** 姓名:*** 指导教师:***
北京工商大学计算机与信息工程学院
1、设计目的(1)了解和掌握一个完整的电子线路设计方法和概念;
(2)通过电子线路设计、仿真、安装和调试,了解和掌握电子系统研发产品的一个基本流程。
(3)了解和掌握一些常见的单元电路设计方法和在电子系统中的应用: 包括放大器、滤波器、比较器、计数和显示电路等。
(4)通过编写设计文档与报告,进一步提高学生撰写科技文档的能力。
2、设计要求
(1)基本要求
设计指标:
1.频率测量:0~250KHz; 2.周期测量:4mS~10S; 3.闸门时间:0.1S,1S;
4.测量分辨率:5位/0.1S,6位/1S; 5.用图形液晶显示状态、单位等。
充分利用单片机软、硬件资源,在其控制和管理下,完成数据的采集、处理和显示等工作,实现频率、周期的等精度测量方案。在方案设计中,要充分估计各种误差的影响,以获得较高的测量精度。
(2)扩展要求
用语音装置来实现频率、周期报数。
(3)误差测试
调试无误后,可用数字示波器与其进行比对,记录测量结果,进行误差分析。
(4)实际完成的要求及效果
1.测量范围:0.1Hz~4MHz,周期、频率测量可调; 2.闸门时间:0.05s~10s可调; 3.测量分辨率:5位/0.01S,6位/0.1S; 4.用图形液晶显示状态、单位(Hz/KHz/MHz)等。
3、硬件电路设计
(1)总体设计思路 本次设计的智能数字频率计可测量矩形波、锯齿波、三角波、方波等信号的频率。系统共设计包括五大模块: 主芯片控制模块、整形模块、分频模块、档位选择模块、和显示模块。设计的总的思想是以AT89S52单片机为核心,将被测信号送到以LM324N为核心的过零比较器,被测信号转化为方波信号,然后方波经过由74LS161构成的分频模块进行分频,再由74LS153构成的四选一选择电路控制档位,各部分的控制信号以及频率的测量主要由单片机计数及控制,最终将测得的信号频率经LCD1602显示。
各模块作用如下: 1.主芯片控制模块: 单片机AT89S52 内部具有2个16位定时/计数器T0、T1,定时/计数器的工作可以由编程来实现定时、计数和产生计数溢出时中断要求的功能。利用单片机的计数器和定时器的功能对被测信号进行计数。以AT89S52 单片机为控制核心,来完成对各种被测信号的精确计数、显示以及对分频比的控制。利用其内部的定时/计数器完成待测信号周期/频率的测量。
2.整形模块:整形电路是将一些不是方波的待测信号转化成方波信号,便于测量。本设计使用运放器LM324连接成过零比较器作为整形电路。
3.分频模块: 考虑单片机利用晶振计数,使用11.0592MHz 时钟时,最大计数速率将近500 kHz,因此需要外部分频。分频电路用于扩展单片机频率测量范围,并实现单片机频率测量使用统一信号,可使单片机测频更易于实现,而且也降低了系统的测频误差。本设计使用的分频芯片是74LS161实现4分频及16分频。
4.档位选择模块:控制74LS161不分频、4分频 或者 16分频,控制芯片是74LS153。5.显示模块:编写相应的程序可以使单片机自动调节测量的量程,并把测出的频率数据送到显示电路显示,本设计选用LCD1602。
(2)测频基本设计原理
所谓“频率”,就是周期性信号在单位时间(1s)内变化的次数。若在一定时间间隔T内测得这个周期性信号的重复变化次数N,则其频率可表示为f=N/T(右图3-1所示)。其中脉冲形成电路的作用是将被测信号变成脉冲信号,其重复频率等于被测频率fx。利用单片机的定时/计数T0、T1的定时、计数功能产生周期为1s的时间脉冲信号,则门控电路的输出信号持 图3-1 续时间亦准确地等于1s。闸门电路由标准的秒脉冲信号进行控制,当秒脉冲信号来到时,闸门开通,被测脉冲信号通过闸门送到计数译码显示电路。秒脉冲信号结束时闸门关闭,计数器停止计数。由于计数器计得的脉冲数N是在1秒时间内的累计数,所以被测频率fx=NHz。
(2)系统框图
本智能数字频率计系统框图如图3-2所示
图3-2智能数字频率计系统框图
(3)单片机部分
P0口经上拉后做LCD数据接口 P2.1~P2.3作为LCD控制端口 P2.4~P2.5作为分频选择端口 P3.5作为被测信号输入端口
P3.2~P3.4作为开关控制端口(对应电路图中K1,K2,SET)
图3-3 89D52单片机部分电路
(4)分频部分
74HC161与74ls161功能兼容,是常用的四位二进制可预置的同步加法计数器,他可以灵活的运用在各种数字电路,以及单片机系统中实现分频器等很多重要的功能。
其管脚图如图3-4所示:
图3-4 74HC161 图3-5 74HC153管脚图
74HC153是一个双4选1数据选择器,其管脚图如图3-5所示:
74LS161对整形后的防波信号进行分频,Q1为四分频输出,Q3为16分频输出。未经分频、经过四分频和经过16分频的三路信号作为74LS153的一个4选1数据选择器低三位输入,由单片机控制选择分频数,然后再送单片机内部计数器T1(如图3-6)。
图3-6 分频、选择分频档位电路图
(5)LCD显示部分
LCD显示,1602的八位数据I/O口与单片机的P0口相连,读写控制端接P2.0-P2.2口。三个按键中,设置键接P3.2单片机按外部中断0接口,当按键按下后,置P3.2口低电平,单片机中断。S1、S2为频率/周期、闸门时间加/减选择按键(如图3-7)。
图3-7 LCD显示部分电路图
4、软件设计
(1)主程序流程图设计
本次程序设计采用的是C语言程序设计,其设计流程图4-1所示:
图4-1主程序流程图
(2)子程序流程图设计
显示程序:
LCD显示程序设计流程如图4-2所示:
图4-2显示程序流程图 频率测量程序框图:
频率测量程序的整体架构如图4-3所示:
图4-3频率测量框架图
(3)中断服务流程图
INT0中断流程图如图4-4所示:
图4-4INT0中断流程图
(4)程序代码
#include #include #include #include float f;
//频率 float p;
//周期 float sj;
//闸门时间 char idata buff[20];char flag=0;
//频率、周期选择标志位
char xs=0;//设置闸门时间结束后是否显示结果的标志位
unsigned char m=0,n=0,yichu=0,fenpin;
//m定时中断次数 n计数中断次数 yichu判断是定时
//器还是计数器溢出
#define Key_Set P3 #define K1 0xf7
//11110111
P33 #define K2 0xef
//11101111
P34 #define NO_Set 0xff #define Freq 0 #define Peri 1
sbit B153=P2^4;sbit A153=P2^3;sbit P17=P3^4;sbit P16=P3^3;sbit P35=P3^5;sbit Set=P3^2;unsigned char LCD_Wait(void);void LCD_Write(bit style, unsigned 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);void C52_Initial();void Delay(unsigned int t);void display(float f);void cepin();void panduan();void timedisplay(float sj);void Time_Set1();void Time_Set2();void t0();void t1();
/*****模块名称 LCD1602显示程序******/
/***********************端口定义 ***********************************/
sbit LcdRs= P2^0;sbit LcdRw= P2^1;sbit LcdEn= P2^2;sfr DBPort= 0x80;
//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口 /************************内部等待函数********************************/
unsigned char LCD_Wait(void){
LcdRs=0;
//寄存器选择输入端 1:数据 0:指令
LcdRw=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=style;
LcdRw=0;
_nop_();
DBPort=input;
_nop_();//注意顺序
LcdEn=1;
_nop_();//注意顺序
LcdEn=0;
_nop_();
LCD_Wait();} /********************设置显示模式*********************************/
#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_SetDisplay(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
//default void LCD_SetInput(unsigned char InputMode){
LCD_Write(LCD_COMMAND, 0x04|InputMode);} /******************初始化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, unsigned char 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!=' ')
{
LCD_Write(LCD_DATA,*str);
str++;
} }
/*************************************************************************** *
模块名称:
频率测量程序
* *
测量范围:0.1Hz~4MHz,闸门时间:0.05s~10s可调。
* ***************************************************************************/ /***************************89c52初始化************************************/ void C52_Initial(){ sj=1000000.00;Key_Set=0xff;TMOD=0x51;
// 01010001 T1为计数器,T0为定时器
EA=1;ET0=1;ET1=1;EX0=1;
PX0=1;
//外部中断0设置为高优先级
IT0=0;
//电平触发方式 } /**************************延时子程序**************************************/ void Delay(unsigned int t)
//t随着数值越大,误差趋于平衡.{
unsigned char i;
while(t--)
{
for(i=0;i
} } /*************************计数中*********************************/ void t1(void)interrupt 3
//计数器1溢出,yichu=1 { n++;yichu=1;TH1=0;TL1=0;} /***********************定时中断****************************/ void t0(void)interrupt 1
{ m++;yichu=2;
//定时器0溢出,yichu=2 TH0=0x3c;
//定时50ms TL0=0xb0;} /***********************频率显示*****************************/ void Fdisplay(float f){
if(f>999400.00)
{
if(f
{sprintf(buff,“ F=%2.4fmHz ”,(f/1000000.00));}
}
else
{
if(f>1040.00)
{sprintf(buff,“ F=%4.2fkHz ”,(f/1000.00));}
else
{
if(f>0.06)
{sprintf(buff,“ F=%3.2fHz
”,f);}
}
}
GotoXY(0,1);
Print(buff);} /***********************周期显示**********************************/ void Pdisplay(float p){
if(p>999400.00)
{
if(p
{sprintf(buff,“ Cycle:%2.4fs ”,(p/1000000.00));}
else
{sprintf(buff,“error(Time or F)”,p);}
}
else
{
if(p>9950.00)
{sprintf(buff,“ Cycle:%4.2fms ”,(p/1000.00));}
else
{
if(p>0.248)
{sprintf(buff,“ Cycle:%3.3fus ”,p);}
else
{sprintf(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;
//定时50ms TL0=0xb0;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;
//设置结束后第二次循环显示结果 B153=1;
//选择16分频 A153=0;yichu=0;TMOD=0x51;
TH0=0xff;
TL0=0x38;TH1=0xff;
TL1=0x9c;TR0=1;
TR1=1;while(yichu==0);
TR0=0;
TR1=0;
if(yichu==1)
(f>500khz)
{fenpin=16;
cepin();} else
频数
{
yichu=0;
B153=0;
A153=1;
TH0=0xfc;
TL0=0x18;
TH1=0xff;
TL1=0x9c;
TR0=1;
TR1=1;
while(yichu==0);
TR0=0;
TR1=0;
if(yichu==1)
(1khz
{fenpin=4;
//定时器0
200us
//计数器1
100脉冲
//启动定时器0和计数器1
//如果没有溢出一直循环
//已经溢出关闭定时器0和计数器1
//计数器先溢出:在200ms内测得的脉冲过多,说明频率较高
//转为测16分频后的频率 //定时器先溢出:100个脉冲的时间比较短,即频率较低,可以减少分
//定时器0
1ms
//计数器1
100个脉冲
//启动定时器0和计数器1
//如果没溢出一直循环
//已经溢出关闭定时器0和计数器1
//计数器先溢出:在1ms内测得的脉冲过多,说明频率较高
//转为测4分频后测频率
cepin();}
else
//定时器先溢出:100个脉冲的时间比较短,即频率较低
{ fenpin=1;
B153=0;
A153=0;
cepin();}
} } /*************************显示闸门时间***********************************/
void timedisplay(float GTime){ sprintf(buff,“GTime=%7.0fus ”,GTime);GotoXY(0,1);Print(buff);Delay(50);} /***************************减按键*******************************/ void Time_Set2(){ Delay(1000);if(P17==1)
{ sj=sj-50000.00;
if(sj>50000.00)timedisplay(sj);
else
{sj=50000.00;
timedisplay(sj);}
} else {while(P17==0)
{ Delay(500);
sj=sj-500000.00;
if(sj>50000.00)timedisplay(sj);
else
{sj=50000.00;
timedisplay(sj);}
} }
} /***************************加按键**********************************/
void Time_Set1(){ Delay(1000)if(P16==1)
{
sj=sj+50000.00;
if(sj
else
{sj=10000000.00;
timedisplay(sj);}
} else {while(P16==0)
{ Delay(500);
sj=sj+500000.00;
if(sj
else
{sj=10000000.00;
timedisplay(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(“ Pre 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
//选择测试频率或周期
{
GotoXY(0,1);
Print(“ 1.Freq 2.Cycle”);
GotoXY(0,0);
Print(“
Select ”);
while(Set==0);
//等待设置按键松开
while(Set==1)
{
switch(Key_Set)
{
case K1: flag=Freq;GotoXY(0,1);Print(“
---Freq---
case K2: flag=Peri;GotoXY(0,1);Print(”
---Cycle---
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(“ Huixi && Xia”);Delay(1000);GotoXY(0,1);Print(“
Waiting...”);
“);break;”);break;
C52_Initial();
//89c52初始化 while(1)
{
panduan();
} }
5、调试过程
程序的设计及调试过程中离不开89C52的开发系统板电路图,起初忽视了开发板上的K3键用到的P35引脚也是定时器T1的信号输入引脚。后来在其他管脚的分配也曾出现错误,不过通过调试、修改都一一改正。仿真的时候默认晶振是12MHz,故程序编写的时候按12MHz设计的定时,以至于在实体时候测量不是很准确,后通过重新计算、修改程序达到了较高的准确率。但最终在实体系统演示中犯了一个极其幼稚的错误,未拿掉短接帽,以至于起初LCD未任何显示,浪费了不少时间去找程序的问题,还是自己不够认真细心。
6、实验结果
(1)最终实物图
最终实体电路系统如图6-1。
图6-1最终实物图
该课程设计验收时结果符合设计要求,可测量矩形波,方波,三角波,锯齿波等信号的频率;测量范围为0.1Hz~4MHz;闸门时间为0.05s~10s可调。
(2)电路仿真分析
由于实物演示不方便,这里用仿真图进行说明: 如下图,开关K1、K2、SET分别代表实物单片机最小系统上的开关K5、K4、K6。SET为确认键,K1可以选择频率输出,K2可以选择周期输出。K1、K2配合还可以调节阀门时间。
下图为开关仿真图和结果显示图:
开关K1,K2选择测周、测频及闸门时间的增减,SET键用于功能切换及确认
初始显示
选择测频率或测周期
频率显示
周期显示
改变阀门时间
7、总结与感悟
本设计通过运用单片机AT89S52,Proteus 仿真软件以及Kell 仿真软件的相关知识,成功地实现了数字频率计的设计。综合调试结果表明,本文提出的设计与传统测频系统相比,具有体积小、成本低、低功耗、精度高等优点,适用于各种测量电路。
本次设计的低频测量部分及高频测量部分分别采用测频、测周的测量方法,并通过计算精确计数,故测量误差很小,再加上智能分频使单片机的测量带宽提高了一千倍以上,仅用几个芯片搭成的低成本简单电路,使该频率计拥有了不错的性价比,且完全可以满足一般的测量需求。本次课程设计由前期自己查资料、想设计思路、写代码及画电路图,然后在实验室多半天基本完成。总体来说还算顺利,所以前期做足准备工作很重要。通过本次课设,我们复习了老师所讲的C51知识,通过将所学的课本知识用于实践,即体会到了知识运用所得成果的快乐,又加深了我对知识的理解,印象更加深刻。通过参加竞赛及此次课设,我深刻体会到无论设计什么,首先要分析需求,根据所学设计构思,只要思路出来了编程的大致方向确定,问题就解决一半。另外,很多东西都是有前人经验的,并不是要我们只会盲目埋头自己苦干,要学会搜集资料,总结前人经验教训用于自己的设计,达到事半功倍的效果。在电路设计及编程、仿真以及最后的搭建实体电路系统中,任何一个环节中细节都不容忽视,比如焊接前外围电路板的排版布局,拿到新的洞洞板要先看构造,综合考虑电路需要,想好布局再焊,尽量避免错误焊接,吸掉重焊。这样既影响美观,又可能损坏电路板。另外,仿真只是初步的检验设计构思是否满足设计需要,仿真效果完美在实体系统调试运行中还是会遇到各种各样的问题亟待解决。总的来说,做任何设计要有清楚的头脑,做好准备工作,还要有耐心、细心,以及团队合作意识。每次的动手设计都能让我学到很多,有知识有心态,实践中的学习总会印象深刻!
单片机课程设计题 目: 专 业: 班 级: 组长 成员 成员 成员 成员智能小车设计 计算机科学与技术14级2班姓名 学号年 12 月 23 日2016打开命令行终端的快捷方式: ctr+al+t:默......
电子课程设计报告设计课题: 数字频率计 作 者:李成赞≦专 业: 08信息工程 班 级: (2)班 学 号: 3081231201 日 期 2009年6月5日——2009年6月17日指导教师: 廖 东 进设......
燕 山 大 学 EDA课程设计报告书题目:数字频率计姓名:Eric 班级:09电子x班 学号: 090104020xxxx 成绩:(注:此文件应以同学学号为文件名)一、设计题目及要求1.输入为矩形脉冲,频率范围0~......
单片机课程设计报告题目:小直流电机调速实验教学单位: 机 电 工 程 系专业: 机械设计制造及其自动化班级: 0803班学号: 0811050342姓名: 程怀虎2011 年 11月(以下内容用宋体,五号,单......
《单片机原理与接口技术》课程设计报告设计题目: 基于80C51单片机系统实验板的制作与程序设计专业:应用电子专业班级: 11应电班姓名: 丁文俊指导教师: 余静老师2013 年 5 月20......
