⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock.c

📁 51C程序的电子钟
💻 C
字号:
/////////// 完整 
#include<absacc.h>
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define COM8155 XBYTE[0x8000]
#define PA8155  XBYTE[0x8001]
#define PB8155  XBYTE[0x8002]
#define PC8155  XBYTE[0x8003]

//全局变量
uint dis[6];
uint date[3]={84,29,11};	//年,日,月
uint time[3]={23,59,50};	//时,秒,分
uint alarm[3]={6,160,30};	//时,开关,分
uint stop_w[3]={0,0,0};		//分,毫秒,秒
uint counter=20;
bit  O_DOT;
bit  DOT;
bit leap;		//闰年标志
bit alarm1;
uint set;
uint *exch;            //交换显示指针
sbit buzzer=P1^3;
uint st[21]={0xc0,0xf9,0xa4,0xb0,
              0x99,0x92,0x82,0xf8,
              0x80,0x90,0x88,0x83,
              0xc6,0xa1,0x86,0x8e,
              0xff,0xc,0x89,0x7f,0xbf};         // 字型码

//判键显示子程序
void process(uint key_vl);
void delay(uint i);
uint scan(void);
uint f_key(void);
void display(void);
void dvid(uint *p);
void timer(void);
void fun(uint set);
void time_m(void);
void data_m(void);
void leap_y(void);
uint dpm(void);       //每月天数判断
void arm_c(void);
/// 定时器0 用于计时/////////
void timer0() interrupt 1 using 1
{
  TH0=0x3C;
  TL0=0xB;
  counter=counter-1;
  if(counter==0)
  {
    counter=20;
    timer();
    DOT=!DOT;
  }
}
/// 中断1 用于秒表/////////
void timer1() interrupt 3 using 2
{
  if(stop_w[1]==99)
  {
   stop_w[1]=0;
   if(stop_w[2]==59)
   {
    stop_w[2]=0;
    stop_w[0]=stop_w[0]+1;
   }
   else
    stop_w[2]=stop_w[2]+1;
  }
  else
    stop_w[1]=stop_w[1]+1;

}
//////////     主函数  ////////////

void main()
{
  uint i;
  uint idata key_vl=0xff;
  O_DOT=1;
  DOT=1;
  alarm1='0';
  for(i=0;i<6;i++)
   dis[i]=0;		////初始化显示缓冲区

  COM8155=0x3;          // 初始化LED
  exch=time;
  set=0;
  EA=1;
  TMOD=0x1;
  TH0=0x3C;
  TL0=0xB;
  ET0=1;
  TR0=1;		// 定时器 0

  TH1=0xd8;
  TL1=0xf;
  ET1=1;
  TR1='0';		//定时器 1
  delay(200);

  while(1)
  {
   arm_c();
   key_vl=scan();
   process(key_vl);
   dvid(exch);
   display();
  }
}
///  键处理 ////////
void process(uint key_vl)
{
  switch(key_vl)
  {
   case 0xff:
          break;
   case 12:
           set=set+1;
           if(set==4)
            set=0;
           switch(set)
           {
             case 0: exch=time;break;
             case 1: exch=date;break;
             case 2: exch=stop_w;break;
             case 3: exch=alarm;break;
             default: break;
            }
            break;
   case 10:
           fun(set); break;
   default:
           break;
  }
}

/////  走时程序 //////////
void timer(void)            //time[3] 时0 秒1 分2  nian ri yue
{
  if(time[1]==59)
  {
   time[1]=0;
   if(time[2]==59)
   {
    time[2]=0;
    if(time[0]==23)
    {
      time[0]=0;
      if(date[1]==dpm())
      {
       date[1]=1;
       if(date[2]==12)
       {
	 date[2]=1;
         date[0]=date[0]+1;
       }
       else
         date[2]=date[2]+1;
      }
      else
       date[1]=date[1]+1;
     }
    else
     time[0]=time[0]+1;
   }
   else
    time[2]=time[2]+1;
  }
  else
    time[1]=time[1]+1;
}
///////   延时    //////////

void delay(uint i)           //延时ims
{
  uint x,y;
  for(x=i;x>0;x--)
   for(y=124;y>0;y--)
   ;
}
///////// 判键  ////////////////

