51单片机频率计.docx

上传人:b****1 文档编号:1728041 上传时间:2023-05-01 格式:DOCX 页数:18 大小:1,001.91KB
下载 相关 举报
51单片机频率计.docx_第1页
第1页 / 共18页
51单片机频率计.docx_第2页
第2页 / 共18页
51单片机频率计.docx_第3页
第3页 / 共18页
51单片机频率计.docx_第4页
第4页 / 共18页
51单片机频率计.docx_第5页
第5页 / 共18页
51单片机频率计.docx_第6页
第6页 / 共18页
51单片机频率计.docx_第7页
第7页 / 共18页
51单片机频率计.docx_第8页
第8页 / 共18页
51单片机频率计.docx_第9页
第9页 / 共18页
51单片机频率计.docx_第10页
第10页 / 共18页
51单片机频率计.docx_第11页
第11页 / 共18页
51单片机频率计.docx_第12页
第12页 / 共18页
51单片机频率计.docx_第13页
第13页 / 共18页
51单片机频率计.docx_第14页
第14页 / 共18页
51单片机频率计.docx_第15页
第15页 / 共18页
51单片机频率计.docx_第16页
第16页 / 共18页
51单片机频率计.docx_第17页
第17页 / 共18页
51单片机频率计.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

51单片机频率计.docx

《51单片机频率计.docx》由会员分享,可在线阅读,更多相关《51单片机频率计.docx(18页珍藏版)》请在冰点文库上搜索。

51单片机频率计.docx

51单片机频率计

实验报告

实验名称基于8255的8LED数显频率计

课程名称Protues软件设计(51单片机)

班级学号

姓名

一、实验要求

基本要求:

用P1或P3口,产生一方波信号,频率为1000Hz,用一组数码管或LCD显示频率和周期以及脉宽等参数(也可用信号源或模拟信号源)。

将输出信号输入到另一端口(INT0/INT1)作频率计的信号输入端,测量此方波信号的频率、周期和脉宽,在另一组数码管或LCD上将参数值显示出来。

(刷新时间1秒)o

发挥部分:

1、设置一功能键,能将当前数码管或LCD上的信号参数值锁定。

2、通过键盘,可修改方显示参数,刷新时间。

3、按键时,蜂鸣器发出提示音,表示按键有效

4、用图形方式显示输入波形(用模拟示波器)动态显示格式:

自定

二、实验内容

实验内容为基于8255的简易8LED数字显示频率计,利用8255的扩展功能,来扩展51单片机的功能管脚,使其可以实现利用8255的A,B端口实现输入输出功能,从而实现51单片机管脚的扩展。

三、实验原理

频率计主要功能是测量频率。

频率是指一秒内发生相同波形的次数,根据这一定义,可以初步得出测量频率的方法,就是通过计量一定时间的脉冲次数就可以通过计算累加获得频率的次数,然后通过数值译码输送的数显电路当中去。

根据实验假设,可以知道实验中需要用的两个定时装置,一个为定时装置,另一个为计数装置。

而单片机中正好就设置了这样的计时器。

8051提供两个16位的内部定时器(计数器),分别为Time0,Time1(简称T0,T1)这两个定时器可以用作为内部定时器或者外部计数器,作为内部计时的时候是计算的是内部的脉冲,以12MHz的计时脉冲系统为例,将此计数器时钟脉冲除12后送入定时器,因此定时器所计数的脉冲周期为1us。

若采用16位的

定时器,最多可以计数65536,约为0,065&因而我们选择0.05S作为单位计数时间长度。

若当成外部计数器时则计数由T0或T1管脚送入脉冲,同样地,若采用16位的定时模式,则最多可以数65536个计数量,相当可观。

在51单片机中有两个16位的定时/计数器T0,T1,分别由TH0、TL0和TH1、TL1组成,它们均是8位寄存器,在特殊功能寄存器中占地址8AH-8DH。

它们用于存放定时或计数的初始值。

此外,内部还有一个8位的方式寄存器TMOD和一个8位的控制寄存器TCON。

用于选择和控制定时/计数器的工作。

其格式见下面两表:

方式控制寄存器TMOD

GATE

C/T

M1

M0

GATE

C/T

M1

M0

门控开关

计数/定时

方式选择

门控开关

计数/定时

方式选择

TCON控制寄存器

TF1

TR1

TF0

TRO

IE1

IT1

IE0

IT0

T1请求有/无

T1工作启/停

T0请求有/无

T0工作启/停

INT1请

求有/无

INT1方

式下沿

INT1请

求有/无

INT1方

式下沿

根据定时时间要求或计数要求计算计数器初值;

将工作方式控制字写入TMOD寄存器;

将计数初值写入THX和TLX寄存器;

启动定时器/计数器,即将TRX置位。

如果工作于中断方式,需置位EA(中断总开关)及ETX(允许定时/计数器中断),并编写中断服务程序。

实验当中规定要求为使用INT0/INT1作频率计的信号输入端,所以启用的是外部中断来执行计数过程。

