基于51单片机的篮球计分器

工程设计课程报告

基于51单片机的篮球计分器

姓名: 莫崇维 学号: 01104022

2012 年 12月 22 日

基于51单片机的篮球计分器

一.需求分析

篮球是一项充满乐趣的运动,打篮球可以学到很多课本里没有的东西,比如信任,合作,鼓励等,现在篮球普及率已经很高,不仅仅是专业运动员的运动,也是普通老百姓的活动,不管是走在学校里,还是公园里,甚至是乡村里,都能看到篮球场,都能看到打篮球的人,篮球已成为我们大部分人生活里不可或缺的组成部分,每天都能听到有人在谈论篮球,说说自己喜欢的NBA巨星……因为喜欢篮球,所以打篮球,时不时会来场激烈的比赛,篮球计分器将让我们摆脱用粉笔或记分牌计分带来的不便,轻轻松松几个按钮开关就能让我们记下分数,让我们感受到科技给我们带来的巨变。

计分器主要功能:

1、记下双方比分,随时显示

2、能够随时更改双方比分

3、能够调整比赛的时间,还有暂停时间

4、能够对换比分当双方更换场地

5、时间走完能发出终场比赛信号

二.方案设计

根据所学的C语言基础知识和一些编程思想,对所需的一些硬件进行市场调查比较,选择了比较简单,易于实现的51单片机,结合运用了C语言思想进行方案设计,运用keil uversion软件编写程序。

51单片机内部的定时器/计数器进行中断可以结合软件延时实现计时。

采用89C51芯片作为硬件核心,其内部采用FlashROM,具有4KB ROM存储空间,能与3V的超低压工作,由于电路设计中时由于不具备ISP在线编程技术,可以运用STC-isp烧入程序。

图1给出了本系统的实现框图。

图1 总体框图

三.电路原理设计

电路主要包括CPU部分、电源部分、复位电路部分、按键部分、LED显示部分。

1、CPU部分

51单片机为单芯片微控制器,常见封装形式为40脚双列直插式塑料封装DIP-40,其引脚识别为:正面面向用户,缺口向上,左上面第一脚为1脚,然后按逆时针方向依次为2~40脚。通常第一脚有标志符号。51单片机管脚图如图2所示。

AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。AT89C单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。

图2 单片机引脚图

管脚说明:

VCC:供电电压。

GND:接地。

P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。

P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。

P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。

P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。

P3口也可作为AT89C51的一些特殊功能口,如下表所示:

口管脚 备选功能

P3.0 RXD(串行输入口)

P3.1 TXD(串行输出口)

P3.2 /INT0(外部中断0)

P3.3 /INT1(外部中断1)

P3.4 T0(记时器0外部输入)

P3.5 T1(记时器1外部输入)

P3.6 /WR(外部数据存储器写选通)

P3.7 /RD(外部数据存储器读选通)

P3口同时为闪烁编程和编程校验接收一些控制信号。

RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。

ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。

/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。

/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。

XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。

XTAL2:来自反向振荡器的输出。

振荡器特性:

XTAL1和XTAL2分别为反向放大器的输入和输出。该反向放大器可以配置为片内振荡器。石晶振荡和陶瓷振荡均可采用。如采用外部时钟源驱动器件,XTAL2应不接。有余输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉宽无任何要求,但必须保证脉冲的高低电平要求的宽度。

单片机是一种微控制器,任何为控制器正常工作最基本的条件是要有正确的电源、时钟电路好复位信号,三者缺一不可。

单片机正常工作最基本条件是:正确的电源、时钟信号、复位信号。51系列单片机第40引脚接电源+5V,第20引脚接地。电压过高或者过低均会引起单片机CPU部工作。单片机指令执行时在时钟脉冲控制下进行的,时钟脉冲信号是由单片机内部时钟电路及18脚、19脚外接晶振和电容组成的时钟电路产生的。时钟电路异常,也会引起单片机CPU部工作,可通过测量30脚(ALE) 是否有时钟脉冲六分频信号输出来判断振荡电路是否起振。复位电路时在CPU通电后,给复位端9脚(RST)一个复位脉冲,使CPU内部处于初始工作状态。51系列单片机是高电平复位,在正确的复位后(工作状态)9脚应保持低电平。如果复位电路

P3口也可作为AT89C51的一些特殊功能口,如下表所示: 口管脚 备选功能

P3.0 RXD(串行输入口) P3.1 TXD(串行输出口) P3.2 /INT0(外部中断0) P3.3 /INT1(外部中断1) P3.4 T0(记时器0外部输入) P3.5 T1(记时器1外部输入)

P3.6 /WR(外部数据存储器写选通) P3.7 /RD(外部数据存储器读选通)

P3口同时为闪烁编程和编程校验接收一些控制信号。

RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。

ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。

/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。

/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。

XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。 XTAL2:来自反向振荡器的输出。 振荡器特性:

XTAL1和XTAL2分别为反向放大器的输入和输出。该反向放大器可以配置为片内振荡器。石晶振荡和陶瓷振荡均可采用。如采用外部时钟源驱动器件,XTAL2应不接。有余输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉宽无任何要求,但必须保证脉冲的高低电平要求的宽度。

单片机是一种微控制器,任何为控制器正常工作最基本的条件是要有正确的电源、时钟电路好复位信号,三者缺一不可。

单片机正常工作最基本条件是:正确的电源、时钟信号、复位信号。51系列单片机第40引脚接电源+5V,第20引脚接地。电压过高或者过低均会引起单片机CPU部工作。单片机指令执行时在时钟脉冲控制下进行的,时钟脉冲信号是由单片机内部时钟电路及18脚、19脚外接晶振和电容组成的时钟电路产生的。时钟电路异常,也会引起单片机CPU部工作,可通过测量30脚(ALE) 是否有时钟脉冲六分频信号输出来判断振荡电路是否起振。复位电路时在CPU通电后,给复位端9脚(RST)一个复位脉冲,使CPU内部处于初始工作状态。51系列单片机是高电平复位,在正确的复位后(工作状态)9脚应保持低电平。如果复位电路

