这么特殊的程序需要定制开发,重点是时钟芯片、按键处理和数码管显示程序段。
看板子是无法编程的,必须原理图才可以,这里有一个篮球计分程序,供参考。
UP1 EQU P1.1
DOWN1 EQU P1.2
UP2 EQU P1.3
DOWN2 EQU P1.4
CHANGE EQU P1.5
BEGIN EQU P1.6
BEEF EQU P2.4
DUAN EQU P2.3
WEI EQU P2.2
GRATE1 EQU 30H
GRATE2 EQU 31H
GRATE_CHG EQU 33H
TIME EQU 34H
CNT EQU 35H
ORG 0000H
LJMP MAIN
ORG 001BH
LJMP T1ISR
ORG 0030H
MAIN:
LCALL INITTIMER1
SETB UP1
SETB DOWN1
SETB UP2
SETB DOWN2
SETB CHANGE
SETB BEGIN
LOOP:
JB UP1,LOOP1
CLR ET1
MOV R7,#5
LCALL DELAY
JNB UP1,$
INC GRATE1
SETB ET1
SJMP LOOP6
LOOP1:
JB DOWN1,LOOP2
CLR ET1
MOV R7,#5
LCALL DELAY
JNB DOWN1,$
MOV A,GRATE1
DEC A
MOV GRATE1,A
SETB ET1
SJMP LOOP6
LOOP2:
JB UP2,LOOP3
CLR ET1
MOV R7,#5
LCALL DELAY
JNB UP2,$
INC GRATE2
SETB ET1
SJMP LOOP6
LOOP3:
JB DOWN2,LOOP4
CLR ET1
MOV R7,#5
LCALL DELAY
JNB DOWN2,$
MOV A,GRATE2
DEC A
MOV GRATE2,A
SETB ET1
SJMP LOOP6
LOOP4:
JB CHANGE,LOOP5
CLR ET1
MOV R7,#5
LCALL DELAY
JNB CHANGE,$
MOV GRATE_CHG,GRATE1
MOV GRATE1,GRATE2
MOV GRATE2,GRATE_CHG
SETB ET1
SJMP LOOP6
LOOP5:
JB BEGIN,LOOP6
MOV R7,#5
LCALL DELAY
JNB BEGIN,$
SETB TR1
LOOP6:
MOV A,TIME
JNZ LOOP7
MOV TIME,#99
CLR TR1
MOV R7,#100
LCALL BEEFE
LOOP7:
LCALL DISPLAY
LJMP LOOP
T1ISR:
CLR TR1
MOV TH1,#HIGH(65536-50000)
MOV TL1,#LOW(65536-50000)
SETB TR1
DJNZ CNT,T0E
MOV CNT,#20
DEC TIME
T0E:
RETI
INITTIMER1:
MOV TMOD,#10H
MOV TH1,#HIGH(65536-50000)
MOV TL1,#LOW(65536-50000)
SETB EA
SETB ET1
MOV CNT,#20
MOV TIME,#99
RET
DELAY:
MOV R2,#17
DLY:
MOV R3,#26
DJNZ R3,$
DJNZ R2,DLY
DJNZ R7,DELAY
RET
BEEFC:
MOV R2,#17
BEEFD:
MOV R3,#16
BEEFE:
CPL BEEF
DJNZ R3,BEEFE
DJNZ R2,BEEFD
DJNZ R7,BEEFC
RET
DISPLAY:
MOV A,GRATE1
MOV B,#10
DIV AB
MOV 40H,A
MOV 41H,B
MOV A,GRATE2
MOV B,#10
DIV AB
MOV 42H,A
MOV 43H,B
MOV A,TIME
MOV B,#10
DIV AB
MOV 46H,A
MOV 47H,B
MOV P0,#0FFH
SETB WEI
MOV P0,#0FEH
CLR WEI
MOV P0,#0FFH
SETB DUAN
MOV DPTR,#LEDTAB
MOV A,40H
MOVC A,@A+DPTR
MOV P0,A
CLR DUAN
MOV R7,#5
LCALL DELAY
MOV P0,#0FFH
SETB WEI
MOV P0,#0FDH
CLR WEI
MOV P0,#0FFH
SETB DUAN
MOV DPTR,#LEDTAB
MOV A,41H
MOVC A,@A+DPTR
MOV P0,A
CLR DUAN
MOV R7,#5
LCALL DELAY
MOV P0,#0FFH
SETB WEI
MOV P0,#0FBH
CLR WEI
MOV P0,#0FFH
SETB DUAN
MOV DPTR,#LEDTAB
MOV A,42H
MOVC A,@A+DPTR
MOV P0,A
CLR DUAN
MOV R7,#5
LCALL DELAY
MOV P0,#0FFH
SETB WEI
MOV P0,#0F7H
CLR WEI
MOV P0,#0FFH
SETB DUAN
MOV DPTR,#LEDTAB
MOV A,43H
MOVC A,@A+DPTR
MOV P0,A
CLR DUAN
MOV R7,#5
LCALL DELAY
MOV P0,#0FFH
SETB WEI
MOV P0,#0BFH
CLR WEI
MOV P0,#0FFH
SETB DUAN
MOV DPTR,#LEDTAB
MOV A,46H
MOVC A,@A+DPTR
MOV P0,A
CLR DUAN
MOV R7,#5
LCALL DELAY
MOV P0,#0FFH
SETB WEI
MOV P0,#07FH
CLR WEI
MOV P0,#0FFH
SETB DUAN
MOV DPTR,#LEDTAB
MOV A,47H
MOVC A,@A+DPTR
MOV P0,A
CLR DUAN
MOV R7,#5
LCALL DELAY
RET
LEDTAB:
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
很好写的
显示加判断
org 00h
main:
mov p1,#00h
mov r1,#00h
a1:call dis
jb p3.2, j1
jb p3.3,j2
jb p3.4,j3
jmp a1
dis:
mov a,r1
mov b,#10
div ab
mov p1,a
setb p2.0
call yanshi
mov p1,b
clr p2.0
call yanshi
ret
ji:call yanshi
jnb p3.2,a1
inc r1
ret
j2:call yanshi
jnb p3.3,a1
inc r1
inc r1
ret
j3:call yanshi
jnb p3.4,a1
subb r1 ,#01h
ret
yanshi :
延时自己写好了
ret
end
这个程序 起始也就是 3个按键控制 +1 +2+ 3 1个按键控制 红方蓝方的电路 很简单
#includereg51.h
#includeintrins.h
#define uchar unsigned char
#define uint unsigned int
// 段码
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
// 待显示的6位缓冲
uchar Num_Buffer[]={0,0,0,0,0,0};
// 按键代码,按键计数
uchar Key_Code,Key_Counts1=0; Key_Counts2=0;//1 2分别是红 蓝方
// 延时
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i120;i++);
}
// 显示函数
void Show_Counts_ON_DSY()
{
uchar i,j=0x01;
Num_Buffer[2]=Key_Counts1/100;
Num_Buffer[1]=Key_Counts1/10%10;
Num_Buffer[0]=Key_Counts1%10;
Num_Buffer[5]=Key_Counts1/100;
Num_Buffer[4]=Key_Counts1/10%10;
Num_Buffer[3]=Key_Counts1%10;
for(i=0;i6;i++)
{
j=_cror_(j,1);
P0=0xff;
P0=DSY_CODE[Num_Buffer[i]];
P2=j;
DelayMS(1);
}
}
// 主程序
void main()
{
uchar i;
P0=0xff;
P1=0xff;
P2=0x00;
Key_Code=0xff;
while(1)
{
Show_Counts_ON_DSY();
P1=0xff;
Key_Code=P1;
//有键按下时,数码管刷新显示 30 次,该行代码同时起到延时作用
if(Key_Code!=0xff)
for(i=0;i30;i++) Show_Counts_ON_DSY();
switch(Key_Code)
{
case 0xfe: if(color==1)Key_Counts1++; else Key_Counts2++; //左边加1还是右边加1
break;
case 0xfd: Key_Counts1=Key_Counts1+2; else Key_Counts2=Key_Counts2+2;
break;
case 0xfb: Key_Counts=Key_Counts1+3; else Key_Counts2=Key_Counts2+3;
case 0xf7; color=!color;//左边还是右边
}
Key_Code=0xff;
}
//P1接数码官段码 P2接片选
这是一个数码管显示的篮球计分程序,你可以参考一下:
#include"reg52.h"
#define u8 unsigned char
#define u16 unsigned int
sbit UP_1 = P1^1; //第一队加分键
sbit DOWN_1 = P1^2; //第一队减分键
sbit UP_2 = P1^3; //第二队加分键
sbit DOWN_2 = P1^4; //第二队减分键
sbit Change = P1^5; //交换键
sbit Begin = P1^6; //开始键
sbit Pause = P1^7; //暂停键
sbit Beef = P2^4; //蜂鸣器
sbit duan = P2^3; //段选
sbit wei = P2^2; //位选
u8 Grate_1=0; //第一队计分
u8 Grate_2=0; //第二队计分
u8 Grate_change=0; //换场标志
u8 Time = 99; //总时间
u16 Flag=0; //计时次数
u8 leddata[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
};
void InitTimer1(void)
{
TMOD = 0x10; //定时器1设为模式1
TH1 = 0xFC;
TL1 = 0x18; //1ms
EA = 1; //开总中断
ET1 = 1; //开定时器1中断
// TR1 = 1; //
}
void delay(u8 d) //延时
{
u8 a,b,c;
for(c=d;c0;c--)
for(b=17;b0;b--)
for(a=16;a0;a--);
}
void beef(u8 d) //发声
{
u8 a,b,c;
for(c=d;c0;c--)
for(b=17;b0;b--)
for(a=16;a0;a--)
{
Beef=~Beef;
}
}
void display(u8 grate_1,u8 grate_2,u8 time) //显示
{
u8 w1,w2,w3,w4,w7,w8;
w1=grate_1/10; //计算第一队分数十位
w2=grate_1%10; //计算第一队分数个位
w3=grate_2/10; //计算第二队分数十位
w4=grate_2%10; //计算第二队分数个位
w7=time/10; //计算时间十位
w8=time%10; //计算时间个位
P0=0xff; //消隐,该段显示第一队分数十位
wei=1;
P0=0xfe; //送位码
wei=0;
P0=0xff;
duan=1;
P0=leddata[w1]; //送段码
duan=0;
delay(5);
P0=0xff; //显示第一队分数个位
wei=1;
P0=0xfd;
wei=0;
P0=0xff;
duan=1;
P0=leddata[w2];
duan=0;
delay(5);
P0=0xff; //显示第二队分数十位
wei=1;
P0=0xf7;
wei=0;
P0=0xff;
duan=1;
P0=leddata[w3];
duan=0;
delay(5);
P0=0xff; //显示第二队分数个位
wei=1;
P0=0xef;
wei=0;
P0=0xff;
duan=1;
P0=leddata[w4];
duan=0;
delay(5);
P0=0xff; //显示时间十位
wei=1;
P0=0xbf;
wei=0;
P0=0xff;
duan=1;
P0=leddata[w7];
duan=0;
delay(5);
P0=0xff; //显示时间个位
wei=1;
P0=0x7f;
wei=0;
P0=0xff;
duan=1;
P0=leddata[w8];
duan=0;
delay(5);
}
void main()
{
InitTimer1(); //初始化定时器1
UP_1 = 1; //以下初始化IO口
DOWN_1 = 1;
UP_2 = 1;
DOWN_2 = 1;
Change = 1;
Begin = 1;
while(1)
{
if(UP_1==0) //如果第一队加分键按下
{
ET1 = 0; //关闭定时器1中断
delay(5); //稍加延时
while(UP_1==0);//等待按键抬起
Grate_1++; //第一队分数加1
ET1 = 1; //开启定时器1中断
}
if(DOWN_1==0) //如果第一队减分键按下
{
ET1 = 0;
delay(5);
while(DOWN_1==0);
Grate_1--; //第一队分数减1
ET1 = 1;
}
if(UP_2==0) //如果第二队加分键按下
{
ET1 = 0;
delay(5);
while(UP_2==0);
Grate_2++; //第二队分数加1
ET1 = 1;
}
if(DOWN_2==0) //如果第二队减分键按下
{
ET1 = 0;
delay(5);
while(DOWN_2==0);
Grate_2--; //第二队分数减1
ET1 = 1;
}
if(Change==0) //如果换场键按下
{
ET1 = 0;
delay(5);
while(Change==0);
Grate_change=Grate_1; //一下三行语句完成分数交换显示
Grate_1=Grate_2;
Grate_2=Grate_change;
ET1 = 1;
}
if(Begin==0) //如果开始键按下
{
delay(5);
while(Begin==0);
TR1 = 1; //开启定时器1
}
if(Pause==0)
{
delay(5);
while(Pause==0);
TR1=0;
}
if(Time=0) //如果时间计数到0
{
Time=99; //恢复初始时间
TR1 = 0; //关闭定时器1
beef(100); //发声
}
display(Grate_1,Grate_2,Time); //显示分数、时间
}
}
void Timer1Interrupt(void) interrupt 3 //定时器1中断函数
{
TH1 = 0xFC; //重赋初值
TL1 = 0x18;
Flag++; //中断次数加1
if(Flag=1000)//1000次也就是1秒到
{
Flag=0;
Time--; //秒变量减1
}
}
单片机篮球比赛计分器程序的介绍就聊到这里吧,感谢您花时间阅读,谢谢。
本文标签:单片机篮球比赛计分器程序