51单片机 下棋对弈计时报警器 protues仿真

2025-09-28 05:34:17

protues原理图如下

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++;

}

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