protues原理图如下
程序如下:
/*甲乙对奕方的计时器共用一个180秒时钟,双方均用3位数码显示,预定的初值均为三分钟,
采用倒计时方式,通过按扭启动,由本方控制对方,比如甲方走完一步棋后必须按一次甲方的按键,
该按键启动乙方倒计时。同理,乙方走完一步棋后必须按一次乙方的按键,该按键启动甲方倒计时*/
//硬件端口连接数码管段码P0位码选择P22P23P24
//按键2个红方按键和黑方按键
//修改为一局共3分钟,红方先走棋,黑方按下后红方走棋,并倒计时,红方按下后,红方时间停止,黑方走棋,并倒计时
#include<reg52.h>
#defineuintunsignedint
#defineucharunsignedchar
/****共阳数码管0--9段码****/
ucharcodetab[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,};
uchara[6];//数码管显示
ucharb[6]={0xFB,0XF7,0XEF,0XDF,0XBF,0X7F};//数码管位码
/****子函数声明****/
voidkey(void);//按键函数
voidshumaguan(void);//数码管显示函数
voidshumaguan1(void);//数码管显示函数
voidsmg();
voidchuli();
voiddelay_ms(uintz);//带参数ms级延时子函数
voidinit();//初始化函数
voiddisplay();//显示函数
/****变量定义****/
ucharshu;//倒计时变量
ucharshu1;
ucharnum;//定时器T0计时变量
ucharnum1;//定时器T1计时变量
ucharflag;//标志位红方走棋
ucharflag1;//标志位黑方走棋
uchark;
uchartemp;
uchartemp1;
/****位定义****/
sbitkey1=P3^2;//红方确认键
sbitkey2=P3^3;//黑方确认键
sbitkey4=P3^5;//复位键
sbitled0=P1^0;//红方走棋指示灯
sbitled1=P1^7;//黑方走棋指示灯
sbitbeep=P3^6;//蜂鸣器
voidmain(void)
{
init();
while(1)
{
key();
chuli();
display();
}
}
voiddisplay()
{
switch(flag)
{
case0:
{
a[5]=tab[shu1/100];
a[4]=tab[shu1%100/10];
a[3]=tab[shu1%10];
a[2]=tab[shu/100];
a[1]=tab[shu%100/10];
a[0]=tab[shu%10];
}
break;
case1://红方走棋
{
a[5]=tab[shu1/100];
a[4]=tab[shu1%100/10];
a[3]=tab[shu1%10];
a[2]=tab[shu/100];
a[1]=tab[shu%100/10];
a[0]=tab[shu%10];
}
break;
case2://黑方走棋
{
a[5]=tab[shu1/100];
a[4]=tab[shu1%100/10];
a[3]=tab[shu1%10];
a[2]=tab[shu/100];
a[1]=tab[shu%100/10];
a[0]=tab[shu%10];
}
break;
}
for(k=0;k<6;k++)
{
P2=b[k];//送位码
P0=a[k];//送段码
delay_ms(10);
P2=0xff;//消影
}
}
voidchuli()
{
if(flag==1)//进入红方走棋模式
{
TR0=1;//启动定时器T0
TR1=0;
if(num==20)//1秒时间到时间减1
{
num=0;
shu=shu-1;
}
if(flag==2)
{
TR0=0;//关闭定时器T0
//temp=shu;//把数值保留在temp中
}
}
if(flag==2)
{
TR0=0;//启动定时器T1
TR1=1;
if(num1==20)//1秒时间到时间减1
{
num1=0;
shu1=shu1-1;
}
if(flag==1)
{
TR1=0;//关闭定时器T1
//temp1=shu1;//把数值保留在temp1中
}
}
}
voidkey(void)
{
if(key2==0)//黑方确认键按下红方走
{
delay_ms(5);
if(key2==0)
{
flag=1;
flag1=0;
}
while(!key2);
}
if(key1==0)//红方确认键按下黑方走
{
delay_ms(5);
if(key1==0)
{
flag1=1;
flag=0;
}
while(!key1);
}
if(key4==0)//复位键按下
{
delay_ms(5);
if(key4==0)//确认开始键按下
{
beep=0;//关闭蜂鸣器
flag=4;
}
while(!key4);
}
}
/*
voidsmg()
{
for(k=0;k<6;k++)
{
P2=b[k];//送位码
P0=a[k];//送段码
delay_ms(2);
P2=0xff;//消影
}
}
*/
/*
voidshumaguan(void)//红方走时
{
ucharbai,shi,ge;//数码管显示的百位十位和各位
bai=shu/100;//百位数的分离用于S2数码管的显示
shi=shu%100/10;
ge=shu%10;
P2=0XEF;//选择S2数码管的段码
P0=tab[bai];
delay_ms(5);
P2=0XF7;//选择S1数码管的段码
P0=tab[shi];
delay_ms(5);
P2=0XFB;//选择S0数码管的段码
P0=tab[ge];
delay_ms(5);
}
voidshumaguan1(void)//黑方走时
{
ucharbai1,shi1,ge1;//数码管显示的百位十位和各位
bai1=shu1/100;//百位数的分离用于S2数码管的显示
shi1=shu1%100/10;
ge1=shu1%10;
P2=0X7F;//选择S2数码管的段码
P0=tab[bai1];
delay_ms(5);
P2=0XBF;//选择S1数码管的段码
P0=tab[shi1];
delay_ms(5);
P2=0XDF;//选择S0数码管的段码
P0=tab[ge1];
delay_ms(5);
}
*/
voiddelay_ms(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidinit()
{
shu=180;//倒计时3分钟的初值
shu1=180;
beep=0;//关闭蜂鸣器
TMOD=0X11;//定时器T0T1方式1
TH0=(65536-50000)/256;//50ms装初值
TL0=(65536-50000)%256;
TH1=(65536-50000)/256;//50ms装初值
TL1=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//开启定时器T0
ET1=1;//开启定时器T1
}
voidtime0()interrupt1
{
TH0=(65536-50000)/256;//重装初值
TL0=(65536-50000)%256;
num++;
}
voidtime1()interrupt3
{
TH1=(65536-50000)/256;//重装初值
TL1=(65536-50000)%256;
num1++;
}