基于单片机的篮球记分牌.docx

上传人:b****3 文档编号:26834064 上传时间:2023-06-23 格式:DOCX 页数:23 大小:731.72KB
下载 相关 举报
基于单片机的篮球记分牌.docx_第1页
第1页 / 共23页
基于单片机的篮球记分牌.docx_第2页
第2页 / 共23页
基于单片机的篮球记分牌.docx_第3页
第3页 / 共23页
基于单片机的篮球记分牌.docx_第4页
第4页 / 共23页
基于单片机的篮球记分牌.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

基于单片机的篮球记分牌.docx

《基于单片机的篮球记分牌.docx》由会员分享,可在线阅读,更多相关《基于单片机的篮球记分牌.docx(23页珍藏版)》请在冰豆网上搜索。

基于单片机的篮球记分牌.docx

基于单片机的篮球记分牌

篮球记分牌

一.设计要求:

1、比赛开始,比分能够全部清零,数码管前2位、末2位做记分用,当中2位做24秒倒计时用。

2、24秒倒计时时间到,蜂鸣器响、指示灯亮,重新开始倒计时,蜂鸣器停止鸣叫、指示灯灭。

3、比分进行增加后,倒计时从24秒重新开始倒计时。

任意时刻24秒可以重新开始倒计时。

必要时候能够关闭倒计时。

4、利用AT24C02或者单片机内部资源保存比分,支持复位保存,掉电保存功能。

5、其他附加功能。

二.原理图:

三.实验流程图:

 

 

四.实验程序:

Main.c文件:

/*********************************************************************************************

函数名:

篮球记分牌

说明:

比赛开始,比分能够全部清零,数码管前2位、末2位做记分用,当中2位做24秒倒计时用。

24秒倒计时时间到,蜂鸣器响、指示灯亮,重新开始倒计时,蜂鸣器停止鸣叫、指示灯灭。

比分进行增加后,倒计时从24秒重新开始倒计时。

任意时刻24秒可以重新开始倒计时。

必要时候能够关闭倒计时。

作者:

完成日期:

2012.12.2

/**********************************************************************************************/

#include

#include

#include"eeprom.h"

#defineucharunsignedchar

#defineuintunsignedint

/***********端口定义*************/

/*数码管段选用P0口,位选用P2口*/

/******指示灯******/

sbitLED=P3^4;

/********蜂鸣器*********/

sbitFMQ=P3^5;

/******数组定义*******/

ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x07f,0x6f};//0,1,2,3,4,5,6,7,8,9

ucharpassword[6];//掉电保存6位数组

/***********变量定义*************/

ucharfen1;//甲队初始得分

ucharfen2;//乙队初始得分

ucharfen3;//甲乙两队上下半场换分

ucharSJ;//时间变量值

ucharcxjs=1;//重新计时标志位

ucharkey;//矩阵键盘按键值

uchartemp;//矩阵键盘P1口寄存变量

uchartime;//中断计数器

 

/***********************************************************

函数名称:

delay

函数功能:

基本延时程序

入口参数:

出口参数:

备注:

***********************************************************/

voiddelay(ucharx)

{ucharj;

while((x--)!

=0)

{for(j=0;j<125;j++)

{;}

}

}

/***********************************************************

函数名称:

display

函数功能:

数码管显示程序

入口参数:

fen1,fen2,SJ

出口参数:

备注:

***********************************************************/

voiddisplay(void)

{

ucharm;

for(m=6;m>0;m--)

{

delay

(2);

if(m==6)

{P2=0XFE;

P0=table[fen1/10];}

if(m==5)

{P2=0XFD;

P0=table[fen1%10];}

if(m==4)

{P2=0XFB;

P0=table[SJ/10];}

if(m==3)

{P2=0XF7;

P0=table[SJ%10];}

if(m==2)

{P2=0XEF;

P0=table[fen2/10];}

if(m==1)

{P2=0XDF;

P0=table[fen2%10];}

}

}

