标题:
篮球计分器 单片机程序
[打印本页]
作者:
crrr
时间:
2025-4-10 09:30
标题:
篮球计分器 单片机程序
#include<reg51.h>//51单片机头文件
typedef unsigned char uchar;
typedef unsigned int uint;
sbit K1=P3^2;//比赛倒计时开始/暂停
sbit K2=P3^3;//24s倒计时重新开始
sbit K3=P1^3;//乙队+1按键
sbit K4=P1^2;//乙队+2按键
sbit K5=P1^1;//甲队+1按键
sbit K6=P1^0;//甲队+2按键
sbit K7=P1^4;//乙队+3按键
sbit K8=P1^5;//甲队+3按键
sbit K9=P1^6;//半场积分互换
sbit K10=P1^7;//分数清0
sbit K11=P2^1;//乙队-1按键
sbit K12=P2^2;//甲队-1按键
sbit K13=P2^3;//乙队犯规按键
sbit K14=P2^4;//甲队犯规按键
sbit LED1=P2^6;//乙队犯规灯
sbit LED2=P3^4;//乙队犯规灯
sbit LED3=P3^0;//甲队犯规灯
sbit LED4=P3^1;//甲队犯规灯
sbit K15=P3^5;//乙队犯规清0按键
sbit K16=P3^6; //甲队犯规清0按键
sbit beep=P2^0;//蜂鸣器接口
sbit RS=P2^7;
sbit E=P2^5;
char miao,fen,num,time,aa;
uchar bb,cc,tt;
uchar code table1[]={"H.T 000:000 R.T "};
uchar code table2[]={"10:00 SEC-1 24"};
bit key_pressed = 0; // 按键按下标志
bit key_pressed1 = 0; // 按键按下标志
unsigned char led_state = 0; // LED状态: 0=都灭, 1=LED1亮, 2=都亮
unsigned char led_state1 = 0; // LED状态: 0=都灭, 1=LED1亮, 2=都亮
//延时子函数
void delay(uint z)
{
uint x;
uchar y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//LCD1602液晶写指令子函数
void write_com(uchar com)
{
RS=0;
P0=com;
delay(5);
E=1;
delay(5);
E=0;
}
//LCD1602液晶写数据子函数
void write_date(uchar date)
{
RS=1;
P0=date;
delay(5);
E=1;
delay(5);
E=0;
}
//LCD1602液晶初始化子函数
void LCD1602_init()
{
uchar i;
bb=0; //H.T分数初始化
cc=0; //R.T分数初始化
time=0;
TMOD=0x10; //定时器1初始化
TL1=0x00;
TH1=0x4c;
EA=1; //开总中断
ET1=1; //开定时器1
TR1=0; //定时器1不工作
EX0=1; //开中断0
EX1=1; //开中断1
IT0=1; //中断0为边沿触发
IT1=1; //中断1为边沿触发
E=0;
beep=0;
miao=0;
fen=10;
num=1;
aa=24;
write_com(0x38); //LCD设置初始化
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80); //LCD显示初始化
for(i=0;i<16;i++)
{
write_date(table1[i]);
}
write_com(0x80+0x40);
for(i=0;i<16;i++)
{
write_date(table2[i]);
}
}
//分数更新子函数
void point_lcd(uchar add,uchar dat)
{
write_com(0x80+add);
write_date(0x30+dat/100);
write_date(0x30+(dat%100)/10);
write_date(0x30+dat%10);
write_com(0x80+add);
}
//按键扫描子函数
void keyscan()
{
if(K3==0) //K3按下H.T分数加一
{
while(K3==0);
bb++;
point_lcd(0x04,bb); //分数显示更新
if(K3==0) //松手检测
{
while(K3==0);
delay(20);
}
}
else if(K4==0) //K4按下H.T分数加二
{
while(K4==0);
bb=bb+2;
point_lcd(0x04,bb);
if(K4==0)
{
while(K4==0);
delay(20);
}
}
else if(K7==0) //K7按下H.T分数加3
{
while(K7==0);
bb=bb+3;
point_lcd(0x04,bb);
if(K7==0)
{
while(K7==0);
delay(20);
}
}
else if(K5==0) //K5按下R.T分数加一
{
while(K5==0);
cc++;
point_lcd(0x08,cc);
if(K5==0)
{
while(K5==0);
delay(20);
}
}
else if(K6==0) //K6按下R.T分数加2
{
while(K6==0);
cc=cc+2;
point_lcd(0x08,cc);
if(K6==0)
{
while(K6==0);
delay(20);
}
}
else if(K8==0) //K9按下R.T分数加3
{
while(K8==0);
cc=cc+3;
point_lcd(0x08,cc);
if(K8==0)
{
while(K8==0);
delay(20);
}
}
else if(K10==0) //K10按下分数清0
{
while(K10==0);
bb=0;
cc=0;
point_lcd(0x04,bb);
point_lcd(0x08,cc);
if(K10==0)
{
while(K10==0);
delay(20);
}
}
else if(K9==0) //K9半场场地互换,积分互换
{
while(K9==0);
{
// uchar code table3[]={"R.T 000:000 H.T "};
tt=bb;bb=cc;cc=tt;
}
point_lcd(0x04,bb);
point_lcd(0x08,cc);
if(K9==0)
{
while(K9==0);
delay(20);
}
}
if(K13 == 0) //K13乙队犯规按键
{
delay(10); // 消抖延时
if(K13 == 0 && !key_pressed) {
key_pressed = 1; // 设置按键按下标志
// 根据当前状态切换LED
if(led_state == 0) {
LED1 = 1; // 点亮第一个LED
led_state = 1;
}
else if(led_state == 1) {
LED2 = 1; // 点亮第二个LED
led_state = 2;
}
// 当led_state == 2时不做任何操作
}
} else {
key_pressed = 0; // 按键释放,清除标志
}
if(K14 == 0) //K13甲队犯规按键
{
delay(10); // 消抖延时
if(K14 == 0 && !key_pressed1) {
key_pressed1 = 1; // 设置按键按下标志
// 根据当前状态切换LED
if(led_state1 == 0) {
LED3 = 1; // 点亮第一个LED
led_state1 = 1;
}
else if(led_state1 == 1) {
LED4 = 1; // 点亮第二个LED
led_state1 = 2;
}
// 当led_state == 2时不做任何操作
}
} else {
key_pressed1 = 0; // 按键释放,清除标志
}
if(K15==0) //K15按下乙队犯规清0
{
while(K15==0);
LED1=0;
LED2=0;
if(K15==0) //松手检测
{
while(K15==0);
delay(20);
}
}
if(K16==0) //K15按下乙队犯规清0
{
while(K16==0);
LED3=0;
LED4=0;
if(K16==0) //松手检测
{
while(K16==0);
delay(20);
}
}
}
//比赛倒计时/24s倒计时
void counter_down()
{
uchar i;
if(time>=20) //每1s倒计时做减一操作
{
miao--;
aa--;
write_com(0x80+0x4e); //24s倒计时显示
write_date(0x30+aa/10);
write_date(0x30+aa%10);
write_com(0x80+0x4e);
if(aa==0) //24s结束发出3s连续报警
{
beep=1;
delay(3000);
beep=0;
aa=24;
}
if((miao==0)&&(fen==0)) //检测一节比赛是否结束
{
TR1=0; //定时器1暂停
write_com(0x80+0x44);
write_date(0x30);
num++;
aa=24; //24s计时复位
write_com(0x80+0x4e); //24s倒计时显示
write_date(0x30+aa/10);
write_date(0x30+aa%10);
write_com(0x80+0x4e);
if(num<5) //每节结束蜂鸣器发出8s的间断报警
{
for(i=80;i>0;i--)
{
beep=1;
delay(500);
beep=0;
delay(500);
}
}
if(num==5) //终场结束,蜂鸣器发出10s的连续警报声
{
beep=1;
delay(10000);
num=0;
}
beep=0; //蜂鸣器关闭
write_com(0x80+0x4b); //更新"SEC-?"
write_date(0x30+num);
write_com(0x80+0x4b);
miao=0; //倒计时复位
fen=10;
}
if(miao<=0)
{
miao=59;
fen--;
}
write_com(0x80+0x40); //更新倒计时显示
write_date(0x30+fen/10);
write_date(0x30+fen%10);
write_com(0x80+0x43);
write_date(0x30+miao/10);
write_date(0x30+miao%10);
write_com(0x80+0x43);
time=0;
}
}
//主函数
void main()
{
LCD1602_init();
LED1 = 0; // 初始关闭LED1
LED2 = 0; // 初始关闭LED2
LED3 = 0; // 初始关闭LED1
LED4 = 0; // 初始关闭LED2
while(1)
{
keyscan(); //分数按键检测
}
}
//外部0中断子函数
void wb0() interrupt 0 //比赛时间开始/暂停
{
TR1=~TR1; //定时器1工作/暂停
if(TR1==1) //当倒计时工作时,S1按下定时器立即停止工作
{
PT1=0;
}
else //倒计时不工作时,S1按下倒计时立即工作
{
PT1=1;
}
if(K1==0) //松手检测
{
while(K1==0);
counter_down();
// delay(20);
}
}
//外部1中断子函数
void wb1() interrupt 2 //24s倒计时重新开始
{
aa=24;
write_com(0x80+0x4e); //24s倒计时显示
write_date(0x30+aa/10);
write_date(0x30+aa%10);
write_com(0x80+0x4e);
if(K2==0) //松手检测
{
while(K2==0)
{
counter_down();
}
delay(20);
}
}
//定时器1中断子函数
void t1() interrupt 3 //定时器1中断20次为1s
{
time++;
TL1=0x00;
TH1=0x4c;
counter_down(); //倒计时
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1