外部中断有INTO和INT1两个,CPU通过两个外部引脚即可接受外部中断的请求。

外部中断信号的采样方式可分为电平触发(低电平)以及边缘触发(负边沿触发)两种。

若采用电平触发,需要将TCON寄存器中的IT0(或IT1)设定为0,则只要INTO引脚为低电平,视为外部中断要求。

若采用边缘触发,需要将TCON寄存器中的IT0(或IT1)设定为1,则只要INTO引脚的信号由高电平转为低电平,则视为外部中断需求。

这些中断需求将反映在IE0(IE1)里,若IE寄存器

的EX0(或EX1)=1,且EA=1,CPU则进入我们设定好的中断程序。

IE中断启用寄存器

IE7

IE6

IE5

IE4

IE3

IE2

IE1

IE0

EA

ES

ET1

EX1

ET0

EX0

显示单路部分,因为要求使用8LED数码管显示电路,所以只用对数码管分别送入数据信号和扫描信号即可。

显示原理如图所示

所以利用8255分别写入数据和扫描信号既可以是其产生所要显示的内容8255的控制字的设置也有不少问题需要解决,

图九28255A编程模型

需要对8255A进行控制字的写入

图扎3方式控制字

根据设计的电路我设计的控制字为

D8255=0x80;

设定的各端口的地址为

#defineA8255XBYTE[OxfffO]

#defineB8255XBYTE[0xfff1]

#defineC8255XBYTE[0xfff2]

#defineD8255XBYTE[0xfff3]

四、设计思路及设计流程图

基本上可以分为三个阶段,第一阶段为读取外部指令,为测量频率,测量周期,测量脉宽。

我采用了P1端口的P1.0,P1.1P1.2三个管脚来作为外部指令的输入方式。

主程序流程图

测量函数部分我使用的是利用外部中断INTO管脚输入信号,设置为负边沿触发,利用

此来触发外部中断子程序voidEX_INT0()interrupt0。

同时计时器开始0.05s的计时程序,当

计时次数满二十次的情况是正好满1S则锁存实验所得数据然后送进显示电路进行显示。

中断程序部分为:

voidEX_INT0()interrupt0

{

countA++;

}

若要做的便是将CountA的数值在计时中断满二十次时进行锁存而后输出即可

频率测量函数流程图

因为测量数据分为测量周期还有测量脉宽等部分,对于周期测量我是对测量的频率值进行了一定的内部处理利用

周期=1/频率

这一特性进行的计算。

对于脉宽的测量也是建立在这一基础之上。

发生程序我嵌套在主程序中的扫描函数当中,当对主程序进行循环的是时候

如果检测到有按键操作则启动发生程序

voidPlay(chart)

chari;

for(i=0;i<120;i++)

{

BEEP=~BEEP;delay(t);

}

BEEP=0;}

五、实验成品

通过protues进行仿真程序,连接各电路,下图为运行后的初始画面

程序共有三个外部按键,从上往下依次为频率,周期,脉宽。

以下分别为设定外部输入信号

为1kHz的周期信号,所得到的实验画面

1000

此图为按下第三个按键后的效果图脉宽为500us

500U5

六、实验代码

#include

#include

〃******定义8255控制端口以及ABC端口的地址#defineA8255XBYTE[OxfffO]

#defineB8255XBYTE[0xfff1]

#defineC8255XBYTE[0xfff2]

#defineD8255XBYTE[0xfff3]

#define

ucharunsingedchar

 

#defineuintunsignedint

//*******

输入按键操作********

sbitPB0=P1A0;

sbitPB1=P1A1;

sbitPB2=P"2;

sbitBEEP=P3A0;

chardisbuffer[8]={0,1,2,3,4,5,6,7};

charTAB[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,};

〃0x83改为0x82修正了数字6的显示问题

charchocode[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};

//charchocode[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

charcodevalue[8]={0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0};

〃最初没有取反,后来前后次序乱使数据原本为12345678变为87654321

#definecount_M150000

#defineH_0(65636-count_M1)/256

#defineL_0(65636-count_M1)%256

chartimes=0;

bitstatus_F=1;

//charscan=1;

unsignedlongintfreq=11;

unsignedlonginttime=0;

unsignedlongintcountA=0;

unsignedlongintmk=0;//设计处为短型,所以导致程序运行不正常

sfr16DPTR=0x82;

voiddelay(int);

voiddisplay(void);//显示函数;

voidmeasureA(void);

voidmeasureTT(void);

voidmeasureMK(void);

voiddelay(intx)

