单片机课程设计篮球计时计分器.docx
《单片机课程设计篮球计时计分器.docx》由会员分享,可在线阅读,更多相关《单片机课程设计篮球计时计分器.docx(22页珍藏版)》请在冰豆网上搜索。
单片机课程设计篮球计时计分器
1概述
1.1单片机简介
单片机是指一个集成在一块芯片上的完整计算机系统。
尽管他的大部分功能集成在一块小芯片上,但是它具有一个完整计算机所需要的大部分部件:
CPU、内存、内部和外部总线系统,目前大部分还会具有外存。
同时集成诸如通讯接口、定时器,实时时钟等外围设备。
而现在最强大的单片机系统甚至可以将声音、图像、网络、复杂的输入输出系统集成在一块芯片上。
单片机也被称为微控制器(Microcontroller),是因为它最早被用在工业控制领域。
单片机由芯片内仅有CPU的专用处理器发展而来。
最早的设计理念是通过将大量外围设备和CPU集成在一个芯片中,使计算机系统更小,更容易集成进复杂的而对体积要求严格的控制设备当中。
INTEL的Z80是最早按照这种思想设计出的处理器,从此以后,单片机和专用处理器的发展便分道扬镳。
早期的单片机都是8位或4位的。
其中最成功的是INTEL的8031,因为简单可靠而性能不错获得了很大的好评。
此后在8031上发展出了MCS51系列单片机系统。
基于这一系统的单片机系统直到现在还在广泛使用。
随着工业控制领域要求的提高,开始出现了16位单片机,但因为性价比不理想并未得到很广泛的应用。
90年代后随着消费电子产品大发展,单片机技术得到了巨大的提高。
1.2课程设计的意义
课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程.随着科学技术发展的日新日异,单片机已经成为当今计算机应用中空前活跃的领域,在生活中可以说得是无处不在。
因此作为二十一世纪的大学来说掌握单片机的开发技术是十分重要的。
1.3任务与要求
设计一个单片机系统用于篮球比赛计时计分,满足以下功能要求:
(1)能记录整个赛程的比赛时间,并能修改比赛时间。
(2)能随时刷新甲、乙两队在整个比赛过程中的比分。
(3)中场交换比赛场地时,能交换甲、乙两队比分的位置。
2系统总体方案及硬件设计
2.1、系统总体方案设计
本设计是采用AT89C52单片机为核心设计的一个用于赛场的篮球计时计分器。
本设计采用定时器T0中断计时,显示部分分为计时和计分显示两部分,均采用共阴极LED显示。
单片机P3口(P3.0——P3.5)是计时计分显示共用的扫描口,P0口是计时数据输出口,P2口是计分数据输出口。
计时部分计时范围宽,而且可定时设定与小时、分钟调整;计分部分调整灵活,显示范围宽,足以满足各种规模赛程需要。
两个显示模块均采用动态扫描方式显示。
2.2、硬件系统设计
2.2.1单片机的选择
AT89C52单片机是美国ATMEL公司生产的低功耗,高性能CMOS8位单片机,片内含4Kbytes的可系统编程的Flash只读程序存储器,器件采用ATMEL公司的高密度,非易失性存储技术生产,兼容标准8051指令系统及引脚。
具有如下特点:
40个引脚,4kBytesFlash片内程序存储器,128bytes的随机存取数据存储器(RAM),32个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器.。
它集Flash程序存储器,既可在线编程(ISP)也可用传统方法进行编程及通用8位微处理器于单片芯片中,ATMEL公司的功能强大,低价单片机可为您提供许多高性价比的应用场合,可灵活应用于各种控制领域。
由于AT89C52的上述优点,结合本设计的功能要求和降低成本,故本设计采用单片机AT89C52。
图2-1AT89C52管脚图
2.2.2、时钟电路模块
MCS-51内部有一个用于构成振荡器的高增益反相放大器,此放大器的输入和输出端分别是引脚XTAL1和XTAL2,在XTAL1和XTAL2上外接时钟源即可构成时钟电路。
有内部和外部两种时钟产生方式。
本设计采用的是外部方式,原理图如图所示:
图2-2时钟电路
参数选择:
C1、C2对频率有微调作用,当外接晶振时,C1和C2通常选择10——30pF;当外接陶瓷谐振器时,C1和C2的典型值约为40+/-10pF,在设计印刷电路板时,晶体或陶瓷谐振器和电容应尽可能安装在单片机芯片附近,以减少寄生电容,保证振荡器稳定和可靠的工作。
为提高稳定性,应采用NPO电容。
本设计采用的震荡频率是12MH
2.2.3、复位电路模块
复位电路的基本功能是:
系统上电时提供复位信号,直至系统电源稳定后,撤销复位信号。
为可靠起见,电源稳定后还要经一定的延时才撤销复位信号,以防电源开关或电源插头分-合过程中引起的抖动而影响复位。
上电复位设利用电容充电来实现的,即上电瞬间RST/Vpd端的电位与Vcc相同,随着充电电流的减少,RST/Vpd的电位下降,最后被嵌位在0V。
按钮电平复位是当按下按钮后,电源Vcc通过电阻R施加在单片机复位端RST/Vpd上,实现单片机复位。
本设计采用的是上电+按钮电平复位电路,是上电自动复位与按钮电平复位电路的组合,当振荡频率选11.0592MH时。
电容C取10uF,R取10K,Rs取1K。
图2-3复位电路
2.2.4、按键控制模块
本设计采用的是用查询方式的,也就是把按键接在P1口,用程序查询方式查询那个按键按下,执行相应的操作。
图如下:
图2-4按键模块
2.2.5、数码管显示原理
数码管实际上是由7个发光管组成8字形构成的,加上小数点就是8个。
我们分别把他命名为A,B,C,D,E,F,G,H。
图2-5数码管内部结构图
假设我们要显示一个数字2,那么A、B、G、E、D这5个段的发光管亮就可以了,C、F、H不亮,同时由于接法为共阳接法,那么为低电平是亮,为高电平是灭。
从高往低排列,P1.7-P1.0写成二进制为01111110,把他转化为16进制则为A2H。
我们可以根据硬件的接线把数码管显示数字编制成一个表格,见下表,以后直接调用就行了。
数码管的接口有静态接口和动态接口两种。
静态接口为固定显示方式,无闪烁,其电路可采用一个并行口接一个数码管,数码管的公共端按共阳接VCC,本次课程设计由于所需数码管较少,故可用些种方法接线。
这种接法占用接口多,仅能接少量数码管。
动态接口采用各数码管循环轮流显示的方法,当循环显示的频率较高时,利用人眼的暂留特性,看不出闪烁显示现象,这种显示需要一个接口完成字形码的输出。
3、软件设计
3.1程序分析
本设计采用AT89c52单片机中的一个16位的定时/计数器T0,分别由TH0和TL0组成,它们均是8位寄存器,在特殊功能寄存器中占地址8AH-8DH。
它们用于存放定时或计数的初始值。
此外,内部还有一个8位的方式寄存器TMOD和一个8位的控制寄存器TCON。
用于选择和控制定时/计数器的工作。
篮球比赛计分器利用单片机的计数器进行工作,计数器对外部脉冲的下降沿进行加1计数,直至计满回零。
作为可编程器件,单片机中的定时/计数器初始化编程步骤如下:
根据定时时间要求或计数要求计算计数器初值;
将工作方式控制字写入TMOD寄存器;
将计数初值写入THX和TLX寄存器;
启动定时器/计数器,即将TRX置位。
如果工作于中断方式,需置位EA(中断总开关)及ET(允许定时/计数器中断),并编写中断服务程序。
其设计中断子程序图如下:
图3-1
4PROTEUS软件仿真
4.1、简介
Proteus软件是英国Labcenterelectronics公司出版的EDA工具软件。
它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。
它是目前最好的仿真单片机及外围器件的工具。
Protues提供了丰富的资源:
仿真元器件资源:
仿真数字和模拟、交流和直流等数千种元器件,有30多个元件库。
仿真仪表资源:
示波器、逻辑分析仪、虚拟终端、SPI调试器、I2C调试器、信号发生器、模式发生器、交直流电压表、交直流电流表。
理论上同一种仪器可以在一个电路中随意的调用。
Proteus还提供了一个图形显示功能,可以将线路上变化的信号,以图形的方式实时地显示出来,其作用与示波器相似,但功能更多。
这些虚拟仪器仪表具有理想的参数指标。
另外Proteus还提供了比较丰富的测试信号用于电路的测试。
这些测试信号包括模拟信号和数字信号。
在Protues中进行电路仿真时,先绘制好原理图,再调入已编译好的目标代码文件:
*.HEX,随后便可在PROTEUS的原理图中模拟的实物运行状态和过程,进行观察从而改良自己的设计方案。
操作简单,非常适合初学者进行单片机的仿真,进而了解其原理,增强实践。
4.2、仿真过程
在计算机中打开PROTEUS软件,建立新的项目,在元件库中选择相应的元件,放在编辑窗口中,依次连线,组成仿真原理图。
在用Protues进行仿真之前,先要用WAVE软件将我们编写好的汇编程序编译。
具体方法是在WAVE中先新建一项目,之后输入编写的程序,输入完成后保存然后执行项目、编译,在目标文件夹内生成编译好的程序文件,其中*.HEX文件就是我们所需要的,在之后电路设计好后用于放入AT89S51中执行其功能。
检查连接好的电路,确保无误后,在电路连接好的PROTEUS窗口中双击AT89S51,在弹出的对话框中选择单片机中要输入的程序。
甲乙两队计分工作仿真状态图:
图4-1
5、调试分析
在仿真成功之后,便可进行实践了。
实物和仿真还是有一定的差别的,制作实物时要考虑的方面比仿真多的多。
做实物时,不仅要考虑到电路正确同时也要注意版面的设计,不仅设计功能要求实现,版面的美观也是必不可少的一方面,这就要注意尽量少的接线。
在电路板刚刚焊好后,与以前制作的单片机板连接在一起,接好电路,烤入程序后发现第一个数码管的C段一直处于亮的状态,经检查后确定不是硬件出现的问题,但在仿真时能正确显示也证明程序也是正确的,找不到问题所在让我非常郁闷。
想着原因可能程序读入时出现错误,试着重新将程序烤入单片机中,显示结果果然变得正常,实践成功。
6、课程设计心得体会
这次课程设计历时二个星期左右,通过这两个星期的学习,发现了自己的很多不足,自己知识的很多漏洞,看到了自己的实践经验还是比较缺乏,理论联系实际的能力还急需提高。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说不懂一些元器件的使用方法,对单片机汇编语言掌握得不好……通过这次课程设计之后,一定把以前所学过的知识重新温故。
这次课程设计终于顺利完成了,在设计中遇到了很多编程问题,最后在老师的辛勤指导下,终于游逆而解。
同时,在XXX、XXX、XXX老师那里我学得到很多实用的知识,在次我表示感谢!
同时,对给过我帮助的所有同学和各位指导老师再次表示忠心的感谢!
参考文献:
[1]余发山.单片机原理及应用技术.徐州:
中国矿业大学出版社,2003.
[2]佟云峰,等.单片机原理及其应用.重庆:
重庆大学出版社,2004,1.
[3]吴金戌,等.8051单片机实践与应用.北京:
清华大学出版社,2001,8.
[4]刘瑞新.单片机原理及应用教程.北京:
机械工业出版社,2005.
[5]聂毅.宏汇编语言程序设计教程.北京:
电子工业出版社,1998.
[6]周航慈.单片机应用程序设计技术.北京:
北京航空航天大学出版社,2002.
源程序代码
scoreDisplayBufferequ40h;设置计分显示缓冲区的地址为40h-45h
ascoreequ47h;设置甲队的计分地址
bscoreequ49h;设置乙队的计分地址
akeybitp1.0;设置甲加分键(按一次加一分)
bkeybitp1.1;设置乙加分键(按一次加一分)
abkeybitp1.6;设置分数位置交换键(交换比分位置)
DisplayBufferequ30h;设置计、定时显示缓冲区地址30h-35h
OneSecondCounterequ39h;设置1秒计数地址
Minuteequ3bh;设置分钟计数地址
Secondequ3ch;设置秒计数地址
ClockModeequ20h.0;设置模式(计时/定时)寄存器地址
AlarmOnOffequ20h.1;设置报警开启/关闭标志
AlarmTimeOnequ20h.2;设置计时时间到标志
DispMinuteequ22h;设置分钟显示寄存器的地址
DispSecondequ23h;设置秒显示寄存器的地址
AlarmMinuteequ2fh;设置定时分钟计数地址
AlarmSetKeybitp1.2;定义设置定时设置切换键
MinuteKeybitp1.5;定义分设置键
RelayOutequp1.3;定义报警发声输出引脚
;@@@@@@@@@@@@@@中断入口程序@@@@@@@@@
org00h
ajmpReset;程序开始
org0bh;T0中断地址
ajmpTimeInt;调到中断服务程序
;@@@@@@@@@@@@@@程序开始@@@@@@@@@@@
org0020h
Reset:
movsp,#70h;工作状态\地址初始化
setbRelayOut
movOneSecondCounter,#125
movMinute,#00
movSecond,#00
movAlarmMinute,#00
movascore,#00
movbscore,#00
clrAlarmOnOff
clrClockMode
clrAlarmTimeOn
setbRelayOut
movtmod,#00000001b
movth0,#0E0h
movtl0,#0C0h
movie,#82h;开全局中断
setbtr0;定时器T0开始工作
;@@@@@@@@@@@@@@@以下为主程序@@@@@@@@@@@@@@@@@
MainLoop:
jnbakey,bbb1;如甲加分键按下,执行bbb1后的语句,完成甲分数加一
jnbbkey,bbb2;如乙加分键按下,执行bbb2后的语句,完成乙分数加一
jnbabkey,bbb3;如显示交换键按下,执行bbb3后的语句,交换显示
ajmpxxx;如果没有分数设置键按下,跳到xxx语句
bbb1:
jnbakey,bbb1;等待按键释放
mova,ascore
adda,#1;完成甲分数加一
movascore,a
callConvertoBuffer;调用转换到显示缓冲区子程序
ajmpxxx;跳到xxx语句
bbb2:
jnbbkey,bbb2;与bbb1的功能类似,完成乙分数加一
mova,bscore
adda,#1
movbscore,a
callConvertoBuffer
ajmpxxx
bbb3:
jnbabkey,bbb3;完成显示交换
mova,ascore
mov48h,a
mova,bscore
movascore,a
mova,48h
movbscore,a
callConvertoBuffer;调用转换到显示缓冲区子程序
xxx:
jbAlarmSetKey,CheckMinuteKey;定时设置键按下了吗?
没有则检测分钟设置键
callDelay
jbAlarmSetKey,CheckMinuteKey;延时去抖动
setbClockMode
callAlarmSet
CheckMinuteKey:
jbMinuteKey,CheckAlarm;分设置键按下了吗?
没有则转去检测小时设置键
mova,Minute
adda,#1
movMinute,a
cjnea,#3ch,NotOver1;到60分钟了吗?
movMinute,#0;到60分钟则将分钟清0
NotOver1:
jnbMinuteKey,$
CheckAlarm:
jnbAlarmTimeOn,ToReturn
callAlarmProcess
ToReturn:
ajmpMainLoop;跳回主程序
;@@@@@@@@@@@@@定时器Timer0中断服务程序@@@@@@@@@@@
TimeInt:
movth0,#0E0h;重新加载定时参数
movtl0,#0C0h
pushacc
pushpsw
setbrs0
clrrs1
djnzOneSecondCounter,NotoneSecond;即够1秒了吗?
movOneSecondCounter,#125;如够1秒则重新设置"OneSecondCounter"计数器
callClock;调用将时钟内容加1秒的子程序
callConvertoBuffer;调用转换到显示缓冲区子程序
NotoneSecond:
callScanDisplay;调用扫描显示子程序
poppsw
popacc
reti;中断返回
;@@@@@@@@@@@@扫描显示子程序@@@@@@@@@@@@@@@@@@
ScanDisplay:
MOVR1,#DisplayBuffer;指向计(定)时显示数据首址
MOVR0,#scoreDisplayBuffer;指向分数显示数据首址
MOVR4,#11111110b;扫描控制字初值
PLAY:
MOVA,R4;扫描字放入A
MOVp3,A;从p3口输出
MOVA,@R1;取计时显示数据到A
MOVDPTR,#TAB;取段码表地址
MOVCA,@A+DPTR;查显示数据对应段码
MOVP0,A;段码放入P0口
MOVA,@R0;取计分显示数据到A
MOVDPTR,#TAB;取段码表地址
MOVCA,@A+DPTR;查显示数据对应段码
MOVP2,A;段码放入P2口
LCALLDelay
INCR1;指向下一地址
INCR0
MOVA,R4;扫描控制字放入A
JNBACC.4,ENDOUT;扫到第六位时结束
RLA;A中数据循环左移
MOVR4,A;放回R4内
AJMPPLAY
ENDOUT:
SETBp3.7
MOVP0,#0FFH
MOVP2,#0FFH
RET;子程序返回
TAB:
DB3FH,06H,5BH,4FH,66H
DB6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H,40H,80H,00H
;@@@@@@@@@@@@@计时加1秒的子程序@@@@@@@@@@@@@@
Clock:
mova,Second;将原秒值送入a
suba,#1;加1秒
movSecond,a
cjnea,#00H,NotOverFlow;够60秒了吗?
movSecond,#59;够了则将秒值清0
mova,Minute
suba,#1
movMinute,a;分钟加1
cjnea,#00H,NotOverFlow;够60分了吗?
movMinute,#59;够了则将分值清0
NotOverFlow:
jnbAlarmOnOff,NotAlarm
mova,Second
jnzNotAlarm;秒为零吗?
mova,Minute
cjnea,AlarmMinute,NotAlarm;计时分钟值和定时设置分钟值相等吗?
setbAlarmTimeOn;到了闹时时间则将“闹时时间到”标志设为1
NotAlarm:
ret
;@@@@@@@计时定时值与计分转换到显示缓冲区子程序@@@@@@@@@@
ConvertoBuffer:
movr1,#DisplayBuffer;将计(定)时缓冲区地址赋给r1
movR0,#scoreDisplayBuffer;将计分缓冲区地址赋给r0
jnbakey,Convert1
jnbbkey,Convert1
jbabkey,zzz1
ajmpConvert1
zzz1:
jbClockMode,DispAlarmSet;判断计时模式,以决定是显示计时时间还是定时时间
mova,Second;将计时数据转到显示寄存器
movDispSecond,a
mova,Minute
movDispminute,a
ajmpConvert
DispAlarmSet:
jbAlarmOnOff,AlarmOn;将定时数据转到显示寄存器
movDispSecond,#00h;秒位显示00说明无效(上次用过的定时)
ajmpNext
AlarmOn:
movDispSecond,#11;显示11说明有效(本次定时)
Next:
mova,AlarmMinute
movDispminute,a
Convert:
mova,DispSecond;将计(定)时显示寄存器中的内容赋值给a
movb,#10;令b=10
divab;a/b商(十位)放a中,余数(个位)放b中
mov@r1,b;将b中的个位赋值给((r1))
incr1;r1自加1
mov@r1,a;将a中的十位赋值给((r1))
incr1;r1自加1
mova,DispMinute;同上
movb,#10
divab
mov@r1,b
incr1
mov@r1,a
Convert1:
mova,bscore;将计分显示寄存器中的内容赋值给a
movb,#10;与计时相应部分的类似
divab
mov@R0,b
incR0
mov@R0,a
incR0
mov@R0,a
incR0
mova,ascore
movb,#10
divab
mov@R0,b
incR0
mov@R0,a
ret
;@@@@@@@@@定时设置子程序@@@@@@@@@@
AlarmSet:
jnbAlarmSetKey,$
callDelay
CheckArmMinuteKey:
jbMinuteKey,AlarmSetEnd;分设置键按下了吗?
没有则转去检测小时设置键
setbAlarmOnOff
mova,AlarmMinute
adda,#1
movAlarmMinute,a
cjnea,#3ch,A