/***********************************************************

函数名称:

keyscan

函数功能:

4X4矩阵键盘扫描程序

入口参数:

出口参数:

备注:

读取的键值赋给了key

***********************************************************/

voidkeyscan(void)

{

temp=P1;

if(temp!

=0xf0)

{

delay(120);

if(temp!

=0xf0)

{

P1=0xfe;

temp=P1;

delay(120);

switch(temp)

{

case(0xee):

key=0;break;

case(0xde):

key=1;break;

case(0xbe):

key=2;break;

case(0x7e):

key=3;break;

}

P1=0xfd;

temp=P1;

delay(120);

switch(temp)

{

case(0xed):

key=4;break;

case(0xdd):

key=5;break;

case(0xbd):

key=6;break;

case(0x7d):

key=7;break;

}

P1=0xfb;

temp=P1;

delay(120);

switch(temp)

{

case(0xeb):

key=8;break;

case(0xdb):

key=9;break;

case(0xbb):

key=10;break;

case(0x7b):

key=11;break;

}

P1=0xf7;

temp=P1;

delay(120);

switch(temp)

{

case(0xe7):

key=12;break;

case(0xd7):

key=13;break;

case(0xb7):

key=14;break;

case(0x77):

key=15;break;

}

}

}

}

/***********************************************************

函数名称:

keydown

函数功能:

4X4矩阵键盘判断程序

入口参数:

出口参数:

备注:

判断是否有按键按下

***********************************************************/

voidkeydown(void)

{

P1=0xF0;

if(P1!

=0xF0)

{

delay(150);//消抖

if(P1!

=0xF0)

{keyscan();}

}

}

/***********************************************************

函数名称:

timer0init

函数功能:

定时器初始化部分程序

入口参数:

出口参数:

备注:

设置定时器0工作方式

***********************************************************/

voidtimer0init()

{

TMOD&=0xf0;//定时器0工作方式1

TMOD|=0x01;

}

/***********************************************************

函数名称:

timer0

函数功能:

中断服务程序

入口参数:

出口参数:

备注:

此程序无调用

***********************************************************/

voidtimer0(void)interrupt1using0

{

TH0=0x15;

TL0=0xa0;

time=time+1;

if(time==20)

{

time=0;

SJ=SJ-1;

if(SJ==0)

{SJ=0;

EA=0;

FMQ=0;

LED=0;}

}

}

/***********************************************************

函数名称:

setpassword

函数功能:

掉电保存程序

入口参数:

出口参数:

备注:

此程序调用eeprom_eares擦除扇区程序,eeprom_write字节编程程序

***********************************************************/

voidsetpassword()

{

eeprom_eares(0x0000);

eeprom_write(0x0000,fen1/10);

eeprom_write(0x0001,fen1%10);

eeprom_write(0x0002,SJ/10);

eeprom_write(0x0003,SJ%10);

eeprom_write(0x0004,fen2/10);

eeprom_write(0x0005,fen2%10);

}

/***********************************************************

函数名称:

getpassword

函数功能:

读出eeprom内存储值

入口参数:

出口参数:

备注:

***********************************************************/

voidgetpassword()

{

uchari;

for(i=0;i<6;i++)

password[i]=eeprom_read(i);

}

/***********************************************************

函数名称:

main

函数功能:

主程序

入口参数:

出口参数:

备注:

实现功能:

通过按键开始/停止,暂停/继续计时和对甲乙两队的加分

***********************************************************/

voidmain()