uint scan(void)
{
  uint idata i=0;
  PA8155=i;
  i=PC8155&7;
  //i=i&0x7;
  if(i==0x7)
    i=0xff;
   else
    i=f_key();
   return i;
}
//////// 求键值   ////////////////
uint f_key(void)
{
   uint idata i=1;
   uint lx,rx;
   delay(10);		//去抖动
   switch(PC8155&7)
   {
    case 3: rx=3;break;
    case 5: rx=2;break;
    case 6: rx=1;break;
   }
   while(1)
   {
     PA8155=i;
     lx=PC8155&7;
     if(lx==7)
	break;
     i=i<<1;
   }
   switch(i)
   {
     case 8: lx=3;break;
     case 4: lx=2;break;
     case 2: lx=1;break;
     case 1: lx=0;break;
   }
   i=rx+lx*3;
   if(i==11)
    i=0;
   while(1)
   {
     display();
     lx=PC8155&7;
     if(lx==7)
	break;
   }
   return i;
}
////////// 显示 //////////////
void display(void)
{
  uint j,n,k=0;
  uint i=0x20;
 for(n=0;n<6;n++)
 {
  PA8155=i;
  j=st[dis[k]];
  if(k==0)
   if(O_DOT==1)
    if(DOT==1)
      j=j^0x80;
  PB8155=j;
  delay(1);
  PB8155=0xff;
  i=i>>1;
  k=k+1;
 }
}
//////  分解传送 /////////
void dvid(uint *p)
{
   uint k;
  for(k=0;k<6;k=k+2)
  {
    dis[k]=*p%10;
    dis[k+1]=*p/10;
    p=p+1;
  }
}
//// 闰年判断 /////////
void leap_y(void)
{
  if(date[0]%4==0)
   leap=1;
  else
   leap='0';
}
//// 每月天判断/////////
uint dpm(void)
{
 uint i;
 leap_y();
 switch(date[2])
 {
   case 1:
   case 3:
   case 5:
   case 7:
   case 8:
   case 10:
   case 12:
       i=31;break;
   case 2:
       if(leap==1)
	i=29;
       else
	i=28;
       break;
  default:
	i=30;break;
 }
 return i;
}
//// 修改函数/////////
void fun(uint set)
{
  uint i;
  switch(set)
  {
    case 0:		// 时间
	time[1]=0;
	time_m();
	break;
    case 1:		// 日期
	O_DOT='0';
	data_m();
	O_DOT=1;
	break;
    case 3:		// 闹钟
	O_DOT='0';
	while(1)
	{
	  dvid(exch);
	  display();
	  i=scan();
	  if(i==10)
	  {
	    alarm1=!alarm1;
	    break;
	  }
	 }
	if(alarm1==1)
	  alarm[1]=161;
	else
	  alarm[1]=160;
	while(1)
	{
	  dvid(exch);
	  display();
	  i=scan();
	  if(i==12)
	  {
	     time_m();
	     break;
	  }
	}
	O_DOT=1;
	break;
    case 2:		// 秒表
          while(1)
          {
            dvid(exch);
            display();
            i=scan();
            if(i==10)          
              TR1=1;
            if(i==12)
              TR1='0';
            if(TR1=='0')
             if(i==0)
             {
              stop_w[0]=stop_w[1]=stop_w[2]=0;
              break;
             }
          }
          break;
   }
}
void time_m(void)
{
  uint i;
  O_DOT='0';
  if(set==0)
   dis[2]=dis[3]=0;   //秒清零
  dis[1]=0;
  while(1)
  {
    display();
    i=scan();
    if(i<3)
     dis[1]=i;
    if(i==12)
     break;
   }                    // 时高位修改
  dis[0]=0;
  while(1)
  {
    display();
    i=scan();
    if(dis[1]==2)
    {
      if(i<4)
	dis[0]=i;
      else
       if(i==12)
         break;
    }
    else
     if(i==12)
       break;
     else
       if(i<10)
	 dis[0]=i;
  }			// 时低位修改
  if(set==0)
    time[0]=dis[1]*10+dis[0];
  else
    alarm[0]=dis[1]*10+dis[0];
  dis[5]=0;
  while(1)
  {
    display();
    i=scan();
    if(i<6)
      dis[5]=i;
    if(i==12)
      break;
  }			// 分高位修改
  dis[4]=0;
  while(1)
  {
    display();
    i=scan();
    if(i==12)
	break;
    else
      if(i<10)
	dis[4]=i;
  }			//分低位修改
  if(set==0)
  {
    time[2]=dis[5]*10+dis[4];
    time[1]=0;    //秒位清零
  }
  else
    alarm[2]=dis[5]*10+dis[4];
  O_DOT=1;
}
//////////  日期修改子函数 ///////////
void data_m(void)
{
  uint i;
  dis[1]=0;
  while(1)
  {
    display();
    i=scan();
    if(i<10)
      dis[1]=i;
    if(i==12)
      break;
   }                    // 年高位修改
  dis[0]=0;
  while(1)
  {
    display();
    i=scan();
    if(i<10)
      dis[0]=i;
    if(i==12)
      break;
  }			// 年低位修改
  date[0]=dis[1]*10+dis[0];
  dis[5]=0;
  while(1)
  {
    display();
    i=scan();
    if(i<2)
      dis[5]=i;
    if(i==12)
      break;
  }			// 月高位修改
  dis[4]=0;
  while(1)
  {
    display();
    i=scan();
    if(dis[5]==0)
    {
      if(i<10)
        dis[4]=i;
      if(i==12)
        break;
    }
    else
    {
      if(i<3)
        dis[4]=i;
      if(i==12)
        break;
    }
  }			//月低位修改
  date[2]=dis[5]*10+dis[4];
  dis[3]=0;
  while(1)
  {
    display();
    i=scan();
    if(date[2]==2)        // 2月
    {
     if(i<3)
       dis[3]=i;
     if(i==12)
       break;
    }
    else
    {
     if(i<4)
       dis[3]=i;
     if(i==12)
       break;
    }
  }			// 日高位修改
  dis[2]=0;
  while(1)
  {
    i=dpm();
    display();
    i=scan();
    if(i==12)
	break;
    else
	if((dis[3]*10+i)<=dpm())
	  dis[2]=i;
  }   			// 日低位修改
  date[1]=dis[3]*10+dis[2];
}
////////// 闹钟 /////////////
void arm_c()
{
  if(alarm[1]==161)
  {
    if(time[0]==alarm[0]&&time[2]==alarm[2])
    {
        buzzer='0';
        if(scan()!=0xff)
            alarm[1]=160;
    }
  }
  else
    buzzer=1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -