根据51单片机的光电计数器的设计.docx
《根据51单片机的光电计数器的设计.docx》由会员分享,可在线阅读,更多相关《根据51单片机的光电计数器的设计.docx(32页珍藏版)》请在冰豆网上搜索。
![根据51单片机的光电计数器的设计.docx](https://file1.bdocx.com/fileroot1/2023-1/28/e939078c-0f30-4ad6-aab1-c10afb940a6d/e939078c-0f30-4ad6-aab1-c10afb940a6d1.gif)
根据51单片机的光电计数器的设计
目录
1.前言 1
2光电计数器的系统设计 1
2.1系统硬件设计 1
2.1.1方案选择 1
2.1.2仪器各部分组成 2
2.2系统软件设计 3
3设计原理 5
3.1转速计算及误差分析 5
3.2转速测量 6
3.2.1门控方式计数 6
3.2.2中断方式计数 7
3.3串行显示接口 7
4软件程序的设计 8
4.11s定时 8
4.2T1计数程序 8
4.3频率数据采集 9
4.4进制转换 10
4.5数码显示 13
5软件设计总体程序 15
6总程序调试 21
7心得体会 21
参考文献 22
1.前言
21世纪是信息时代,获取信息,处理信息,运用信息。
传感与检测技术的重要性在于它是获得信息并对信息进行必要处理的基础技术,是获取信息和处理加工信息的手段,无法获取信息则无法运用信息。
传感与检测技术是一门知识面广、综合程度高、实用性很强的专业课程。
它从传感器的基本理论入手,着重讲叙传感器的结构与感测原理,传感器是一个二端口的装置,不同的传感器输入-输出特性不同,同一传感器适应不同的被测信号呈现的特性也有所不同。
尤其当被测信号为静态信号时两种状态下,传感器的输入-输出特性完全不同。
感测技术在许多新技术、新器件里都有应用,在课程安排上,以信息的传感、转换、处理为核心,从基本物理概念入手,阐述热工量、机械量、几何量等参数的测量原理及方法。
光电式传感器是将光信号转化为电信号的一种传感器。
它的理论基础是光电效应。
这类效应大致可分为三类。
第一类是外光电效应,即在光照射下,能使电子逸出物体表面。
利用这种效应所做成的器件有真空光电管、光电倍增管等。
第二类是内光电效应,即在光线照射下,能使物质的电阻率改变。
这类器件包括各类半导体光敏电阻。
第三类是光生伏特效应,即在光线作用下,物体内产生电动势的现象,此电动势称为光生电动势。
这类器件包括光电池、光电晶体管等。
光电效应都是利用光电元件受光照后,电特性发生变化。
敏感的光波长是在可见光附近,包括红外波长和紫外波长。
本课题利用AT89C51单片机,探讨一种简易光电计数器的设计思路。
2光电计数器的系统设计
2.1系统硬件设计
2.1.1方案选择
由于单片机所具有的特性,它特别适用于各种智能仪器仪表,家电等领域中,可以减少硬件以减轻仪表的重量,便于携带和使用,同时也可能低存本,提高性能价格之比。
该光电计数器选用MCS-51系列单片机的AT89C51芯片,该系统的整体结构框图见下图2.1所示:
图2.1光电计数器总结构流程图
2.1.2仪器各部分组成
u 稳压直流电源的实现
(1) 稳压直流电源原理图
(2) 稳压直流电源原理
u 传感器
传感器为红外光电式传感器。
其中一个发光二极管发出红外波长的光,可不受室内自然光的影响,此光照到旋转物体上反射回后,被光敏三极管接收。
光敏三极管接受到此信号后,经放大,整形转换为矩形脉冲信号送入MCS-51单片机的外部中断输入端INTO和INT1上。
u 显示器
4个LED数码管作显示器,通过573驱动。
u 数据存储器
数据存储器由AT89C51片内的低128字节和8155内部256字节的RAM组成.AT89C51的内部RAM主要用于堆栈,工作寄存器,显示缓冲器,各测量参数的计算缓冲器和标致位等。
而8155内部的RAM除上部4个单元外,全部用于存放转速和线速度值,其存储空间划分如图2-2所示,共分为三组,每组84个单元,可存入42个16位二进制数据,即42个4位16进制数据。
如下图2.1为外部RAM存储器空间划分图。
图2.1外部RAM存储器空间划分
u 检测齿轮:
检测齿轮上有10个齿均匀分布在轮盘周围,并被直接固定在被测轴上,安装时光电耦合器的发光二极管和光敏三极管正对齿轮上的齿,当被测轴转动时带动检测齿轮转动,光电耦合器通过对检测齿轮上的齿进行耦合从而产生数字脉冲。
脉冲经过放大送向单片机的计数端。
u 系统工作简图
u 整体硬件电路设计
2.2系统软件设计
系统监控程序的主程序流程框图见图2.2系统软件采用模块式结构,由主程序及多个功能模块子程序组成,可使程序清楚,易编易读,便于调试和修改。
图2.2监控主程序流程图
主程序的任务是对AT89C51单片机初始化,如设置堆栈,预置各定时器的控制字,初始化显示缓冲区,8155的初始化,设置标致位,清内存等;然后显示开机初始化状态,扫描键盘,根据按下键的功能各自的功能操作。
3设计原理
3.1转速计算及误差分析
根据转速,周期,频率之间的关系可知:
(3-1)
(3-2)
(3-3)
式中,n—被测转速,r/min;
T-转速信号周期,s;
f-转速信号频率,Hz;
-计算计数脉冲的周期,又称时基,
.
将式(3-3)代入式(6-1),可得:
(3-4)
用十六进制数表示,为:
式中N已存入75H,74H,73H单元。
利用除法子程序,即可求出转速。
下面计算系统得相对误差。
分别对式(3-1)和(3-3)求微分
(3-5)
(3-6)
将式(3-6代入(3-5),可得:
(3-7)
式中,
为量化误差,
个计数脉冲,又已知时基
,故
(3-8)
由式(3-8)可知,相对误差与频率成正比,即相对误差随转速得升高而升高。
因此,为了提高测量精度,高转速时需要连续测量数个周期。
本系统中为4个周期,即测得的N为4个周期内的总和,所以
(3-9)
(3-10)
用十六进制数表示,为
对式(3-9)进行微分得:
.
因此,可求出高速测量时的相对误差为
。
同样,代入
,
个计数脉冲,则:
(3-11)
将式(3-11)与式(3-8)比较可知,采用多周期测量相对精度大大提高。
若设置系统的临界转速为3662r/min,其对应的每周期计数脉冲个数为
。
开机时,首先按低转速测量,然后判断转速n是高于还是低于3662r/min。
若低与此临界值,则仍然低转速测量,若高于它,便主动转入高转速测量,即连续测量4个周期.这样,就可以实现量程自动切换。
3.2转速测量
由式(3-4)和(3-10)可知,只要能够求出脉冲个数N,即可求出转速。
为了得到计数脉冲,可以采用门控方式的硬件计数方法,也可以采用中断方式的软件计数方法。
3.2.1门控方式计数
由AT89C51定时器/计数器T0工作原理可知,当其工作在计数方式,只要T0引脚上有负跳变,计数器就加1。
CPU在每个机器周期的
状态时,采样T0,所以需要2个机器周期才能识别一个T0的负跳变,即T0的周期至少应该等于2倍机器周期。
若晶振频率为6MHz,6分频后得到ALE信号,故ALE信号周期为
,机器周期为
。
由此可知,最低计数脉冲周期
为
,可由ALE信号经74LS74中的两个D触发器4分频后取得。
为了保证精度,要求AT89C51内部计数器0与
的上跳沿同步,此时开始计数,在
的下跳沿停止计数。
图3.1门控脉冲与计数脉冲
为了实现此功能,可以利用51单片机特有的定时器门控工作方式,通过指令MOVTHOD,#1DH来设置定时器/计数器的工作方式。
这里使定时器/计数器0工作于16位技术方式,并由
门脉冲进行控制。
只有当
为高电平时,且运行控制位
时,计数器0才开始工作。
一旦
转为低电平,计数器0即刻停止计数。
3.2.2中断方式计数
高转速时,为了连续测量4个输入脉冲周期,可以采用中断方式计数。
在初始化或前一次测量结果时,单片机禁止”外部中断0”和”定时器0”溢出中断。
设置”外部中断0”为负跳沿触发方式,设定”计数器0”为非门控计数方式,然后等待中断。
外部中断负脉冲一到,立刻启动”计数器0”对T0的
计数脉冲进行计数。
计到4个测量周期时,停止”计数器0”工作,禁止外”中断”,恢复测量周期常数3,并将计得的脉冲数存入相应的单元。
门控方式和中断方式计数,有效的解决了精度测量输入脉冲周期和高低量程自动切换问题,测得计数脉冲个数后,即可转入计算转速n子程序,计算结果得BCD吗存入相应的4个存储单元,以备显示。
3.3串行显示接口
51单片机的I/O口串行口为全双工接口,串行工作在方式0时,外接移位寄存器,可将串口转换成8位并口。
其显示的速率为
即
,可以满足显示器稳定显示。
串行数据的接受/发送均通过RXD,而由TXD输出移位脉冲。
在串口上外接4片移位寄存器74LS64作为8位显示器的静态显示口。
变串行输入为并行输出,经缓冲器接至数码管。
4软件程序的设计
4.11s定时
本次设计选用定时器T0完成定时功能,选用方式1时最多也只能定时
,显然不能满足定时1
的要求,可以用下面这种方法解决:
采用T0定时10
,连续循环定时100次即可完成1
定时,用一个计数单元20H存放循环的次数,每一次循环20H单元自减1,当20H单元为零时则1
定时到时。
定时器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
4.2T1计数程序
设计中T1采用计数功能,需要注意的一个问题是,输入的待测时钟信号的频率最高可以达到460800Hz,但计数器最多只能计数65536次,显然需要对计数单元进行扩展,扩展的思路是除了计数器T1的TH1和TL1用于计数外,再选用一个计数单元23H,每当计数器T1溢出回零时产生中断,中断程序执行23H单元自增1,这样,当一秒到时时采集的计数数据,23H单元存放的是数据的最高位,TH1存放的是数据的次高位,TL1存放的是数据的最低位。
当然,这里所说的“最高位”“次高位”以及“最低位”都是针对十六进制而言的。
计数器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
4.3频率数据采集
到1
定时时,存储计数器T1以及扩充计数单元23H记录的数据即为输入时钟信号的频率,为了保证记录的频率精确度,到1
定时后应立即停止T1的计数,因为指令的执行也需要时间,并且待测的时钟信号频率越高,指令执行所需要的时间就越不能忽略,这里采用的指令为CLRTR1。
数据采集程序如下:
CLRTR0
MOV22H,TH1 ;1s定时到则采集数据
MOV21H,TL1
AJMPEXIT
4.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。
图4.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;存储十进制数十万位
4.5数码显示
将采集到的频率转换为十进制数后,还不能直接将这些数送给数码显示,因为七段LED数码管内部由7个条形发光二极管和一个小圆点发光二极管组成,根据各管的亮暗组合成字符。
本次设计所给数码管十进制数显示代码如下所示。
表4.1 LED十进制字形显示代码表
将十进制数转换为相应的LED显示的代码,最容易实现的编程方法就是查表,因数码管最多只需要显示六位,只需要查六次表就可以了。
编写的程序如下:
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所示。
具体程序实现如下:
NUMBYT EQU5DH
SLA EQU5EH
MTD EQU5FH
SCL EQUP1.0
SDA EQUP1.1
MOVMTD,#10H ;字节数据发送
MOVNUMBYT,#09H
MOVSLA,#70H
LCALLWRNBYT
WRNBYT:
PUSH PSW
WRNBYT1:
MOVPSW,#18h
CALLSTA
MOVA,SLA
CALLWRB
CALLCACK
JB F0,WRNBYT
MOV R0,#MTD
MOV R5,NUMBYT
WRDA:
MOV A,@R0
LCALL WRB
LCALLCACK
JB F0,WRNBYT1
INC R0
DJNZ R5,WRDA
LCALL STOP
POP PSW
RET
WRB:
MOV R7,#8
WLP:
RLC A
JC WR1
CLR SDA
SETB SCL
NOP
NOP
NOP
NOP
CLR SCL
DJNZ R7,WLP
RET
WR1:
SETB SDA
SETB SCL
NOP
NOP
NOP
NOP
CLR SCL
CLR SDA
DJNZ R7,WLP
RET
CACK:
;应答位检查
SETB SDA
SETB SCL
NOP
NOP
MOV C,SDA
MOV F0,C
CLR SCL
NOP
NOP
RET
STA:
SETB SDA;发送起始位
SETB SCL
NOP
NOP
NOP
NOP
CLR SDA
NOP
NOP
NOP
NOP
CLR SCL
RET
STOP:
CLR SDA;发送停止位
SETB SCL
NOP
NOP
NOP
NOP
SETB SDA
NOP
NOP
NOP
NOP
CLR SCL
RETI
5软件设计总体程序
各单元子程序已经设计完毕,将各子程序通过适当的指令链接起来,总程序的第一部分为T0、T1初始化,第二部分为1
定时,第三部分为计数,第四部分为采集频率,第五福分为进制转化,第六部分为数码显示,这几部分构成了光电计数器软件系统的总体程序见附表。
6总程序调试
编写的光电计数器软件总体程序编译成HEX文件,烧写入51单片机内,P3.5角输入一定频率(较小)的时钟信号,观察数码管显示的频率与输入信号的频率相符,逐渐增大输入信号的频率,数码显示的频率开始出现误差,并且误差随着输入信号频率的增加而增加,当输信号达到频率计所允许输入的最高频率时,误差达到了650Hz,即误差
此误差很小可以认误差在允许的范围内,即频率计的计频功能满足要求。
另外在观察数码管显示的时候,发现高位的“0”仍然能够显示,而通常十进制的高位的“0”通常是省略的。
显示“0”的原因是没有考虑到频率值小于六位十进制数的情况,当频率小于六位十进制数时,传送到ZLG7290显示区的数据仍然是六位,高位由“0”填充,因此会出现高位显示“0”的情况。
为了解决这个问题,需要另外添加一段屏蔽高位的“0”的程序。
解决的思想是把高位“0”的个数记下,设为n,那么只需要传送给管理芯