{inti;intj;

for(i=0;i

}

//*********发声程序*********奇怪的现象,当T0接输入时,喇叭会自动的响voidPlay(chart)

{

chari;

for(i=0;i<120;i++)

{

BEEP=~BEEP;

delay(t);

}

BEEP=0;

}

〃测量频率主函数

main()

{P仁Oxff;//设定P1端口的初始值防止外部干扰

D8255=0x80;

while

(1)

{

if(PB0==0)

{Play

(1);

status_F=O;

measureA();

while(status_F==O);

}

if(PB1==0)

{Play

(2);

status_F=0;

measureA();

while(status_F==0);measureTT();

}

if(PB2==0)

{Play(3);

status_F=0;

measureA();

while(status_F==0);measureMK();

}

elsedisplay();

}

}

//测频率使用外部中断

voidmeasureA(void)

{

IE=0x8f;

TMOD=Ox51;

TH0=H_0;

TL0=L_0;countA=O;

IT仁1;

IT0=1;

PX0=1;

TR0=1;TR1=0;}

//************

外部中断intO****计时程序***

 

voidEX_INT0()interrupt0{

countA++;

//display。

}

//********T0一

一秒时间中断**************

voidT0_1S(void)interrupt1

{TH0=H_0;TL0=L_0;

if(++times==20)

{times=0;

TR1=0;TR0=0;

〃DPL=TL1;DPH=TH1;

freq=countA;

codevalue[7]=TAB[freq/10000000];codevalue[6]=TAB[(freq/1000000)%10];codevalue[5]=TAB[(freq/100000)%10];

codevalue[4]=TAB[(freq/10000)%10];

codevalue[3]=TAB[(freq/1000)%10];

codevalue[2]=TAB[(freq/100)%10];

codevalue[1]=TAB[(freq/10)%10];

codevalue[0]=TAB[(freq%10)];

status_F=1;

}

}

//*

*********

测量周期

************

voidmeasureTT(void)

{time=1000000/freq;

codevalue[1]=0xc1;codevalue[0]=TAB[5];

codevalue[7]=TAB[(time/100000)%10];codevalue[6]=TAB[(time/10000)%10];

codevalue[5]=TAB[(time/1000)%10];

codevalue[4]=TAB[(time/100)%10];

codevalue[3]=TAB[(time/10)%10];

codevalue[2]=TAB[(time%10)];

 

//*

******

测量脉宽*******

voidmeasureMK(void)

{mk=500000/freq;

codevalue[1]=0xc1;

codevalue[0]=TAB[5];

codevalue[7]=TAB[(mk/100000)%10];

codevalue[6]=TAB[(mk/10000)%10];

codevalue[5]=TAB[(mk/1000)%10];

codevalue[4]=TAB[(mk/100)%10];

codevalue[3]=TAB[(mk/10)%10];

codevalue[2]=TAB[(mk%10)];

}

voiddisplay(void)

{

chari,p,temp;

0xc0进行比较因为类型不同所

if(codevalue[7]==TAB[0])〃不能拿codevalue直接和

以不能比较儿赋值的时候则不同!

{

codevalue[7]=0xff;if(codevalue[6]==TAB[0]){codevalue[6]=0xff;if(codevalue[5]==TAB[0]){codevalue[5]=0xff;if(codevalue[4]==TAB[0]){codevalue[4]=0xff;if(codevalue[3]==TAB[0]){codevalue[3]=0xff;if(codevalue[2]==TAB[0]){codevalue[2]=0xff;if(codevalue[1]==TAB[0]){codevalue[1]=0xff;if(codevalue[0]==TAB[0]){codevalue[0]=0xc0;}}}}}}}}

for(i=0;i<8;i++)

{

p=disbuffer[i];temp=chocode[p];

B8255=~temp;temp=codevalue[p];A8255=temp;

//delay

(1);〃多余的延时程序

temp=chocode[i];

B8255=~temp;

delay

(1);

}

}

七、实验体会和意见

在实验过程中遇到了很多很多的问题,刚开始拿到这个实验题目的时候基于8255的

8Led的数显频率计,首先想到的8255是什么东西,想起8255是大二时的前续课程中《微

机原理》中所讲过一章的内容中有所提及,8255为并口扩展芯片,可以编程,共有多种写

入方式。

关于8255的8Led的输入输出查阅了很多的资料,后来在一些书籍当中查阅到了相关有用信息,连接中加入了一块74373锁存芯片,可以对输入的数据进行锁存,这样就解

决了控制字的问题,因而就不需要再设定控制字。

在设计数显电路时遇到的问题还有很多由于先扫描还是先输出数据的问题上颠倒了次序,导致数码管显示非常的不正常。

调换次序后该问题得到了解决,据我分析应该是数据重

叠。

实验初期因为没有看清题目要求使用的是T0,T1中断既P3.5口作为外部信号输入端口

进行测量,且同样实现了显示频率脉宽的功能。

因而对于内部中断的执行也有了深入的理解,

因为题目问题是后来最后两天才发现的,所以更改比较唐突,所以该程序仍拥有很多问题。

比如测周期使用的是利用所测频率进行数值运算所得到的值,所以运算速度需要一秒左右,比较慢,而且脉宽的测量并非准确。

通过本次试验对于单片机有了一定深度的了解,对于内部各种中断,端口地址,输入输

出,寄存器的读写都有了一定的了解。

觉得单片机是一门学科,同时设计的时候也是一门艺

术。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 小学作文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2