实训题目:篮球计分牌
1 系统设计
1.1 设计要求
1.1.1 设计任务
(1) 按照题目要求独立设计系统所需电路,并完成硬件电路的制作及调试。(40分)
(2)结合硬件能够正常计分(1,2,3)。(10分)
(3)能够正常显示分值。(10分)
(4)能够正常修改工作模式(计分与24秒)。(10分)
(5)能够24秒的误差不小于1秒。(15分)
能够两队球员犯规次数计数。
1.2 设计思路及设计框图
1.2.1设计思路
通过利用STC89C52RC芯片进行设计,7个按键实现对应功能:
(1)P1^3通过控制点对应切换1队和2队加分。
(2)P1^0、P1^1、P1^2分别对应+1、+2、+3分。
(3)P1^4计分清零
(4)P1^5对应24秒倒计时和计分的转换。
(5)P1^7外接复位键,对应复位功能。
外加复位键,按下则数码管显示回到比分计分显示,并清零;24秒倒计时至5秒时led灯依次点亮,倒计时结束时全部点亮。倒数为0时蜂鸣器响,重新倒数时蜂鸣器关闭。切换加分后24s倒计时会自动重新计时。24s倒计时需要用定时器中断方式0实现,采用工作方式一。并且每秒的时长要有晶振电路控制。
将12MHZ的石英晶体振荡器和单片机对应的引脚正确连接,将晶振产生的时钟信号作为定时信号。篮球计分牌分为三个部分:开关控制、数码管显示和警示电路。P主要在篮球比赛中用于记录24秒犯规计时和显示红蓝两队在比赛过程中的比分情况,本计时计分器有两部分组成:一部分用来实现计时功能,其基本原理和定时闹钟相似;另一部分用来实现计分功能,其基本原理和计数器相似,只不过所要记录和显示的对象分别是按键按下的次数和扫描脉冲次数。
1.2.2总体设计框图
2 各个模块程序的设计
2.1 AT89S52芯片模块
本次实验所用到的主要芯片,AT89S52是美国ATMEL公司生产的低电压,高性能CMOS8位单片机,片内含4K bytes的可反复擦写的只读程序存储器(PEROM)和128 bytes的随机存取数据存储器(RAM),期间采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器(CPU)和Flash存储单元,功能强大AT89S52单片机可为您提供许多高性价比的应用场合,可灵活应用于各种控制领域。
2.2振荡电路模块
晶振模块给电路提供一定频率的稳定的震荡(脉冲)信号。
2.3数码管显示模块
排阻保护电路使数码管正常输出相应的数据信息。
2.4 LED电路
通过LED灯来指示队伍、提示犯规、计时提示等功能。
2.5按键模块
按键控制加分、切换、计时控制等。
2.6电源部分
为电路提供电源,使其工作。
2.7复位模块
作用是将单片机复位,将单片机初始化。
3 调试过程
3.1制作过程
n 设计电路原理图;
n 上网查阅C51管脚及数码管管脚资料;
n 把器件安在打好孔的万用板上,然后焊接;
n 焊接好后,接通5V电源,检查电路是否显示正常;
n 根据硬件写出实现实训要求的对应程序,并进行调试,直到能全部正确实现要求的功能。
4 功能测试
4.1 测试仪器与设备
n 单片机程序下载线 1条
n 万用表 1个
n PC机 1台
4.2 性能指标测试
1、指标测试:以实现两队比分的正确显示,可以进行24S正常倒计时并报警,能记两队的1分2分3分。
2、软件调试还算顺利,没有太大的问题。
3、第一次硬件调试时,发现有一盏LED没有亮,确定是LED灯坏了便从新焊上一个好的。
4、拆掉所有跳线后,被指出所有的按键连接错误,这些按键内部结构是对脚线相连。于是重连按键。删掉原理图中不需要的元器件,直接按着原理图焊接跳线。
4.3 误差分析
倒计时24s在倒计时方面时和现实的时间存在点小误差,但是误差很小可以忽略.感觉软件方面没有什么问题,硬件上按键不是很灵敏,可能是线路接触不良。数码管验收出现小问题,是管脚虚焊导致的。
5 实训心得体会
通过这次实训,让我学习了很多。这次实训应该算是目前最难得一次实训吧。辅导老师给了基本的原理图,然后经过自己百度和同学帮助下完善了原理图。然后自己根据原理图焊了很久,最后焊完时让同学帮我下载程序,结果程序下载不进去,最后在学霸的帮助下解决了这个下问题。验收的时候我看其他同学都有好多的功能,感觉自己的功能略少,心里一阵紧张。不过幸运的是基本功能还是能实现的。就是验收的时候出现了一点小问题,数码管段选除了一些问题,应该是数码管管脚虚焊,但是在宿舍前一晚还好,以后要是在做实训要加强焊接
总的来说过程是最重要的,很开心自己能够完成这次实训,在这过程中又让我学很多知识。每次焊接虽然都要到晚上两点 ,虽然很累但是发现问题解决问题让我信心满满,这次实训让我明白了不要老想着靠别人自己动手操作一根根的去找,按照原理图一根去接会发现问题出在哪里,以前只想出现问题了去找大神帮忙,但是这次实训给了我很大的信心,虽然我每次实训都是一波三折,但是这也代表我不放弃所以以后做实训一定要自己査好资料,出现问题了先自己解决,在回答问题上我准备的还是不够充分,本来在前一天晚上看到了两点,一直再看原理图,但是关于周期和程序问题还是没回答上,不过在动手能力上又增强了很多信心!也谢谢两位老师开题的指导,衷心谢谢老师。
附录
附录1:原理图
附录2:程序清单
#include<reg52.H> //*****头文件*****//
#define ucharunsigned char //*定义变量*//
#define uint unsigned int //*定义uint为无符号整形变量*//
unsigned t =0x3cb0;
uchar CZ=24; //*计时初值*//
uchar key=0;
uchar score;
uchar mode=1;//*模式变量*//
uchar score1=0; //*甲队得分变量*//
ucharscore2=0; //*乙队得分变量*//
ucharbittime=0,bitdisplay=0; //*定义变量*//
uchar codetab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //*段码0,1,2,3,4,5,6,7,8,9*//
sbit J0=P1^0; //*独立按键 *//
sbit J1=P1^1;
sbit J2=P1^2;
sbit J3=P1^3;
sbit J4=P1^4;
sbit J5=P1^5;
sbit J6=P1^6;
sbit LED1 = P3^4;
sbit LED2 = P3^5;
sbit LED3 = P3^6;
sbit LED4 = P3^7;
sbit SPK=P1^7;
/********延时函数******/
void delay(ucharz)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/* 服务程序*/
void timer0 (void)interrupt 1 using 0
{
TH0=0x3c; //*50ms*//
TL0=0xb0;
bittime++; //每来一次中断,中断次数bittime自加1
while(bittime==20)
{
bittime=0; //每经一秒调用一次显示程序
bitdisplay=1;
if(bitdisplay)
{
bitdisplay = 0;
CZ--;
if(-1 == CZ) CZ=24;
}
}
}
/* 甲队分数显示函数*/
voiddisplay_1(uint z)
{
P2 = 0XFD; /*11111101甲队个位分数显示*/
P0 = tab[z%10];
delay(10);
P2 = 0XFE; /*11111110甲队十位分数显示*/
P0 = tab[z/10];
delay(10);
}
/* 乙队分数显示函数*/
voiddisplay_2(uint z)
{
P2 = 0Xfb; /*11110111乙队个位分数显示*/
P0 = tab[z%10];
delay(10);
P2 = 0Xf7; /*11111011乙队十位分数显示*/
P0 = tab[z/10];
delay(10);
}
/* 甲分数处理函数*/
int inc1()
{
if(~J3)
{
delay(10);
score1=score1+1;
}while(~J3);
if(~J4)
{
delay(10);
score1= score1+2;
}while(~J4);
if(~J5)
{
delay(10);
score1=score1+3;
}while(~J5);
returnscore1;
}
/* 乙分数处理函数*/
int inc2()
{
if(~J3)
{
delay(10);
score2=score2+1;
}while(~J3);
if(~J4)
{
delay(10);
score2= score2+2;
}while(~J4);
if(~J5)
{
delay(10);
score2=score2+3;
}while(~J5);
returnscore1;
}
/* 甲乙队切加分换处理函数*/
uchar turn()
{
if(~J2)
{
delay(10);
if(~J2)
{
delay(10);
LED1 = 1;
LED2 = 1;
LED3 = 0;
LED4 = 1;
key = 1;
}while(~J2);
}
if(~J6)
{
delay(10);
if(~J6)
{
delay(10);
LED1 = 1;
LED2 = 1;
LED3 = 1;
LED4 = 0;
key = 2;
}while(~J6);
}
return key;
}
/* 加分显示函数*/
void marks()
{
turn();
if(key== 1)
{
inc1();
if(score1<100)
{
display_1(score1);
display_2(score2);
}
else score1 =score1-100;
}
elseif(key == 2)
{
inc2();
if(score2<100)
{
display_1(score1);
display_2(score2);
}
else score2 = score2-100;
}
}
/*模式选择函数*/
ucharmode_select()
{
if(~J0)
{
delay(10);
if(~J0)
{
delay(10);
mode = 1;
LED1 = 0;
LED2 = 1;
LED3 = 1;
LED4 = 1;
}while(~J0);
}
if(~J1)
{
delay(10);
if(~J1)
{
delay(10);
mode = 2;
LED1 = 1;
LED2 = 0;
LED3 = 1;
LED4 = 1;
}while(~J1);
}
return mode;
}
/*倒计时处理*/
void time_count()
{
TR0 = 1;
P2 = 0XFD; /*11111010甲乙十位显示*/
P0 = tab[CZ/10];
delay(10);
P2 = 0XFB; /*11110101甲乙个位显示*/
P0 = tab[CZ%10];
delay(10);
}
/* 主函数*/
int main()
{
TMOD= 0x01;
TH0=0x3c;
TL0=0xb0;
EA = 1; //cpu允许所有中断
ET0 =1;//定时器T0中断允许
TR0 = 0;//关闭定时器T0
P2 = 0XF0;
P0 = 0x3f;
SPK=0;
while(1)
{
mode_select();
if(1 == mode) //加分功能
{
TR0 = 0;//关闭定时器
CZ = 24; //重新赋初值24秒
display_1(score1);
delay(10);
display_2(score2);
marks();
}
if(2== mode) //计时功能
{
if(CZ == 0){TR0 = 0,SPK=1;delay(30);SPK =0;
foul_sever();
}
time_count();}
}
return 0;
}
|