void delay(int t) 调用该子程序能实现延时功能
{ 通过参数t,可以调成延时时间
while(t--)
{
unsigned int i; 设置变量i的变化范围,能调整延时的单位时间
for(i=0;i<200;i++); 长度,i越小,延时的单位时间越短,精度越高
}
}
3.2.2 数码管动态刷新显示程序
void display(int i,int j,int x,int y) 变量i,j,x,y分别为分,秒,A分数,B分数
{
if(jie==1&&bujin!=2) 当中间变量jie==1时,为上半场,此时对P1赋值
P1=0xbf; 使P1=0xbf, 即P1=1011 1111B,上半场指示灯对应点亮
P2=0xfe; 数码管动态刷新显示程序 P2=1111 1110, i为分钟
P0=seg[i%100/10]; P2=0xfe,所以刷新显示时间的分钟十位,调用延时程序,
delay(1); 延时数码管的点亮
P2=0xff;
P0=0;
P2=0xfd; 同理,动态刷新时分钟个位并延时点亮
P0=seg[i%10];
delay(1);
P2=0xff;
P0=0;
P2=0xfb; 同理,动态刷新时秒钟十位并延时点亮
P0=seg[j%100/10];
delay(1);
P0=0;
P2=0xff;
P2=0xf7; 同理,动态刷新时秒钟个位并延时点亮
P0=seg[j%10];
delay(1);
P0=0;
P2=0xff;
P2=0xef; 同理,动态刷新A分数十位并延时点亮
P0=seg[x%100/10];
delay(1);
P2=0xff;
P0=0;
P2=0xdf; 同理,动态刷新A分数个位并延时点亮
P0=seg[x%10];
delay(1);
P2=0xff;
P0=0;
P2=0xbf; 同理,动态刷新B分数十位并延时点亮
P0=seg[y%100/10];
delay(1);
P0=0;
P2=0xff;
P2=0x7f; 同理,动态刷新B分数十位并延时点亮
P0=seg[y%10];
delay(1);
P0=0;
P2=0xff;
}
本设计中各个数码管采用动态驱动,使各位数码管逐个轮流受控显示,由于扫描速度极快(本实验中大约每20毫秒刷新一次),所以显示效果与静态驱动相同。
3.2.3 T0中断程序
void t0(void) interrupt 1 本设计调用定时器T0,计时单位为一秒
{
TH0=0xb1; 对定时器T0送入计数初值,由于TH0=0xb;
TL0=0x10; TL0=0x10 故定时器定时为20毫秒,即每
if(n==0) 20毫秒调用一次void t0(void) interrupt 1
{
n=60;
m--;
}
i++;
if(i==50)
{ 令i值为50 50*20毫秒=1秒,来实现计时
n--; 单位为一秒
i=0;
}
display(m,n-1,x,y); 调用动态刷新显示程序,即每20毫秒刷新一
} 次数码管
3.2.4 加分子程序
void keyjiafen1()
{ 当检测到RXD按键按下时,调用延时子程序 if(RXD==0) 实现消除按键抖动功能,即,当
delay(1);,
{ 检测到按键按下时候,延时,按键仍按下,说明
if(RXD==0) 按键确实按下,非抖动,A对应加分
{
while(RXD==0);
x++;
}
}
if(TXD==0) 检测TXD加分按键时候按下,B加分
{
delay(1);
if(TXD==0)
{
while(TXD==0);
y++;
}
}
}
3.2.5减分子程序
void keyjianfen1() 减分按键检测子程序,其基本算法及功能与加分
{ 相同
if(WR==0)
{
delay(1);
if(WR==0)
{
while(WR==0);
x--;
}
}
if(RD==0)
{
delay(1);
if(RD==0)
{
while(RD==0);
y--;
}
}
}
3.2.6 调整时间子程序
调整时间子程序,使时间快速倒退或快进,实现回表功能,同时回表之后能自动暂停
void key2()
{
if(INT0==0)
{
delay(10);
if(INT0==0) 回表子程序,检测到INT0按下时,使时间回倒
{
chuzanting==0; chuzanting==0; zanting=1;为附加变量,当回表按键
zanting=1; 松开时,表暂停,这两个变量用来调用暂停
n++;
if(n==60)
{
m++;
n=1;
}
}
}
if(INT1==0) 快表子程序,检测到INT1按下时,使倒计加快,
{ 通常情况下与回表子程序配合使用,即当回表
回过的时候,按此键调整时间
delay(10); chuzanting==0; zanting=1;作用同上
if(INT1==0)
{
chuzanting==0;
zanting=1;
n--;
}
}
}
void shijian() 该程序使回表和快表按键松开时候能自动暂停
{
if(zanting==1&&INT0==1&&INT1==1&&chuzanting==0 )
{
EA=0; zanting==1&&INT0==1&&INT1==1&&chuzanting==0作用为
zanting=0; 当按键松开的时候,调用暂停程序条件
huzanting=0; zanting=0;chuzanting=0,初始化,以便下次回表和快表 while(1) 按键松开时候仍能调用暂停程序
{
display(m,n,x,y);
if(P1_0==0) 当检测暂停键按下,开中断,跳出暂停
{
delay(1);
if(P1_0==0)
{
while(P1_0==0);
EA=1;
break;
}
}
}
}
}
3.2.7 半场交换比分子程序
void key3()
{
int temp; 定义中间变量temp,检测到有按键按下时候
if(zidong==1&&jie==1) 通过temp交换甲队,乙队两队比赛分数
{
temp=x; zidong==1&&jie==1是判断半场的条件
y=temp;
display(m,n,x,y); 刷新数码管
zidong=0;
bujin=0;
}
}
3.2.8 比赛暂停子程序
void key4()
{
if(P1_0==0) 检测到暂停按键按下时候,令EA=0关闭中断
{
delay(1); 同通过死循环程序while(1),不断刷新数码管
if(P1_0==0) 当暂停键再次按下时候,开中断,以使比赛时间
{ 继续倒计时,由于在暂停的时候,程序处于死循
while(P1_0==0);
EA=0; 无法回到主程序,暂停时,除了暂停键
while(1) 其他按键按下均无效
{
display(m,n,x,y);
if(P1_0==0)
{ 当暂停键再次按下时候,EA=1开中断,计时数码管
delay(1); 继续倒计时,同时通过break语句,跳出死循环
if(P1_0==0)
{
while(P1_0==0);
EA=1;
break;
}
}
}
}
}
}
3.2.9 中场指示灯程序
void over()
{
if((m==0)&&(n==0)) 当m,n均为0的时候,通过变量jie的值判断比赛
{ 是否结束
if(jie>1) 如果jie>1,说明半场到了,比赛没有结束,
{ 令m=2,n=0,关中断,再次按下暂停键时候继续倒计时
m=2; 同是T1=1;delay(400) ; delay(400);,是蜂鸣器
n=0; 发声报警
EA=0;
T1=1;
delay(400);
T1=0;
while(1)
{
display(m,n,x,y); 刷新数码管,等待暂停减再次按下,跳出暂停
if(P1_0==0)
{
delay(1);
if(P1_0==0)
{
while(P1_0==0);
EA=1;
break;
}
}
}
jie--;
}
if(jie==1&&bujin==2) 如果jie==1&&bujin==2,说明比赛结束了, { 关闭中断,比赛秒表不再走动,同时不短刷新数码管, EA=0;
m=0;
n=0;
T1=1; 全场比赛结束蜂鸣器开始报警
delay(400);
T1=0;
P1=0x3f; P1=0x3f上下半场指示灯同时点亮,比赛结束 while(1)
display(m,n,x,y); 同时应当不断刷新数码管
}
}
}
3.2.10 主程序
void main()
{ TMOD=0x01; 首先设置定时器工作方式
EA=1;
ET0=1;
TH0=0xb1; 定时器送计数初值,EA=1,开中断,P3口电平拉高
TL0=0x10; P1=0x7f, 上半场指示灯点亮
TR0=1; TR0=1启动定时器
P3=0xff;
P1=0x7f;
T1=0;
while(1) 主程序通过 while(1),反复调用循环体内的子程序
{ 来执行相应的功能
keyjiafen1();
keyjianfen1();
key2();
if(zidong==1) zidong==1为key3()执行条件
key3(); key3()半场交换场地时自动交换双方
if(n==18&&bujin==0) 比赛分数子程序,所以仅当中场时调用
{
bujin=2; 修改变量bujin的值,目的是设定over()
} 中第二个if语句的执行条件
shijian();
key4();
over();
}
}