出现故障,CPU也将无法工作。由于CPU的复位电路只有在开机瞬间产生复位脉冲,周期一般为几毫秒,用万用表无法鉴别正常与否。对于只有上电复位的复位电路,快速判断CPU是否有故障可以采取强制复位的方法,将复位瞬时接电源正端,如果此时CPU恢复工作,说明CPU的复位电路出现故障。对于有按键复位的复位电路,按下复位键,测量复位端是否有高电平产生来判断复位电路工作是否正常。

图3 CPU控制电路

2、电源部分

图4 电源部分

如图4所示,为单片机,复位电路提供电源。

3、复位电路部分

如图5所示,单片机中RST端口通过一个10uF的电解电容接VCC,又通过一个10K的电阻接地 。接VCC的电容为复位电容,接地的电阻为下拉电阻。工作过程:单片机刚上电时需复位一次才能可靠工作,通过电容接VCC,是利用电容充电来提供>>2个机器周期的高电平时间让单片机复位,如此单片机可以正常工作了,这之后又不要求单片机复位,所以可以通过10K的电阻下拉接地,保证RST脚维持在低电平状态(即不复位状态)。

图5 复位电路 4、按键部分

如图6所示,键盘对应名称如下:

ADD1,DEC1,EXCHANGE,ADD2,DEC2,RUN/STOP 其中,

ADD1 甲队比分加1键,(暂停时为调整时间分钟加1) DEC1 甲队比分减1键,(暂停时为调整时间分钟减1) EXCHANGE 换场键,半场休息时换场。 ADD2 乙队比分加1键,(暂停时为调整时间秒钟加1) DEC2 乙队比分减1键,(暂停时为调整时间秒钟减1)

RUN/STOP 启动暂停键,比赛开始时按下启动计时,比赛开始。比赛开始后,按下为暂停计时,比赛暂停。

图6 按键部分 5、LED显示部分

如图7,图8和图9所示,分别代表甲乙两队记分牌和剩余时间牌。其中图5为

剩余时间牌,初始剩余时间默认为12:00;图8和图9为甲乙两队的比分值,用三位数表示,范围从000到999。

图7 D2(4LED)

图8 D3 (3LED) 图9 D4 (3LED)

系统的总电路图

图10给出了系统总电路图

四、硬件设计与调试

1、电路板的的焊接

要区分开电源地和信号地,电源地主要是针对电源回路而言的,而信号地主要是指两块芯片或者模块之间的通信信号的回流所流过的路径,电源地可以理解为通过发电厂与大地相连接而信号地仅仅是电路板上所有接地信号的公共端。两者之间应该接在一起。但是由于电源地存在很多的高频污染,所以经常通过电感,电容,磁珠或者0欧姆电阻将二者相连。磁珠的等效电路相当于带阻限波器,只对某个频点的噪声有显著抑制作用,使用时需要预先估计噪点频率,以便选用适当型号。主流的直流电变换芯片主要分为相控电源,线性电源,开关电源三类。焊接cup时,首先要检查cpu的各个管脚,保证没有弯曲或者错位,然后将CUP各个管脚跟pcb板上的焊盘仔细的对齐,然后用电烙铁轻轻烫一下管脚,由于CPU管脚和焊盘上均有少量的残锡,可以将CPU固定住,然后用电烙铁依次将管脚压平。接下来最关键的步骤:补锡。先在cup管脚的一端点少量焊锡,然后将一排管脚涂满松香,快速而缓慢的划过管脚。焊接电路要有分块化的思想,首先焊接电源模块,然后测试各个供电电压;然后焊接CPu模块、Rs232和TTL电平转换模块,通电后通过串口isp测试cup是否启动能否烧写程序。然后是无线通讯某块和IO串口某块,最后成功后焊接引出的管脚。晶振(Crystal)即为石英振荡器,是一种机电器件,是用电损耗很小的石英晶体经精密切割磨削并镀上电极焊上引线做成。这种晶体有一个很重要的特性,如果给他通电,他就会产生机械振荡,反之,如果给他机械力,他又会产生电,这种特性叫机电效应。他们有一个很重要的特点,其振荡频率与他们的形状,材料,切割方向等密切相关。由于石英晶体化学性能非常稳定,热膨胀系数非常小,其振荡频率也非常稳定,由于控制几何尺寸可以做到很精密,因此,其谐振频率也很准确。根据石英晶体的机电效应,我们可以把它等效为一个电磁振荡回路,即谐振回路。他们的机电效应是机-电-机-电....的不断转换,由电感和电容组成的谐振回路是电场-磁场的不断转换。在电路中的应用实际上是把它当作一个高Q值的电磁谐振回路。由于石英晶体的损耗非常小,即Q 值非常高,做振荡器用时,可以产生非常稳定的振荡,作滤波器用,可以获得非常稳定和陡削的带通或带阻曲线。

2、程序的调试

程序的调试是编写一个程序的重要步骤,根据思想框图写好代码,不是写完就可以运用,由于一些因素可能会造成程序无法编译,这等于代码不能使用,有时候会因为一个小小的标点符号,会使你半天找不到错误,因为目标太小,但却是致命的,debug过程比写程序还要麻烦,有时候你模仿别人的程序写出所需程序,写好了就是无法编译,这是跟编程者的思想息息相关,编写程序最好模块分明,注释明了,使人一目了然,让懂的人一看便知你的思想,这是最重要的,所以要条理清晰,这是我调试程序的一些心得体会。

五、测试方法和测试结果

在proteus下的仿真。

仿真如图11-图17所示

图11 80C51单片机部分

图12 排阻部分

图13 蜂鸣器部分

图14 按键部分

图15 时间显示部分

图16 比分显示部分

图17 仿真全图

调整比赛时间:插上电源后,系列默认比赛时间为12:00,甲乙队比分默认000,此时按下ADD1键,可以对比赛时间分钟加1,按下DEC1键,可以对比赛时间的分钟减1,按下ADD2键,可以对比赛时间秒加1,按下DEC2键,可以对比赛时间秒减1。

开始比赛:按下RUN/STOP键,计时开始,比赛时间以1秒的频率倒计时。

暂停比赛:比赛运行的状态下,按RUN/STOP键,比赛暂停,计时暂停。

比分修改:在比赛进行的状态下按ADD1,DEC1键,可以对甲队比分加、减1,

