51单片机 下棋对弈计时报警器 protues仿真
程序如下:
/* 甲乙对奕方的计时器共用一个180秒时钟,双方均用3位数码显示,预定的初值均为三分钟,
采用倒计时方式,通过按扭启动,由本方控制对方,比如甲方走完一步棋后必须按一次甲方的按键,
该按键启动乙方倒计时。同理,乙方走完一步棋后必须按一次乙方的按键,该按键启动甲方倒计时 */
//硬件端口连接 数码管段码P0位码选择P22 P23 P24
//按键2个 红方按键和黑方按键
//修改为一局共3分钟,红方先走棋,黑方按下后红方走棋,并倒计时,红方按下后,红方时间停止,黑方走棋,并倒计时
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
/****共阳数码管0--9段码****/
uchar code tab[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,};
uchar a[6];//数码管显示
uchar b[6]={0xFB,0XF7,0XEF,0XDF,0XBF,0X7F};//数码管位码
/****子函数声明****/
void key(void);//按键函数
void shumaguan(void);//数码管显示函数
void shumaguan1(void);//数码管显示函数
void smg();
void chuli();
void delay_ms(uint z);//带参数ms级延时子函数
void init();//初始化函数
void display();//显示函数
/****变量定义****/
uchar shu; //倒计时变量
uchar shu1;
uchar num;//定时器T0计时变量
uchar num1;//定时器T1计时变量
uchar flag;//标志位红方走棋
uchar flag1; //标志位黑方走棋
uchar k;
uchar temp;
uchar temp1;
/****位定义****/
sbit key1=P3^2;//红方确认键
sbit key2=P3^3;//黑方确认键
sbit key4=P3^5; //复位键
sbit led0=P1^0; //红方走棋指示灯
sbit led1=P1^7; //黑方走棋指示灯
sbit beep=P3^6; //蜂鸣器
void main(void)
{
init();
while(1)
{
key();
chuli();
display();
}
}
void display()
{
switch(flag)
{
case 0:
{
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;
case 1: //红方走棋
{
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;
case 2: //黑方走棋
{
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;//消影
}
}
void chuli()
{
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中
}
}
}
void key(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);
}
}
/*
void smg()
{
for(k=0;k<6;k++)
{
P2=b[k]; //送位码
P0=a[k]; //送段码
delay_ms(2);
P2=0xff;//消影
}
}
*/
/*
void shumaguan(void) //红方走时
{
uchar bai,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);
}
void shumaguan1(void) //黑方走时
{
uchar bai1,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);
}
*/
void delay_ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void init()
{
shu=180;//倒计时3分钟的初值
shu1=180;
beep=0;//关闭蜂鸣器
TMOD=0X11;//定时器T0 T1 方式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
}
void time0() interrupt 1
{
TH0=(65536-50000)/256;//重装初值
TL0=(65536-50000)%256;
num++;
}
void time1() interrupt 3
{
TH1=(65536-50000)/256;//重装初值
TL1=(65536-50000)%256;
num1++;
}