{

LED=1;

FMQ=1;

P2=0xFF;

P1=0xF0;

SJ=24;

fen1=0;

fen2=0;

key=16;

/*定时器设置*/

timer0init();

ET0=1;

TR0=1;

while

(1)

{

display();

keydown();

if(key==0)//开始按键

{

EA=1;

}

if(key==1)//甲队加分按键

{

fen1=fen1+1;

cxjs=0;

}

if(key==2)//乙队加分按键

{

fen2=fen2+1;

cxjs=0;

}

if(key==3)//暂停计时

{EA=0;}

if(key==4)//停止按键

{

fen1=0;

fen2=0;

SJ=24;

EA=0;

FMQ=1;

LED=1;

}

if(key==5)//上下半场换分

{

fen3=fen1;

fen1=fen2;

fen2=fen3;

}

if(cxjs==0)//重新计时

{

SJ=24;

cxjs=1;

}

if(key==6)//保存当前值

{setpassword();}

if(key==7)//调用前次记录

{

getpassword();

fen1=password[0]*10+password[1];

SJ=password[2]*10+password[3];

fen2=password[4]*10+password[5];

EA=0;

}

key=16;//此处赋值key,否则key将一直保留按键后的值

}

}

Eeprom.c文件:

#defineeeprom

#include"eeprom.h"

//-------------------------------------------------------------------------------------------------------

//EEPROM操作

//------------------------------------------------------------------------------------------------------

//定义Flash操作等待时间及允许IAP/ISP/EEPROM操作的常数

//#defineENABLE_ISP0x80//系统工作时钟<30MHz时,对IAP_CONTR寄存器设置此值

//#defineENABLE_ISP0x81//系统工作时钟<24MHz时,对IAP_CONTR寄存器设置此值

#defineENABLE_ISP0x82//系统工作时钟<20MHz时,对IAP_CONTR寄存器设置此值

//#defineENABLE_ISP0x83//系统工作时钟<12MHz时,对IAP_CONTR寄存器设置此值

//#defineENABLE_ISP0x84//系统工作时钟<6MHz时,对IAP_CONTR寄存器设置此值

//#defineENABLE_ISP0x85//系统工作时钟<3MHz时,对IAP_CONTR寄存器设置此值

//#defineENABLE_ISP0x86//系统工作时钟<2MHz时,对IAP_CONTR寄存器设置此值

//#defineENABLE_ISP0x87//系统工作时钟<1MHz时,对IAP_CONTR寄存器设置此值

 

unionunion_temp16

{

unsignedintun_temp16;

unsignedcharun_temp8[2];

}my_unTemp16;

unsignedchareeprom_read(unsignedintadd);//读一字节,调用前需打开IAP功能

voideeprom_write(unsignedintadd,unsignedcharch);//字节编程,调用前需打开IAP功能

voideeprom_eares(unsignedintadd);//擦除扇区

voidIAP_Disable();//关闭IAP功能

 

voidIAP_Disable()

{

//关闭IAP功能,清相关的特殊功能寄存器,使CPU处于安全状态,

//一次连续的IAP操作完成之后建议关闭IAP功能,不需要每次都关

IAP_CONTR=0;//关闭IAP功能

IAP_CMD=0;//清命令寄存器,使命令寄存器无命令,此句可不用

IAP_TRIG=0;//清命令触发寄存器,使命令触发寄存器无触发,此句可不用

IAP_ADDRH=0;

IAP_ADDRL=0;

}

//读一字节,调用前需打开IAP功能,入口:

DPTR=字节地址,返回:

A=读出字节

unsignedchareeprom_read(unsignedintadd)

{

IAP_DATA=0x00;

IAP_CONTR=ENABLE_ISP;//打开IAP功能,设置Flash操作等待时间

IAP_CMD=0x01;//IAP/ISP/EEPROM字节读命令

my_unTemp16.un_temp16=add;

IAP_ADDRH=my_unTemp16.un_temp8[0];//设置目标单元地址的高8位地址

IAP_ADDRL=my_unTemp16.un_temp8[1];//设置目标单元地址的低8位地址

//EA=0;

IAP_TRIG=0x5A;//先送5Ah,再送A5h到ISP/IAP触发寄存器,每次都需如此

IAP_TRIG=0xA5;//送完A5h后,ISP/IAP命令立即被触发起动

_nop_();

//EA=1;

IAP_Disable();//关闭IAP功能,清相关的特殊功能寄存器,使CPU处于安全状态,

//一次连续的IAP操作完成之后建议关闭IAP功能,不需要每次都关

return(IAP_DATA);

}