按ADD2、DEC2键,可以对乙队比分加、减1.

交换场地:在半场休息时,按下EXCHANGE键,比赛时间重新预置为12:00,同时左右两边数码管的比分交换显示。此时按下启动键可以开始新一节的比赛。

报警提示:在一节比赛时间倒计时到00:00时,蜂鸣器发出报警提示。

六、结论

通过这次工程设计实验,我们能很好地结合所学的一些理论知识,让我们更好地理解,通过实践使我们更进一步了解所学理论,巩固和加深印象,让我们从抽象的理论知识到生动的实体感受,更有利于学习和掌握新的知识。

附、源程序代码

#include #define LEDData P0

//定时数码管的段值从P0口输出

//数码管

unsigned char code

LEDCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 0--9的编码

unsigned char minit,second,count,count1; //分,秒,计数器

unsigned char set_minit=12,set_second=0;

sbit add1=P1^0; //甲队加分,每按一次加1分 /比赛前为时间加1分

sbit dec1=P1^1; //甲队减分,每按一次减1分/比赛前为时间减1分 sbit exchange=P1^2;

//交换场地

sbit add2=P1^3; //乙队加分,每按一次加1分/比赛前为时间加1秒 sbit dec2=P1^4; //乙队减分,每按一次减1分/比赛前为时间减1秒 sbit secondpoint=P0^7;

//----数码管的位选控制脚,共有10位数码管------ sbit led1=P2^7; sbit led2=P2^6; sbit led3=P2^5; sbit led4=P2^4;

//秒闪动点

sbit led5=P2^3; sbit led6=P2^2; sbit led7=P2^1; sbit led8=P2^0; sbit led9=P3^7; sbit led10=P3^6;

sbit alam=P1^7;

bit playon=0; bit timeover=0; bit AorB=0;

//比赛进行标志位,为1时表示比赛开始,计时开启 //比赛结束标志位,为1时表示比赛结束 //甲乙队交换位置标志位 //半秒标志位

//甲队得分 //乙队得分

//报警

bit halfsecond=0; unsigned int scoreA;

unsigned int scoreB;

//====================延时================== void Delay5ms(void) { }

void display(void)

{

//-----------显示时间(分钟)--------------

unsigned int i; for(i=100;i>0;i--);

LEDData=LEDCode[minit/10]; //显示分钟的十位 led1=0;

//开启位选

//延时,以便足以点亮数码管。 //关闭位选

Delay5ms(); led1=1;

LEDData=LEDCode[minit%10]; //显示分钟的个位

led2=0; Delay5ms(); led2=1;

//-------------秒点闪动------------ if(halfsecond==1)

LEDData=0x80;

else

LEDData=0x00;

led2=0; Delay5ms(); led2=1; secondpoint=0;

//-----------显示时间(秒钟)------------ LEDData=LEDCode[second/10]; led3=0; Delay5ms(); led3=1;

LEDData=LEDCode[second%10]; led4=0; Delay5ms(); led4=1;

//-----------显示1组的分数百位------- if(AorB==0)

LEDData=LEDCode[scoreA/100];

else

LEDData=LEDCode[scoreB/100];

//显示秒钟的十位

//显示秒钟的个位

Delay5ms(); led5=1;

//---------------显示1组分数的十位-----------

//---------------显示1组分数的个位-----------

//-----------显示2组分数的百位-------

if(AorB==0)

LEDData=LEDCode[(scoreA%100)/10];

else

LEDData=LEDCode[(scoreB%100)/10];

led6=0; Delay5ms(); led6=1;

if(AorB==0)

LEDData=LEDCode[scoreA%10];

else

LEDData=LEDCode[scoreB%10];

led7=0; Delay5ms(); led7=1;

if(AorB==1)

LEDData=LEDCode[scoreA/100];

else

LEDData=LEDCode[scoreB/100];

led8=0; Delay5ms(); led8=1;

//-----------显示2组分数的十位-----------

//-----------显示2组分数的个位-----------

}

//=========================按键检测程序

================================================

