基于单片机的频率计设计1doc.docx
《基于单片机的频率计设计1doc.docx》由会员分享,可在线阅读,更多相关《基于单片机的频率计设计1doc.docx(34页珍藏版)》请在冰点文库上搜索。
![基于单片机的频率计设计1doc.docx](https://file1.bingdoc.com/fileroot1/2023-5/7/8d5353ad-922b-4639-93f0-3ca63e5d681d/8d5353ad-922b-4639-93f0-3ca63e5d681d1.gif)
基于单片机的频率计设计1doc
目录
1绪论1
2总体方案介绍1
3硬件设计2
4单元程序的设计2
4.11s定时2
4.2T1计数程序4
4.3频率数据采集6
4.4进制转换6
5运行调试8
参考文献8
1前言
单片机是20世纪中期发展起来的一种面向控制的大规模集成电路模块,具有功能强、体积小、可靠性高、价格低廉等特点,在工业控制、数据采集、智能仪表、机电一体化、家用电器等领域得到了广泛的应用,极大的提高了这些领域的技术水平和自动化程度。
51系列单片机是国内目前应用最广泛的一种8位单片机之一,随着嵌入式系统、片上系统等概念的提出和普遍接受及应用。
51系列及其衍生单片机还会在继后很长一段时间占据嵌入式系统产品的低端市场,因此,作为新世纪的大学生,在信息产业高速发展的今天,掌握单片机的基本结构、原理和使用是非常重要的。
本次课程设计的内容是使用89C51RC单片机最小系统设计频率计系统,系统以单片机为主控单元,主要用于对方波频率的测量。
2频率计原理
频率的测量实际上就是在1s时间内对信号进行计数,计数值就是信号频率。
用单片机设计频率计通常采用两种办法,第一种方法是使用单片机自带的计数器对输入脉冲进行计数;第二种方法是单片机外部使用计数器对脉冲信号进行计数,计数值再由单片机读取。
第一种方法的好处是设计出的频率计系统结构和程序编写简单,成本低廉,不需要外部计数器,直接利用所给的单片机最小系统就可以实现。
这种方法的缺陷是受限于单片机计数的晶振频率,输入的时钟频率通常是单片机晶振频率的几分之一甚至是几十分之一,在本次设计使用的98C51单片机,由于检测一个由“1”到“0”的跳变需要两个机器周期,前一个机器周期测出“1”,后一个周期测出“0”。
故输入时钟信号的最高频率不得超过单片机晶振频率的二十四分之一。
第二种方法的好处是输入的时钟信号频率可以不受单片机晶振频率的限制,可以对相对较高频率进行测量,但缺点是成本比第一种方法高,设计出来的系统结构和程序也比较复杂。
由于成本有限,本次设计中采用第一种方法,因此输入的时钟信号最高频率不得高于11.0592MHz/24=460.8KHz。
对外部脉冲的占空比无特殊要求。
根据频率检测的原理,很容易想到利用51单片机的T0、T1两个定时/计数器,一个用来定时,另一个用来计数,两者均应该工作在中断方式,一个中断用于1s时间的中断处理,一个中断用于对频率脉冲的计数溢出处理,(对另一个计数单元加一),此方法可以弥补计数器最多只能计数65536的不足。
3设计思想
明确频率计工作原理以后,为了更方思路更清晰地对程序编写,还应该作出程序的总体框图,如图3.1所示。
程序的主体可以分为4个模块:
定时计数、采集数据、进制转换和数码显示,当然,程序还应该包括很多细节问题,例如为了数码显示通过
通信的方式把需要显示的数据传送给数码管管理芯片ZLG7290;为了数码管能清晰的显示数据,需要先对管理芯片对应的显示区域清零;通常十进制数字高位的零时不用显示的,所以还应该对数码显示高位的零屏蔽掉。
图3.1频率计系统总体框图
451单片机系统的硬件连接及调试
本次课程设计使用的单片机系统是根据老师提供的系统原件,自己焊接而成。
焊接完成以后,首先烧写控制LED发光二极管闪烁的程序后,发现发光二极管是根据自己的设计而闪烁,烧写程序控制发光数码管显示时,数码管同样是根据自己的设计而显示的字符,说明本次51单片机的硬件焊接取得成功。
此次设计要求制作一频率计系统,需要使用的硬件主要包括51单片机芯片,ZLG7290数码管管理芯片和数码管。
另外还是用到排线若干,下载线及电源线。
其中51单片机硬件链接如图4.1所示,ZLG7290芯片连接图如图4.2所示,数码管连接图如图4.3所示。
图4.151单片机硬件连接图
图4.2ZLG7290硬件连接图
图4.3数码管硬件连接图
5单元程序的设计
5.11s定时
本次设计选用定时器T0完成定时功能,选用方式1时最多也只能定时
,显然不能满足定时1
的要求,可以用下面这种方法解决:
采用T0定时10
,连续循环定时100次即可完成1
定时,用一个计数单元20H存放循环的次数,每一次循环20H单元自减1,当20H单元为零时则1
定时到时。
其程序流程图如图5.1所示。
图5.11s定时流程图
定时器T0初始化程序如下:
MOVIE,#8AH;开放T0、T1中断
MOVTMOD,#51H;T0定时,T1计数,都工作于方式一
MOV20H,#100;100*10ms=1s
SETBTR0
根据流程图设计的1s定时程序如下:
T0INT:
DJNZ20H,NEXT
NEXT:
MOVTH0,#0DCH;1s还未到则置初值继续定时
MOVTL0,#00H
EXIT:
RETI
5.2T1计数程序
设计中T1采用计数功能,需要注意的一个问题是,输入的待测时钟信号的频率最高可以达到460800Hz,但计数器最多只能计数65536次,显然需要对计数单元进行扩展,扩展的思路是除了计数器T1的TH1和TL1用于计数外,再选用一个计数单元23H,每当计数器T1溢出回零时产生中断,中断程序执行23H单元自增1,这样,当一秒到时时采集的计数数据,23H单元存放的是数据的最高位,TH1存放的是数据的次高位,TL1存放的是数据的最低位。
当然,这里所说的“最高位”“次高位”以及“最低位”都是针对十六进制而言的。
T1计数程序的流程图如图5.2所示。
图5.2T1计数流程图
计数器T1初始化程序如下:
MOVIE,#8AH;开放T0、T1中断
MOVTMOD,#51H;T0定时,T1计数,都工作于方式一
MOVTH1,#00H
MOVTL1,#00H;计数初值为零
SETBTR1
根据流程图设计的计数程序如下:
MOV21H,#0
MOV22H,#0
MOV23H,#0;此三个单元存放采集到的频率
T1INT:
INC23H;计数器溢出则23H单元自增1
RETI
5.3频率数据采集
到1
定时时,存储计数器T1以及扩充计数单元23H记录的数据即为输入时钟信号的频率,为了保证记录的频率精确度,到1
定时后应立即停止T1的计数,因为指令的执行也需要时间,并且待测的时钟信号频率越高,指令执行所需要的时间就越不能忽略,这里采用的指令为CLRTR1。
数据采集程序如下:
CLRTR0
MOV22H,TH1;1s定时到则采集数据
MOV21H,TL1
AJMPEXIT
5.4进制转换
从计数器采集到的频率数据是十六进制的,如果直接把这些数据送给数码管显示显然很不直观,因此需要把这些数据向十进制转换。
转换的算法有两种,第一种算法的思想是对该十六进制数除以100,商为百位,余数再除以10,再得到的商为十位,余数为个位。
这种算法虽然程序的编写非常简单,但是它的局限性也非常明显,即它只能对不大于两位的十六进制数进行转换,对于大于两位的十进制数则无能为力。
这次设计的频率计频率范围远不止两位十六进制数就能记得下,所以这里采用第二种方法。
第二种方法算法的编程实现非常复杂,但是可以对任意长度的十六进制数向十进制转换。
这种算法的基本思路是:
第一步将最高位的高半字节提出来,除以10,把商存储起来,余数与最高位的低半字节组合成一个字节,再除以10,再存储商,余数以此类推,直到最后一次计算得到的余数即为十进制数的个位;第二步把第一步存储的商组合成一个字节,依次除以10,仍然把每次得到的商存储起来,以此类推最后一次得到的余数即为十进制数的十位;以后也是以此类推得到十进制数的百位、千位……以上算法必须要注意的一个为题是,每次得到的余数与低位的半字节组合成一个字节时,余数必须放在该字节的高半字节,否则计算错误。
该本次频率计系待测的时钟信号的最高频率为460800Hz,对应的十六进制数为70800H,这里就以70800H转换为十进制数为例来说明这种算法。
第一步:
用7H除以10,商0H余7H,把商0存储在24H单元,余数7H与下一个字节08H的高半字节0H组合成一个字节70H。
70H除以10,商BH余2H,把商BH存储在25H单元,余数2H与8H组合成一个字节28H。
28H除以10,商4H余0H,把商4H存储在26H单元,余数0H与0H组合成一个字节00H。
00H除以10,商0H余0H,把商0H存储在27H单元,余数0H与0H组合成一个字节00H。
00H除以10,商0H余0H,把商0H存储在28H单元,余数0即为所需十进制数的个位。
第二步:
把存储在24H与25H单元的商组合成一个字节0BH。
0BH除以10,同第一步,存储商,余数与下一个商组合成一个字节,再除以10,一次类推得到十进制数的十位0。
第三步:
方法同第二步,得到十进制数的百位8。
第四步:
方法同第三步,得到十进制数的千位0。
第五步:
方法同第四步,得到十进制数的万位6和十万位4。
最后得到了十进制数460800。
图5.3详细的展示了这种进制转换算法的过程。
图5.3进制转换说明图
这种算法的编程实现如下,转换后的十进制数由低到高依次存放再50H—60H单元中。
ZHUANHUAN:
;向十进制转换
MOVA,23H
MOVB,#0AH
DIVAB
MOV24H,A;存储第一位商
;---------------
MOVA,B
MOV30H,22H
ANL30H,#0F0H
ADDA,30H
SWAPA
MOVB,#0AH
DIVAB
MOV25H,A;存储第二位商
;---------------
MOVA,B
SWAPA
ANL22H,#0FH
ADDA,22H
MOVB,#0AH
DIVAB
MOV26H,A;存储第三位商
;---------------
MOVA,B
MOV30H,21H
ANL30H,#0F0H
ADDA,30H
SWAPA
MOVB,#0AH
DIVAB
MOV27H,A;存储第四位商
;---------------
MOVA,B
SWAPA
ANL21H,#0FH
ADDA,21H
MOVB,#0AH
DIVAB
MOV28H,A;存储第五位商
MOV50H,B;存储十进制数个位
;;;;;;;;;;;;;;;;;
MOVA,24H
SWAPA
ADDA,25H
MOVB,#0AH
DIVAB
MOV24H,A;存储第一位商
;---------------
MOVA,B
SWAPA
ADDA,26H
MOVB,#0AH
DIVAB
MOV25H,A;存储第二位商
;---------------
MOVA,B
SWAPA
ADDA,27H
MOVB,#0AH
DIVAB
MOV26H,A;存储第三位商
;---------------
MOVA,B
SWAPA
ADDA,28H
MOVB,#0AH
DIVAB
MOV27H,A;存储第四位商
MOV51H,B;存储十进制数十位
;;;;;;;;;;;;;;;;;
MOVA,24H
SWAPA
ADDA,25H
MOVB,#0AH
DIVAB
MOV24H,A;存储第一位商
;---------------
MOVA,B
SWAPA
ADDA,26H
MOVB,#0AH
DIVAB
MOV25H,A;存储第二位商
;---------------
MOVA,B
SWAPA
ADDA,27H
MOVB,#0AH
DIVAB
MOV26H,A;存储第三位商
MOV52H,B;存储十进制数百位
;;;;;;;;;;;;;;;;;
MOVA,24H
SWAPA
ADDA,25H
MOVB,#0AH
DIVAB
MOV24H,A;存储第一位商
;---------------
MOVA,B
SWAPA
ADDA,26H
MOVB,#0AH
DIVAB
MOV25H,A;存储第二位商
MOV53H,B;存储十进制数千位
;;;;;;;;;;;;;;;;;
MOVA,24H
SWAPA
ADDA,25H
MOVB,#0AH
DIVAB
MOV54H,B;存储十进制数万位
MOV55H,A;存储十进制数十万位
5.5数码显示
将采集到的频率转换为十进制数后,还不能直接将这些数送给数码显示,因为七段LED数码管内部由7个条形发光二极管和一个小圆点发光二极管组成,根据各管的亮暗组合成字符。
本次设计所给数码管十进制数显示代码如下所示。
表5.1LED十进制字形显示代码表
0---------------------------FC1---------------------------60
2---------------------------DA3--------------------------F2
4---------------------------665--------------------------B6
6---------------------------BE7---------------------------E0
8---------------------------FE9---------------------------E6
将十进制数转换为相应的LED显示的代码,最容易实现的编程方法就是查表,因数码管最多只需要显示六位,只需要查六次表就可以了,图5.4是将十进制数对应的LED显示代码存入以60H为首单元的流程图。
图5.4十进制数转换为显示代码流程图
根据流程图编写的流程图如下:
MOVR0,#50H
MOVR1,#5FH
MOVDPTR,#TAB
NEXT3:
MOVA,@R0
MOVCA,@A+DPTR
INCR0
INCR1
MOV@R1,A;把即将数码管显示的数据送入以60H为首的单元
DJNZR2,NEXT3
TAB:
DB0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,0FEH,0F6H
得到十进制数的LED显示代码以后,就可以把这些代码送入数码管显示了,方法是50单片机先通过
通信的方式把显示代码发送给数码管管理芯片ZLG7290相应的显示区域,就可以通过数码管显示频率了。
51单片机通过
通信传送数据的过程如图5.5所示。
图5.5
通信过程框图
具体程序实现如下:
NUMBYTEQU5DH
SLAEQU5EH
MTDEQU5FH
SCLEQUP1.0
SDAEQUP1.1
MOVMTD,#10H;字节数据发送
MOVNUMBYT,#09H
MOVSLA,#70H
LCALLWRNBYT
WRNBYT:
PUSHPSW
WRNBYT1:
MOVPSW,#18h
CALLSTA
MOVA,SLA
CALLWRB
CALLCACK
JBF0,WRNBYT
MOVR0,#MTD
MOVR5,NUMBYT
WRDA:
MOVA,@R0
LCALLWRB
LCALLCACK
JBF0,WRNBYT1
INCR0
DJNZR5,WRDA
LCALLSTOP
POPPSW
RET
WRB:
MOVR7,#8
WLP:
RLCA
JCWR1
CLRSDA
SETBSCL
NOP
NOP
NOP
NOP
CLRSCL
DJNZR7,WLP
RET
WR1:
SETBSDA
SETBSCL
NOP
NOP
NOP
NOP
CLRSCL
CLRSDA
DJNZR7,WLP
RET
CACK:
;应答位检查
SETBSDA
SETBSCL
NOP
NOP
MOVC,SDA
MOVF0,C
CLRSCL
NOP
NOP
RET
STA:
SETBSDA;发送起始位
SETBSCL
NOP
NOP
NOP
NOP
CLRSDA
NOP
NOP
NOP
NOP
CLRSCL
RET
STOP:
CLRSDA;发送停止位
SETBSCL
NOP
NOP
NOP
NOP
SETBSDA
NOP
NOP
NOP
NOP
CLRSCL
RETI
6频率计系统总体程序
各单元子程序已经设计完毕,将各子程序通过适当的指令链接起来,总程序的第一部分为T0、T1初始化,第二部分为1
定时,第三部分为计数,第四部分为采集频率,第五福分为进制转化,第六部分为数码显示,这几各部分即构成了频率计系统的总体程序,如下所示。
NUMBYTEQU5DH
SLAEQU5EH
MTDEQU5FH
SCLEQUP1.0
SDAEQUP1.1
ORG0000H
AJMPSTART
ORG000BH;T0中断入口
AJMPT0INT
ORG001BH;T1中断入口
AJMPT1INT
ORG0030H
START:
MOVSP,#70H
MOVIE,#8AH;开放T0、T1中断
MOVTMOD,#51H;T0定时,T1计数
MOVTH0,#0DCH
MOVTL0,#00H;定时10ms
MOV20H,#100;100*10ms=1s
MOVTH1,#00H
MOVTL1,#00H
MOV21H,#0
MOV22H,#0
MOV23H,#0;存放采集到的频率
SETBTR1
SETBTR0
WAIT:
AJMPWAIT;等待中断
T1INT:
INC23H;计数器溢出则23H单元自增1
RETI
T0INT:
;定时10ms产生中断
DJNZ20H,NEXT1
CLRTR1
CLRTR0
MOV22H,TH1;1s时间到则采集数据
MOV21H,TL1
ACALLDISPLAY
AJMPEXIT
NEXT1:
MOVTH0,#0DCH;继续定时
MOVTL0,#00H
EXIT:
RETI
DISPLAY:
MOVR0,#60H
MOVR1,#08H;对60H-67H单元清零
NEXT2:
MOV@R0,#0
INCR0
DJNZR1,NEXT2
ZHUANHUAN:
;进制转换
MOVA,23H
MOVB,#0AH
DIVAB
MOV24H,A;存储第一位商
;---------------
MOVA,B
MOV30H,22H
ANL30H,#0F0H
ADDA,30H
SWAPA
MOVB,#0AH
DIVAB
MOV25H,A;存储第二位商
;---------------
MOVA,B
SWAPA
ANL22H,#0FH
ADDA,22H
MOVB,#0AH
DIVAB
MOV26H,A;存储第三位商
;---------------
MOVA,B
MOV30H,21H
ANL30H,#0F0H
ADDA,30H
SWAPA
MOVB,#0AH
DIVAB
MOV27H,A;存储第四位商
;---------------
MOVA,B
SWAPA
ANL21H,#0FH
ADDA,21H
MOVB,#0AH
DIVAB
MOV28H,A;存储第五位商
MOV50H,B;存储十进制数个位
;;;;;;;;;;;;;;;;;
MOVA,24H
SWAPA
ADDA,25H
MOVB,#0AH
DIVAB
MOV24H,A;存储第一位商
;---------------
MOVA,B
SWAPA
ADDA,26H
MOVB,#0AH
DIVAB
MOV25H,A;存储第二位商
;---------------
MOVA,B
SWAPA
ADDA,27H
MOVB,#0AH
DIVAB
MOV26H,A;存储第三位商
;---------------
MOVA,B
SWAPA
ADDA,28H
MOVB,#0AH
DIVAB
MOV27H,A;存储第四位商
MOV51H,B;存储十进制数十位
;;;;;;;;;;;;;;;;;
MOVA,24H
SWAPA
ADDA,25H
MOVB,#0AH
DIVAB
MOV24H,A;存储第一位商
;---------------
MOVA,B
SWAPA
ADDA,26H
MOVB,#0AH
DIVAB
MOV25H,A;存储第二位商
;---------------
MOVA,B
SWAPA
ADDA,27H
MOVB,#0AH
DIVAB
MOV26H,A;存储第三位商
MOV52H,B;存储十进制数百位
;;;;;;;;;;;;;;;;;
MOVA,24H
SWAPA
ADDA,25H
MOVB,#0AH
DIVAB
MOV24H,A;存储第一位商
;---------------
MOVA,B
SWAPA
ADDA,26H
MOVB,#0AH
DIVAB
MOV25H,A;存储第二位商
MOV53H,B;存储十进制数千位
;;;;;;;;;;;;;;;;;
MOVA,24H
SWAPA
ADDA,25H
MOVB,#0AH
DIVAB
MOV54H,B;存储十进制数万位
MOV55H,A;存储十进制数十万位
PINBI:
;将高位的0屏蔽不显示
MOVR3,#0
MOVR0,#55H
ST2:
MOVA,@R0
JZST1
AJMPSHUMA
ST1:
INCR3
DECR0
AJMPST2
SHUMA:
MOVA,#6
CLRC
SUBBA,R3
MOVR2,A;将需要显示的位数存入R2
MOVR0,#50H
MOVR1,#5FH
MOVDPTR,#TAB
NEXT3:
MOVA,@R0
MOVCA,@A+DPTR
INCR0
INCR1
MOV@R1,A
DJNZR2,NEXT3
MOVMTD,#10H
MOVNUMBYT,#09H
MOVSLA,#70H
LCALLWRNBYT
RET
WRNBYT:
PUSHPSW
WRNBYT1:
MOVPSW,#18h
CALLSTA
MOVA,SLA
CALLWRB
CALLCACK
JBF