//字节编程,调用前需打开IAP功能,入口:

DPTR=字节地址,A=须编程字节的数据

voideeprom_write(unsignedintadd,unsignedcharch)

{

IAP_CONTR=ENABLE_ISP;//打开IAP功能,设置Flash操作等待时间

IAP_CMD=0x02;//IAP/ISP/EEPROM字节编程命令

my_unTemp16.un_temp16=add;

IAP_ADDRH=my_unTemp16.un_temp8[0];//设置目标单元地址的高8位地址

IAP_ADDRL=my_unTemp16.un_temp8[1];//设置目标单元地址的低8位地址

IAP_DATA=ch;//要编程的数据先送进IAP_DATA寄存器

//EA=0;

IAP_TRIG=0x5A;//先送5Ah,再送A5h到ISP/IAP触发寄存器,每次都需如此

IAP_TRIG=0xA5;//送完A5h后,ISP/IAP命令立即被触发起动

_nop_();

//EA=1;

IAP_Disable();//关闭IAP功能,清相关的特殊功能寄存器,使CPU处于安全状态,

//一次连续的IAP操作完成之后建议关闭IAP功能,不需要每次都关

}

//擦除扇区,入口:

DPTR=扇区地址

voideeprom_eares(unsignedintadd)

{

IAP_CONTR=ENABLE_ISP;//打开IAP功能,设置Flash操作等待时间

IAP_CMD=0x03;//IAP/ISP/EEPROM扇区擦除命令

my_unTemp16.un_temp16=add;

IAP_ADDRH=my_unTemp16.un_temp8[0];//设置目标单元地址的高8位地址

IAP_ADDRL=my_unTemp16.un_temp8[1];//设置目标单元地址的低8位地址

//EA=0;

IAP_TRIG=0x5A;//先送5Ah,再送A5h到ISP/IAP触发寄存器,每次都需如此

IAP_TRIG=0xA5;//送完A5h后,ISP/IAP命令立即被触发起动

_nop_();

//EA=1;

IAP_Disable();//关闭IAP功能,清相关的特殊功能寄存器,使CPU处于安全状态,

//一次连续的IAP操作完成之后建议关闭IAP功能,不需要每次都关

}

//-------------------------------------------------------------------------------------------------------

Eeprom.h文件:

#ifndef_eeprom_h_

#define_eeprom_h_

#ifdefeeprom

#include

#include"intrins.h"

#defineEXET

#else

#defineEXETextern

#endif

//typedefunsignedcharINT8U;

//typedefunsignedintINT16U;

EXETunsignedchareeprom_read(unsignedintadd);//读一字节,调用前需打开IAP功能

EXETvoideeprom_write(unsignedintadd,unsignedcharch);//字节编程,调用前需打开IAP功能

EXETvoideeprom_eares(unsignedintadd);//擦除扇区

#endif

 

五.实验仿真:

 

六.实验实物图:

七.实验总结:

通过这次单片机课程设计,我学到了很多东西。

主要收获有:

1.将理论教学与实践相结合,使我对于单片机的实际应用有了较深刻的认识;

2.使我对单片机应用系统设计的各种方法有所了解;

3.通过分工合作,培养了我和同学之间的合作精神;

4.让我熟悉了电子系统设计的全过程;提高了我对设计课题的分析能力、编程能力及解决实际问题的综合能力。

5.通过实践,增强了我下阶段的学习信心。

存在的问题:

1.对于基础知识掌握的不牢固。

2.缺乏对于电子系统设计测试的概念。

总之,通过这次单片机课程设计,我不但学到了很多知识,而且还看到了自己的不足之处,在以后的学习生活中,我会加以改正的。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1