void keyscan(void) {

if(AorB==1)

LEDData=LEDCode[(scoreA%100)/10];

else

LEDData=LEDCode[(scoreB%100)/10];

led9=0; Delay5ms(); led9=1;

if(AorB==1)

LEDData=LEDCode[scoreA%10];

else

LEDData=LEDCode[scoreB%10];

led10=0; Delay5ms(); led10=1;

if(playon==0) {

//在比赛未开始的状态下

if(add1==0) {

display();

//当add1按键按下时

//调用显示,同时作为延时消抖

if(add1==0); //延时消抖后,依然检查到按键按下

{ } do

//当按键未松开时,一直调用显示,防止数

if(minit

minit++;

else

minit=99;

//否则,分钟仍然为99,调整为99分钟

码管闪动,

}

display();

while(add1==0);

if(dec1==0)

{ }

//当dec1键按下时,dec1的原理与add一样,

display(); if(dec1==0); { } do

display(); if(minit>0)

minit--;

else

minit=0;

while(dec1==0);

if(add2==0) {

display();

//调整秒,原理同上

if(add2==0); {

if(second

second++;

else

second=59;

} do

display();

while(add2==0);

}

if(dec2==0) { display(); if(dec2==0); { if(second>0)

second--;

else

second=0;

} do

display(); while(dec2==0);

}

if(exchange==0)

{ display(); if(exchange==0); { TR1=0;

alam=1;

//换场键

//关闭T1计数器//关报警

}

} do

AorB=~AorB;

//开启交换

}

minit=set_minit; second=0;

//并将时间预设为12:00

display();

while(exchange==0);

else {

//比赛开始。

if(add1==0) {

display();

//add1键按下

//调用显示,同时延时消抖

if(add1==0); {

if(AorB==0) { } else { }

if(scoreB

scoreB++;

//当场地标志位=1时,

if(scoreA

scoreA++;

//当场地标志位=0时,

else

scoreA=999;

//否则最大值为999分

else

scoreB=999;

//否则最在值为999分

}

do

display();

while(add1==0);

if(dec1==0) { }

display();

//当dec1键按下时,原理与add1一样,比分减1

if(dec1==0); { } do

display(); if(AorB==0) { } else { }

if(scoreB>0)

scoreB--; if(scoreA>0)

scoreA--;

else

scoreA=0;

else

scoreB=0;

while(dec1==0);

if(add2==0)

//原理同上

{

}

display(); if(add2==0); { } do

display(); if(AorB==1) { } else { }

if(scoreB

scoreB++; if(scoreA

scoreA++;

else

scoreA=999;

else

scoreB=999;

while(add2==0);

if(dec2==0) {

display(); if(dec2==0);

}

} } { } do display(); if(AorB==1) { } else { } if(scoreB>0) scoreB--; if(scoreA>0) scoreA--; else scoreA=0; else scoreB=0; while(dec2==0);

//******************************主函数

void main(void)

{

TMOD=0x11;

//TMOD设置 TL0=0xb0;

TH0=0x3c;

TL1=0xb0;

//定时器0,初值为0x3CB0,既定时0.05s //定时器1,初值为0x3CB0,即定时0.05s

TH1=0x3c;

minit=set_minit; second=0;

//开总中断 //开T0中断 //开T1中断 //初始值为12:00 EA=1; ET0=1; ET1=1; TR0=0;

TR1=0; EX0=1; IT0=1; IT1=1; //开外部中断0

// EX1=1;

PX0=1;

// PX1=1;

PT0=0; P1=0xFF; P3=0xFF;

while(1)

{

keyscan(); display(); //按键检查 //显示程序

}

}

//============外部中断0中断程序=================

void PxInt0(void) interrupt 0

{

Delay5ms(); EX0=0; alam=1; //关中断使能 //关蜂鸣器

TR1=0; //关定时器0 //当一节比较时间结束时,结束标志位=1 if(timeover==1) { } timeover=0; //清除标志位 if(playon==0)

} { } else { } //当比赛结束或暂停时 playon=1; TR0=1; //开始标志位 //开启计时 playon=0; TR0=0; //开始标志位清零,表示暂停 //暂停计时 EX0=1; //重新开中断

//===================定时器0中断服务函数======================

void time0_int(void) interrupt 1

{

TL0=0xb0;

TH0=0x3c;

TR0=1;

count++;

//启动计时 //软件计数器加1 //0.05s*10=0.5s,即0.5秒钟时 //重赋初值 if(count==10) { } halfsecond=0; //半秒标志位清零

if(count==20) //0.05s*20=1s,即1秒钟

{ count=0;

//清除计数器 //半秒标志置1 //倒计时,每计时1秒钟,时间减1,当秒halfsecond=1; if(second==0)

=0时,秒=59,分钟减1

{ } else

} second--; if(minit>0) { } else { } second=59; minit--; //当分,秒都为0时,表示倒计时时间到, timeover=1; playon=0; TR0=0; TR1=1; //时间标志位置1 //比赛标志清0,表示1节比赛结束 //关闭定时器0 //开启定时1,使蜂鸣器报警

}

//==============定时器1中断服务函数==========================

void time1_int(void) interrupt 3

{

TL1=0xb0; //重赋初值

TH1=0x3c;

TR1=1;

//启动计时

count1++;

} } //软件计数器加1 //0.05s*10=0.5s,也就是半秒钟 if(count1==10) { } alam=0; //开启蜂鸣器 if(count1==20) { count1=0; alam=1; //0.05s*20=1s,也就是1秒钟 //清除软件计数器, //关闭蜂鸣器,也就是蜂鸣器以1秒的频率响

参考文献及网站

[1]冯育长等. 单片机系统设计及实例分析. 西安:西安电子科技大学出版社, 2007.5

[2]雷思孝,冯育长.单片机系统设计及工程应用.西安:西安电子科技大学出版社,2005.5

[3]百度 http://www.baidu.com

[4]杨欣,王玉凤,刘湘黔.电子设计从零开始.北京:清华大学出版社,2005.10

[5]易运晖. Protel 99入(PCB) 0403Protel99SE-PCB.pdf

http://eelab.xidian.edu.cn/ 2012.10

[6]易运晖.Protel 99 入门(SCH) 0403Protel99SE-SCH.pdf

http://eelab.xidian.edu.cn/ 2012.10

[7]易运晖.Electronics Work Bench入门 EWB.pdf

http://eelab.xidian.edu.cn/ 2012.10

工程设计课程报告

基于51单片机的篮球计分器

姓名: 莫崇维 学号: 01104022

2012 年 12月 22 日

基于51单片机的篮球计分器

一.需求分析

篮球是一项充满乐趣的运动,打篮球可以学到很多课本里没有的东西,比如信任,合作,鼓励等,现在篮球普及率已经很高,不仅仅是专业运动员的运动,也是普通老百姓的活动,不管是走在学校里,还是公园里,甚至是乡村里,都能看到篮球场,都能看到打篮球的人,篮球已成为我们大部分人生活里不可或缺的组成部分,每天都能听到有人在谈论篮球,说说自己喜欢的NBA巨星……因为喜欢篮球,所以打篮球,时不时会来场激烈的比赛,篮球计分器将让我们摆脱用粉笔或记分牌计分带来的不便,轻轻松松几个按钮开关就能让我们记下分数,让我们感受到科技给我们带来的巨变。

计分器主要功能:

1、记下双方比分,随时显示

2、能够随时更改双方比分

3、能够调整比赛的时间,还有暂停时间

4、能够对换比分当双方更换场地

5、时间走完能发出终场比赛信号

二.方案设计

根据所学的C语言基础知识和一些编程思想,对所需的一些硬件进行市场调查比较,选择了比较简单,易于实现的51单片机,结合运用了C语言思想进行方案设计,运用keil uversion软件编写程序。

51单片机内部的定时器/计数器进行中断可以结合软件延时实现计时。

采用89C51芯片作为硬件核心,其内部采用FlashROM,具有4KB ROM存储空间,能与3V的超低压工作,由于电路设计中时由于不具备ISP在线编程技术,可以运用STC-isp烧入程序。

图1给出了本系统的实现框图。

图1 总体框图

三.电路原理设计

电路主要包括CPU部分、电源部分、复位电路部分、按键部分、LED显示部分。

1、CPU部分

51单片机为单芯片微控制器,常见封装形式为40脚双列直插式塑料封装DIP-40,其引脚识别为:正面面向用户,缺口向上,左上面第一脚为1脚,然后按逆时针方向依次为2~40脚。通常第一脚有标志符号。51单片机管脚图如图2所示。

AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。AT89C单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。

图2 单片机引脚图

管脚说明:

VCC:供电电压。

GND:接地。

P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。

P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。

P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。

P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。

P3口也可作为AT89C51的一些特殊功能口,如下表所示:

口管脚 备选功能

P3.0 RXD(串行输入口)

P3.1 TXD(串行输出口)

P3.2 /INT0(外部中断0)

P3.3 /INT1(外部中断1)

P3.4 T0(记时器0外部输入)

P3.5 T1(记时器1外部输入)

P3.6 /WR(外部数据存储器写选通)

P3.7 /RD(外部数据存储器读选通)

P3口同时为闪烁编程和编程校验接收一些控制信号。

RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。

ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。

/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。

/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。

XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。

XTAL2:来自反向振荡器的输出。

振荡器特性:

XTAL1和XTAL2分别为反向放大器的输入和输出。该反向放大器可以配置为片内振荡器。石晶振荡和陶瓷振荡均可采用。如采用外部时钟源驱动器件,XTAL2应不接。有余输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉宽无任何要求,但必须保证脉冲的高低电平要求的宽度。

单片机是一种微控制器,任何为控制器正常工作最基本的条件是要有正确的电源、时钟电路好复位信号,三者缺一不可。

单片机正常工作最基本条件是:正确的电源、时钟信号、复位信号。51系列单片机第40引脚接电源+5V,第20引脚接地。电压过高或者过低均会引起单片机CPU部工作。单片机指令执行时在时钟脉冲控制下进行的,时钟脉冲信号是由单片机内部时钟电路及18脚、19脚外接晶振和电容组成的时钟电路产生的。时钟电路异常,也会引起单片机CPU部工作,可通过测量30脚(ALE) 是否有时钟脉冲六分频信号输出来判断振荡电路是否起振。复位电路时在CPU通电后,给复位端9脚(RST)一个复位脉冲,使CPU内部处于初始工作状态。51系列单片机是高电平复位,在正确的复位后(工作状态)9脚应保持低电平。如果复位电路

P3口也可作为AT89C51的一些特殊功能口,如下表所示: 口管脚 备选功能

P3.0 RXD(串行输入口) P3.1 TXD(串行输出口) P3.2 /INT0(外部中断0) P3.3 /INT1(外部中断1) P3.4 T0(记时器0外部输入) P3.5 T1(记时器1外部输入)

P3.6 /WR(外部数据存储器写选通) P3.7 /RD(外部数据存储器读选通)

P3口同时为闪烁编程和编程校验接收一些控制信号。

RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。

ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。

/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。

/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。

XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。 XTAL2:来自反向振荡器的输出。 振荡器特性:

XTAL1和XTAL2分别为反向放大器的输入和输出。该反向放大器可以配置为片内振荡器。石晶振荡和陶瓷振荡均可采用。如采用外部时钟源驱动器件,XTAL2应不接。有余输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉宽无任何要求,但必须保证脉冲的高低电平要求的宽度。

单片机是一种微控制器,任何为控制器正常工作最基本的条件是要有正确的电源、时钟电路好复位信号,三者缺一不可。

单片机正常工作最基本条件是:正确的电源、时钟信号、复位信号。51系列单片机第40引脚接电源+5V,第20引脚接地。电压过高或者过低均会引起单片机CPU部工作。单片机指令执行时在时钟脉冲控制下进行的,时钟脉冲信号是由单片机内部时钟电路及18脚、19脚外接晶振和电容组成的时钟电路产生的。时钟电路异常,也会引起单片机CPU部工作,可通过测量30脚(ALE) 是否有时钟脉冲六分频信号输出来判断振荡电路是否起振。复位电路时在CPU通电后,给复位端9脚(RST)一个复位脉冲,使CPU内部处于初始工作状态。51系列单片机是高电平复位,在正确的复位后(工作状态)9脚应保持低电平。如果复位电路

出现故障,CPU也将无法工作。由于CPU的复位电路只有在开机瞬间产生复位脉冲,周期一般为几毫秒,用万用表无法鉴别正常与否。对于只有上电复位的复位电路,快速判断CPU是否有故障可以采取强制复位的方法,将复位瞬时接电源正端,如果此时CPU恢复工作,说明CPU的复位电路出现故障。对于有按键复位的复位电路,按下复位键,测量复位端是否有高电平产生来判断复位电路工作是否正常。

图3 CPU控制电路

2、电源部分

图4 电源部分

如图4所示,为单片机,复位电路提供电源。

3、复位电路部分

如图5所示,单片机中RST端口通过一个10uF的电解电容接VCC,又通过一个10K的电阻接地 。接VCC的电容为复位电容,接地的电阻为下拉电阻。工作过程:单片机刚上电时需复位一次才能可靠工作,通过电容接VCC,是利用电容充电来提供>>2个机器周期的高电平时间让单片机复位,如此单片机可以正常工作了,这之后又不要求单片机复位,所以可以通过10K的电阻下拉接地,保证RST脚维持在低电平状态(即不复位状态)。

图5 复位电路 4、按键部分

如图6所示,键盘对应名称如下:

ADD1,DEC1,EXCHANGE,ADD2,DEC2,RUN/STOP 其中,

ADD1 甲队比分加1键,(暂停时为调整时间分钟加1) DEC1 甲队比分减1键,(暂停时为调整时间分钟减1) EXCHANGE 换场键,半场休息时换场。 ADD2 乙队比分加1键,(暂停时为调整时间秒钟加1) DEC2 乙队比分减1键,(暂停时为调整时间秒钟减1)

RUN/STOP 启动暂停键,比赛开始时按下启动计时,比赛开始。比赛开始后,按下为暂停计时,比赛暂停。

图6 按键部分 5、LED显示部分

如图7,图8和图9所示,分别代表甲乙两队记分牌和剩余时间牌。其中图5为

剩余时间牌,初始剩余时间默认为12:00;图8和图9为甲乙两队的比分值,用三位数表示,范围从000到999。

图7 D2(4LED)

图8 D3 (3LED) 图9 D4 (3LED)

系统的总电路图

图10给出了系统总电路图

四、硬件设计与调试

1、电路板的的焊接

要区分开电源地和信号地,电源地主要是针对电源回路而言的,而信号地主要是指两块芯片或者模块之间的通信信号的回流所流过的路径,电源地可以理解为通过发电厂与大地相连接而信号地仅仅是电路板上所有接地信号的公共端。两者之间应该接在一起。但是由于电源地存在很多的高频污染,所以经常通过电感,电容,磁珠或者0欧姆电阻将二者相连。磁珠的等效电路相当于带阻限波器,只对某个频点的噪声有显著抑制作用,使用时需要预先估计噪点频率,以便选用适当型号。主流的直流电变换芯片主要分为相控电源,线性电源,开关电源三类。焊接cup时,首先要检查cpu的各个管脚,保证没有弯曲或者错位,然后将CUP各个管脚跟pcb板上的焊盘仔细的对齐,然后用电烙铁轻轻烫一下管脚,由于CPU管脚和焊盘上均有少量的残锡,可以将CPU固定住,然后用电烙铁依次将管脚压平。接下来最关键的步骤:补锡。先在cup管脚的一端点少量焊锡,然后将一排管脚涂满松香,快速而缓慢的划过管脚。焊接电路要有分块化的思想,首先焊接电源模块,然后测试各个供电电压;然后焊接CPu模块、Rs232和TTL电平转换模块,通电后通过串口isp测试cup是否启动能否烧写程序。然后是无线通讯某块和IO串口某块,最后成功后焊接引出的管脚。晶振(Crystal)即为石英振荡器,是一种机电器件,是用电损耗很小的石英晶体经精密切割磨削并镀上电极焊上引线做成。这种晶体有一个很重要的特性,如果给他通电,他就会产生机械振荡,反之,如果给他机械力,他又会产生电,这种特性叫机电效应。他们有一个很重要的特点,其振荡频率与他们的形状,材料,切割方向等密切相关。由于石英晶体化学性能非常稳定,热膨胀系数非常小,其振荡频率也非常稳定,由于控制几何尺寸可以做到很精密,因此,其谐振频率也很准确。根据石英晶体的机电效应,我们可以把它等效为一个电磁振荡回路,即谐振回路。他们的机电效应是机-电-机-电....的不断转换,由电感和电容组成的谐振回路是电场-磁场的不断转换。在电路中的应用实际上是把它当作一个高Q值的电磁谐振回路。由于石英晶体的损耗非常小,即Q 值非常高,做振荡器用时,可以产生非常稳定的振荡,作滤波器用,可以获得非常稳定和陡削的带通或带阻曲线。

2、程序的调试

程序的调试是编写一个程序的重要步骤,根据思想框图写好代码,不是写完就可以运用,由于一些因素可能会造成程序无法编译,这等于代码不能使用,有时候会因为一个小小的标点符号,会使你半天找不到错误,因为目标太小,但却是致命的,debug过程比写程序还要麻烦,有时候你模仿别人的程序写出所需程序,写好了就是无法编译,这是跟编程者的思想息息相关,编写程序最好模块分明,注释明了,使人一目了然,让懂的人一看便知你的思想,这是最重要的,所以要条理清晰,这是我调试程序的一些心得体会。

五、测试方法和测试结果

在proteus下的仿真。

仿真如图11-图17所示

图11 80C51单片机部分

图12 排阻部分

图13 蜂鸣器部分

图14 按键部分

图15 时间显示部分

图16 比分显示部分

图17 仿真全图

调整比赛时间:插上电源后,系列默认比赛时间为12:00,甲乙队比分默认000,此时按下ADD1键,可以对比赛时间分钟加1,按下DEC1键,可以对比赛时间的分钟减1,按下ADD2键,可以对比赛时间秒加1,按下DEC2键,可以对比赛时间秒减1。

开始比赛:按下RUN/STOP键,计时开始,比赛时间以1秒的频率倒计时。

暂停比赛:比赛运行的状态下,按RUN/STOP键,比赛暂停,计时暂停。

比分修改:在比赛进行的状态下按ADD1,DEC1键,可以对甲队比分加、减1,

按ADD2、DEC2键,可以对乙队比分加、减1.

交换场地:在半场休息时,按下EXCHANGE键,比赛时间重新预置为12:00,同时左右两边数码管的比分交换显示。此时按下启动键可以开始新一节的比赛。

报警提示:在一节比赛时间倒计时到00:00时,蜂鸣器发出报警提示。

六、结论

通过这次工程设计实验,我们能很好地结合所学的一些理论知识,让我们更好地理解,通过实践使我们更进一步了解所学理论,巩固和加深印象,让我们从抽象的理论知识到生动的实体感受,更有利于学习和掌握新的知识。

附、源程序代码

#include #define LEDData P0

//定时数码管的段值从P0口输出

//数码管

unsigned char code

LEDCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 0--9的编码

unsigned char minit,second,count,count1; //分,秒,计数器

unsigned char set_minit=12,set_second=0;

sbit add1=P1^0; //甲队加分,每按一次加1分 /比赛前为时间加1分

sbit dec1=P1^1; //甲队减分,每按一次减1分/比赛前为时间减1分 sbit exchange=P1^2;

//交换场地

sbit add2=P1^3; //乙队加分,每按一次加1分/比赛前为时间加1秒 sbit dec2=P1^4; //乙队减分,每按一次减1分/比赛前为时间减1秒 sbit secondpoint=P0^7;

//----数码管的位选控制脚,共有10位数码管------ sbit led1=P2^7; sbit led2=P2^6; sbit led3=P2^5; sbit led4=P2^4;

//秒闪动点

sbit led5=P2^3; sbit led6=P2^2; sbit led7=P2^1; sbit led8=P2^0; sbit led9=P3^7; sbit led10=P3^6;

sbit alam=P1^7;

bit playon=0; bit timeover=0; bit AorB=0;

//比赛进行标志位,为1时表示比赛开始,计时开启 //比赛结束标志位,为1时表示比赛结束 //甲乙队交换位置标志位 //半秒标志位

//甲队得分 //乙队得分

//报警

bit halfsecond=0; unsigned int scoreA;

unsigned int scoreB;

//====================延时================== void Delay5ms(void) { }

void display(void)

{

//-----------显示时间(分钟)--------------

unsigned int i; for(i=100;i>0;i--);

LEDData=LEDCode[minit/10]; //显示分钟的十位 led1=0;

//开启位选

//延时,以便足以点亮数码管。 //关闭位选

Delay5ms(); led1=1;

LEDData=LEDCode[minit%10]; //显示分钟的个位

led2=0; Delay5ms(); led2=1;

//-------------秒点闪动------------ if(halfsecond==1)

LEDData=0x80;

else

LEDData=0x00;

led2=0; Delay5ms(); led2=1; secondpoint=0;

//-----------显示时间(秒钟)------------ LEDData=LEDCode[second/10]; led3=0; Delay5ms(); led3=1;

LEDData=LEDCode[second%10]; led4=0; Delay5ms(); led4=1;

//-----------显示1组的分数百位------- if(AorB==0)

LEDData=LEDCode[scoreA/100];

else

LEDData=LEDCode[scoreB/100];

//显示秒钟的十位

//显示秒钟的个位

Delay5ms(); led5=1;

//---------------显示1组分数的十位-----------

//---------------显示1组分数的个位-----------

//-----------显示2组分数的百位-------

if(AorB==0)

LEDData=LEDCode[(scoreA%100)/10];

else

LEDData=LEDCode[(scoreB%100)/10];

led6=0; Delay5ms(); led6=1;

if(AorB==0)

LEDData=LEDCode[scoreA%10];

else

LEDData=LEDCode[scoreB%10];

led7=0; Delay5ms(); led7=1;

if(AorB==1)

LEDData=LEDCode[scoreA/100];

else

LEDData=LEDCode[scoreB/100];

led8=0; Delay5ms(); led8=1;

//-----------显示2组分数的十位-----------

//-----------显示2组分数的个位-----------

}

//=========================按键检测程序

================================================

void keyscan(void) {

if(AorB==1)

LEDData=LEDCode[(scoreA%100)/10];

else

LEDData=LEDCode[(scoreB%100)/10];

led9=0; Delay5ms(); led9=1;

if(AorB==1)

LEDData=LEDCode[scoreA%10];

else

LEDData=LEDCode[scoreB%10];

led10=0; Delay5ms(); led10=1;

if(playon==0) {

//在比赛未开始的状态下

if(add1==0) {

display();

//当add1按键按下时

//调用显示,同时作为延时消抖

if(add1==0); //延时消抖后,依然检查到按键按下

{ } do

//当按键未松开时,一直调用显示,防止数

if(minit

minit++;

else

minit=99;

//否则,分钟仍然为99,调整为99分钟

码管闪动,

}

display();

while(add1==0);

if(dec1==0)

{ }

//当dec1键按下时,dec1的原理与add一样,

display(); if(dec1==0); { } do

display(); if(minit>0)

minit--;

else

minit=0;

while(dec1==0);

if(add2==0) {

display();

//调整秒,原理同上

if(add2==0); {

if(second

second++;

else

second=59;

} do

display();

while(add2==0);

}

if(dec2==0) { display(); if(dec2==0); { if(second>0)

second--;

else

second=0;

} do

display(); while(dec2==0);

}

if(exchange==0)

{ display(); if(exchange==0); { TR1=0;

alam=1;

//换场键

//关闭T1计数器//关报警

}

} do

AorB=~AorB;

//开启交换

}

minit=set_minit; second=0;

//并将时间预设为12:00

display();

while(exchange==0);

else {

//比赛开始。

if(add1==0) {

display();

//add1键按下

//调用显示,同时延时消抖

if(add1==0); {

if(AorB==0) { } else { }

if(scoreB

scoreB++;

//当场地标志位=1时,

if(scoreA

scoreA++;

//当场地标志位=0时,

else

scoreA=999;

//否则最大值为999分

else

scoreB=999;

//否则最在值为999分

}

do

display();

while(add1==0);

if(dec1==0) { }

display();

//当dec1键按下时,原理与add1一样,比分减1

if(dec1==0); { } do

display(); if(AorB==0) { } else { }

if(scoreB>0)

scoreB--; if(scoreA>0)

scoreA--;

else

scoreA=0;

else

scoreB=0;

while(dec1==0);

if(add2==0)

//原理同上

{

}

display(); if(add2==0); { } do

display(); if(AorB==1) { } else { }

if(scoreB

scoreB++; if(scoreA

scoreA++;

else

scoreA=999;

else

scoreB=999;

while(add2==0);

if(dec2==0) {

display(); if(dec2==0);

}

} } { } do display(); if(AorB==1) { } else { } if(scoreB>0) scoreB--; if(scoreA>0) scoreA--; else scoreA=0; else scoreB=0; while(dec2==0);

//******************************主函数

void main(void)

{

TMOD=0x11;

//TMOD设置 TL0=0xb0;

TH0=0x3c;

TL1=0xb0;

//定时器0,初值为0x3CB0,既定时0.05s //定时器1,初值为0x3CB0,即定时0.05s

TH1=0x3c;

minit=set_minit; second=0;

//开总中断 //开T0中断 //开T1中断 //初始值为12:00 EA=1; ET0=1; ET1=1; TR0=0;

TR1=0; EX0=1; IT0=1; IT1=1; //开外部中断0

// EX1=1;

PX0=1;

// PX1=1;

PT0=0; P1=0xFF; P3=0xFF;

while(1)

{

keyscan(); display(); //按键检查 //显示程序

}

}

//============外部中断0中断程序=================

void PxInt0(void) interrupt 0

{

Delay5ms(); EX0=0; alam=1; //关中断使能 //关蜂鸣器

TR1=0; //关定时器0 //当一节比较时间结束时,结束标志位=1 if(timeover==1) { } timeover=0; //清除标志位 if(playon==0)

} { } else { } //当比赛结束或暂停时 playon=1; TR0=1; //开始标志位 //开启计时 playon=0; TR0=0; //开始标志位清零,表示暂停 //暂停计时 EX0=1; //重新开中断

//===================定时器0中断服务函数======================

void time0_int(void) interrupt 1

{

TL0=0xb0;

TH0=0x3c;

TR0=1;

count++;

//启动计时 //软件计数器加1 //0.05s*10=0.5s,即0.5秒钟时 //重赋初值 if(count==10) { } halfsecond=0; //半秒标志位清零

if(count==20) //0.05s*20=1s,即1秒钟

{ count=0;

//清除计数器 //半秒标志置1 //倒计时,每计时1秒钟,时间减1,当秒halfsecond=1; if(second==0)

=0时,秒=59,分钟减1

{ } else

} second--; if(minit>0) { } else { } second=59; minit--; //当分,秒都为0时,表示倒计时时间到, timeover=1; playon=0; TR0=0; TR1=1; //时间标志位置1 //比赛标志清0,表示1节比赛结束 //关闭定时器0 //开启定时1,使蜂鸣器报警

}

//==============定时器1中断服务函数==========================

void time1_int(void) interrupt 3

{

TL1=0xb0; //重赋初值

TH1=0x3c;

TR1=1;

//启动计时

count1++;

} } //软件计数器加1 //0.05s*10=0.5s,也就是半秒钟 if(count1==10) { } alam=0; //开启蜂鸣器 if(count1==20) { count1=0; alam=1; //0.05s*20=1s,也就是1秒钟 //清除软件计数器, //关闭蜂鸣器,也就是蜂鸣器以1秒的频率响

参考文献及网站

[1]冯育长等. 单片机系统设计及实例分析. 西安:西安电子科技大学出版社, 2007.5

[2]雷思孝,冯育长.单片机系统设计及工程应用.西安:西安电子科技大学出版社,2005.5

[3]百度 http://www.baidu.com

[4]杨欣,王玉凤,刘湘黔.电子设计从零开始.北京:清华大学出版社,2005.10

[5]易运晖. Protel 99入(PCB) 0403Protel99SE-PCB.pdf

http://eelab.xidian.edu.cn/ 2012.10

[6]易运晖.Protel 99 入门(SCH) 0403Protel99SE-SCH.pdf

http://eelab.xidian.edu.cn/ 2012.10

[7]易运晖.Electronics Work Bench入门 EWB.pdf

http://eelab.xidian.edu.cn/ 2012.10


相关内容

  • 篮球赛计时计分器开题报告(自己写的)
  • 华东交通大学理工学院 本科生毕业设计 开题报告 题 目: 嵌入式篮球赛计分屏的设计 分 院: 电气与信息工程学院 专 业: 班 级: 学 号: 姓 名: 指导教师: 填表日期:年 目 录 一.选题的依据及意义„„„„„„„„„„„„„„„„„„„„„„„„„„„2 1.1选题的依据„„„„„„„„„ ...

  • 基于51单片机的篮球比赛计分计时器设计
  • 课 程 设 计 任 务 书 篮球比赛计分器设计 摘要:篮球比赛计分器的设计是为了解决篮球比赛时计分与计时准确方便和灵活适用的问题而提出的,我组设计的篮球比赛计分器硬件部分主要利用AT89S52单片机完成了计分与计时的功能,并通过两个四位七段数码管分别用来显示比赛时间和甲.乙比赛双方的分数,软件部分利 ...

  • 篮球产品设计说明书
  • 漯河市青少年科技创新奖候选人申报材料 智能篮球计时计分器设计与制作 1.前言 随着科学技术日新月异的发展,微电子技术更是以突飞猛进的速度前进.单片机(Single Chip Microcomputer or One Chip Microcomputer)是微型计算机的一个重要分支.它使计算机从海量数 ...

  • 电子综合课程设计题目
  • 电子综合课程设计题目汇总 1. 水温控制系统设计 任务:设计并制作一个水温自动控制系统,控制对象为1升净水,容器为搪瓷器皿.水温可以在一定范围内由人工设定,并能在环境温度降低时实现自动控制,以保持设定的温度基本不变. 要求: 1)基本要求 (1)温度设定范围为40-90℃,最小区分度为1℃,标定温度 ...

  • 51单片机篮球计分器程序+电路图
  • [复制链接] 电梯直达 楼主 niuniu发表于 2015-4-19 23:14:23|只看该作者 下面是电路图: 以下是篮球计分器的c语言程序源代码: #include #include #define uchar unsigned char #define uint unsigned int u ...

  • 单片机毕业设计题目
  • 1. 智能压力传感器系统设计 2. 智能定时器 3. 液位控制系统设计 4. 液晶控制模块的制作 5. 嵌入式激光打标机运动控制卡软件系统设计 6. 嵌入式激光打标机运动控制卡硬件系统设计 7. 基于单片机控制的数字气压计的设计与实现 8. 基于MSC1211的温度智能温度传感器 9. 机器视觉系统 ...

  • 自动化毕业设计论文题目
  • 自 动 化 毕 业 设 计 论 文 题 目 1. 智能压力传感器系统设计 2. 智能定时器 3. 液位控制系统设计 4. 液晶控制模块的制作 5. 嵌入式激光打标机运动控制卡软件系统设计 6. 嵌入式激光打标机运动控制卡硬件系统设计 7. 基于单片机控制的数字气压计的设计与实现 8. 基于MSC12 ...

  • 通信工程毕业设计题目精选
  • 不管怎样,生活还是要继续向前走去.有的时候伤害和失败不见得是一件坏事,它会让你变得更好,孤单和失落亦是如此.每件事到最后一定会变成一件好事,只要你能够走到最后. 通信工程毕业设计题目精选 1. 智能压力传感器系统设计 2. 智能定时器 3. 液位控制系统设计 4. 液晶控制模块的制作 5. 嵌入式激 ...

  • 电气自动化设计论文题目大全
  • 机电一体化 毕 业 设 计 论 文 题 目 第1-100个电气自动化毕业设计论文题目 1. 智能压力传感器系统设计 2. 智能定时器 3. 液位控制系统设计 4. 液晶控制模块的制作 5. 嵌入式激光打标机运动控制卡软件系统设计 6. 嵌入式激光打标机运动控制卡硬件系统设计 7. 基于单片机控制的数 ...