本发明专利涉及机电设计技术领域,尤其涉及一种应用89c51单片机的秒表。
背景技术:
电子秒表是电器制造,工业自动化控制、国防、实验室及科研单位理想的计时仪器,同时也广泛应用于社会生活的方方面面。随着今年来科技的飞速发展,单片机的应用正在不断的走向深入。
发明专利内容
本发明专利涉及一种应用89c51单片机的秒表,本发明以单片机为核心,设计一个秒表,具有计时功能,按键有启动计时、数据清零、停止、时间显示。
本发明采用3个led数码管显示时间,计时范围设置为0~99.9秒,即精确到0.1秒,用按键控制秒表的“开始”、“暂停”、“复位”,按“开始”按键,开始计时;按“暂停”按键,系统暂停计时;再按“开始”键,系统继续计时;数码管显示当前计时值;按“复位”按键,系统清零。
附图说明
图1:89c51单片机引脚图。
图2:晶振电路图。
图3:复位电路图。
图4:按键电路图。
图5:显示电路图。
图6:程序流程图。
具体实施方式
为了使本发明专利的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明专利进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明专利,并不用于限定本发明专利。
本发明专利涉及一种应用89c51单片机的秒表,本发明以单片机为核心,设计一个秒表,具有计时功能,按键有启动计时、数据清零、停止、时间显示。
进一步的,本发明采用3个led数码管显示时间,计时范围设置为0~99.9秒,即精确到0.1秒,用按键控制秒表的“开始”、“暂停”、“复位”,按“开始”按键,开始计时;按“暂停”按键,系统暂停计时;再按“开始”键,系统继续计时;数码管显示当前计时值;按“复位”按键,系统清零。
进一步的,本发明采89c51单片机,89c51的引脚如图1所示。
进一步的,89c51单片机内部的振荡电路是一个高增益反相放大器,引线xtal1和xtal2分别为反相振荡放大器的输入及内部时钟工作电路的输入和来自反相振荡器的输出,该反相放大器可以配置为片内振荡器。本发明选用51单片机12mhz的内部振荡方式,电路如下:c2、c3起稳定振荡频率、快速起振的作用。晶振电路如图2所示。
进一步的,本发明的复位电路采用上电复位,上电后,由于电容充电,使rst持续一段时间的高电平,从而实现上电复位操作。这不仅能使单片机复位,还能是单片机的外围设备同时复位,当程序出现错误时,可以随时使电路复位。电路图如图3所示。
进一步的,本发明的按键电路如图4所示,当按键被按下时,相应的引脚被拉低,经扫描后,获得键值,并执行键功能程序,因此按下不同的按键,将执行不同的功能程序。
进一步的,本发明采用3个led数码管,led是七段显示器,内部有7个条形发光二极管和1个小圆点发光二极管,根据各管的亮暗组成字符。在用数码管显示时,有静态和动态两种选择,本发明采用led动态显示,用p0、p1、p2口驱动显示,由于p0口没有上拉电阻,因此p0口需要外接上拉电阻才能输出高电平,这里使用8个4.7k的电阻作为上拉电阻。电路图如图5所示。
进一步的,本发明的引脚控制如下:
p0.0—p0.7、p2.0—p2.7、p1.0—p1.7对应三个数码管的a、b、c、d、e、f、g段和小数点位;p0控制数码管十位的显示,p2控制数码管个位的现实,p1控制小数点后一问的显示,p3.2、p3.3、p3.4分别接。
进一步的,本发明的程序流程图如图6所示,程序的各个组成模块及工作流程描述:
(1)秒表的初始化:根据程序流程图,先进行秒表的初始化,即:①将i/o口p3全写1,为秒表的控制输入做好准备;②将数码管全部置零,使其处于秒表计时的初始状态;③将工作寄存器r0~r2以及30h初始化,留待后面的计时程序备用;④将定时器0置于工作方式1,并为其装入计时预置数d8fe(因为程序运行过程中占用的时间会导致一定误差,此为经实物测试之后的修正值),即将定时器定为每10ms溢出;⑤开总中断允许和定时器0中断允许。初始化完成后,即进入之后的按键扫描程序;
(2)按键检测程序:轮流检测开始计时(p3.2)、暂停计时(p3.3)、秒表清零(p3.4)三个按键。若发现有一个按键出现低电平(可能被按下),则延时10ms(调用延时子程序delay),延时完成后,若发现低电平消失,则说明该按键实际上未被按下,此时转回按键检测处继续检测;若发现仍然是低电平,则说明此键确实被按下了,此时就跳转至相应的程序标号处,执行相应的功能;
(3)开始计时:若确认“开始计时”键被按下,则跳转至程序标号“run”处,将定时器0计时允许控制位tr0置位,则定时器开始运行。此动作完成后,返回按键检测程序,等待操作者的下一次指令;
(4)计时程序:定时器0计时至10ms,溢出,引发中断,程序跳转至定时器0中断服务程序入口000bh处执行。程序跳转至中断服务程序time0。由于秒表的最小计时单位是0.1s,即100ms,因此需加入软件计时,使定时器0溢出10次之后才改变数码管的显示状态。因此每来一次中断就将30h中的数加1,若30h中的数没有到10,则给定时器0重新装入预置数,之后中断返回并继续等待中断;到10了,才进入显示程序,改变数码管的显示状态,执行完毕之后中断返回并继续等待中断;
(5)显示程序:将数码管的段选码放在数表tab中。每次100ms计时完成后,将r0中的值(初值为0)送入a,然后自加1。.若r0中的值没到10,则使用累加器a查表,并将查得的数码管段选码送入毫秒位数码管。之后将30h中的数置零,中断返回。若发现r0中的数到10了,则将r0置零,并转入秒位进位子程序second,向秒位进位,之后,继续照常向毫秒位送数。在秒位进位子程序second中,由于要用到累加器a,因此先将其推入堆栈保护。将r1中的值(初值为10)送入a,然后自加1。.若r1中的值没到20,则使用累加器a查表,并将查得的数码管段选码送入秒位数码管。若发现r1中的数到20了,则将r1重置为10,并转入十秒位进位子程序second1,向十秒位进位,之后,继续照常向秒位送数。完成后,弹出acc和psw,子程序返回。十秒位进位子程序与秒位进位子程序相似,只是没有向下一位进位的功能;
(6)暂停计时:若确认“暂停计时”键被按下,则跳转至程序标号“pause”处,将定时器0计时允许控制位tr0置零,则定时器暂停运行。此动作完成后,返回按键检测程序,等待操作者的下一次指令;
(7)秒表清零:若确认“秒表清零”键被按下,则跳转至程序标号“stop”处,将tr0置零,关闭定时器0运行。并且将数码管、工作寄存器、定时器0预置数全部重置,使其处于秒表计时的初始状态。此动作完成后,返回按键检测程序,等待操作者的下一次指令;
(8)延时程序:用于按键延时防抖,延时10ms。
进一步的,本发明的程序代码如下:
org0000h;程序开始
ajmpstart;跳转到主程序start
org000bh;定时器0中断的地址入口
ajmptime0;定时器0溢出,跳转到中断程序time0
start:;主程序
movp3,#0ffh;输入端口p3全写1
movp0,#3fh;
movp1,#3fh;
movp2,#0bfh;数码管初始化
mov30h,#00h;
movr0,#00h;
movr1,#0ah;
movr2,#00h;工作寄存器初始化
movtmod,#01h;定时器0工作于方式1
movth0,#0d8h;
movtl0,#0feh;定时器0预置数(d8feh=55550d)
setbea;开总中断允许
setbet0;开定时器0中断允许
read:;读键程序
l1:jbp3.2,l2;
lcalldelay;按键延时防抖
jbp3.2,l1;
ajmprun;确认计时键被按下,开始/继续计时
l2:jbp3.3,l3;
lcalldelay;按键延时防抖
jbp3.3,l2;
ajmppause;确认暂停键被按下,暂停计时
l3:jbp3.4,l1;
lcalldelay;按键延时防抖
jbp3.4,l3;
ajmpstop;确认清零键被按下,秒表重置
run:;计时键按下,跳转至此
setbtr0;定时器0开始/继续运行
ajmpread;
pause:;暂停键按下,跳转至此
clrtr0;
ajmpread;
time0:;定时器0溢出,中断,跳转至此
inc30h;
mova,30h;
cjnea,#0ah,time1;30h单元中的值到10了吗(计时到10毫秒了吗,也就是说,该向毫秒位送数了吗)
movdptr,#tab;30h中的值到10了,顺序执行
mova,r0;
incr0;
cjner0,#0ah,get;r0中的值到10了吗(该向秒位进位了吗)
movr0,#00h;
lcallsecond;到了,r0清零,调用进位子程序second,向秒位进位
get:;没到,跳过进位子程序
movca,@a+dptr;
movp1,a;查表并向数码管毫秒位送数
mov30h,#00h;重置30h单元
time1:;
movth0,#0d8h;
movtl0,#0feh;给定时器0重新预置数
reti;中断返回
second:;秒位进位子程序
pushacc;
pushpsw;将acc和psw推入堆栈保护
mova,r1;
incr1;
cjner1,#14h,get1;r1中的值到20了吗,也就是说,该向十秒位进位了吗
movr1,#0ah;
lcallsecond1;到了。r1重置,调用进位子程序second1,向十秒位进位
get1:;没到,跳过进位子程序
movca,@a+dptr;
movp2,a;查表并向数码管秒位送数
poppsw;
popacc;psw,acc出栈
ret;子程序返回
second1:;十秒位进位子程序
pushacc;
pushpsw;将acc和psw推入堆栈保护
mova,r2;
incr2;
cjner2,#0ah,get2;r2中的值到10了吗,也就是说,该将此位归零了吗
movr2,#00h;到了,r2清零
get2:;没到,跳过清零程序
movca,@a+dptr;
movp0,a;查表并向数码管十秒位送数
poppsw;
popacc;psw,acc出栈
ret;子程序返回
stop:;清零键按下,跳转至此
movp3,#0ffh;
movp0,#3fh;
movp1,#3fh;
movp2,#0bfh;数码管清零
mov30h,#00h;
movr0,#00h;
movr1,#0ah;
movr2,#00h;工作寄存器初始化
clrtr0;计时器0停止计时
movth0,#0d8h;
movtl0,#0feh;定时器0预置数
ajmpread;
delay:;延时10ms子程序
movr3,#50d;
d1:movr4,#100d;
d2:djnzr4,d2;
djnzr3,d1;
ret;子程序返回
tab:db06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,3fh,86h,0dbh,0cfh,0e6h,0edh,0fdh,87h,0ffh,0efh,0bfh;数码管段选码数表
end;程序结束
以上所述仅为本发明专利的较佳实施例而已,并不用以限制本发明专利,凡在本发明专利的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明专利的保护范围之内。