天天看点

51单片机电子时钟

展示代码

需要看仿真图的

可以到微信公众号“伊斯电子编程”去查看仿真图。

#include<reg52.h>
#include<intrins.h>
​
#define uint unsigned int
#define uchar unsigned char
 
#define KEY_MENU 0x01
#define KEY_UP 0x02
#define KEY_DOWN 0x03
#define KEY_CLK 0x04
#define KEY_OK 0x05
#define KEY_CANCLE 0x06
​
uint hour,minute,sec,t;
uchar code tabdu[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};/*共阳极数码管编码从0到F*/
uchar code tabwe[]={0x01,0x02,0x04,0x08};/*数码管位选编码,当P0为tablewe[0]时表示第一位数码管亮,其他五个不亮*/
uint n[4];
uchar tiao,ctiao; //分别控制调时的时候时分秒跳动,跳动的频率,闹钟控制位
uchar clkh=24,clkm,clks;//闹钟的定时时间 时、分、秒
uchar hour1,min1,sec1;
​
bit CLK,STOPCLK;
bit CONTIME;
bit flag;
​
//sbit dula=P2^6;    //段选控制位
//sbit wela=P2^7;    //位选控制位
sbit key_menu=P1^1;
sbit key_up=P1^2;
sbit key_down=P1^3;
sbit key_clk=P1^4;
sbit feng=P3^1;
sbit led=P3^0;
void delay(uint n)   //延时函数
{
  uint i,j;
  for(i=n;i>0;i--)
    for(j=40;j>0;j--);
}
void getval()     //将时分秒的各位数据存放到数组n中
{
  if(CLK)    //如果在设置闹钟,则数码管显示相应数字而不是去显示时间
  {
    n[0]=clkh/10;
    n[1]=clkh%10;
    n[2]=clkm/10;
    n[3]=clkm%10;
    return;  
  }
  if(CONTIME)
  {
    n[0]=hour1/10;
    n[1]=hour1%10;
    n[2]=min1/10;
    n[3]=min1%10;
    return;
  }
  n[0]=hour/10;
  n[1]=hour%10;
  n[2]=minute/10;
  n[3]=minute%10;
}
void clock()//闹钟处理函数
{
  if(clkh==hour&&clkm==minute&&STOPCLK)
    feng=0;
  else
    feng=1;
}
void baoshi()//整点报时
{
  if(minute==0&&sec==0)
    feng=0;
  else
    feng=1;
}
uchar Get_Key()     //如果有键按下则返回想应的值
{     
  uchar val=0;
  P1=0xff;
  delay(2);
  val=P1;
  if(val!=0xff)
  {
    delay(20);
    while(P1!=0xff);
  }
  switch(val)
  {
    case 0xfd:return KEY_MENU;break;
    case 0xfb:return KEY_UP;break;
    case 0xf7:return KEY_DOWN;break;
    case 0xef:return KEY_CLK;break;
    case 0xdf:return KEY_OK;break;
    case 0xbf:return KEY_CANCLE;break;
    default:return 0;
  }
}
void Key_val(uchar key1)//处理按键
{
  static uchar key=0;
  uchar keyval;
  keyval=key1;
  if(flag==0)    
  {
    hour1=hour;
    min1=minute;
    sec1=sec;
  }
  switch(keyval)
  {
    case KEY_MENU : if(CLK==0)
            {CONTIME=flag=1;key=(++key)%3;tiao=key;if(key==0) tiao=key=1;}
            else 
            {key=++key%3;tiao=key;if(key==0) key=tiao=1;}
            break;
    case KEY_UP :if(CLK==0)
           {    switch(key)
              {
          
              case 1:min1++;if(min1==60) min1=0;break;
              case 2:hour1++;if(hour1==24) hour1=0;break;
              default:break;
               }
             }
             else
             {
               switch(key)
               {
        
              case 1:clkm++;if(clkm==60) clkm=0;break;
              case 2:clkh++;if(clkh==24) clkh=0;break;
              default:break;
               }
            }
             break;
    case KEY_DOWN :if(CLK==0)
                switch(key)
               {
        
              case 1:  if(min1==0) min1=60;min1--;break;
              case 2:  if(hour1==0) hour1=24;hour1--;break;
              default: break;
               }
             else
               switch(key)
               {
        
              case 1:  if(clkm==0) clkm=60;clkm--;break;
              case 2:  if(clkh==0) clkh=24;clkh--;break;
              default: break;
               }
             break;
    case KEY_CLK : if(clkh==hour&&clkm==minute&&STOPCLK==1) {STOPCLK=0;feng=1;return;}  //关闹钟
             else {CLK=1;key=tiao=2;}break; //设置闹钟
    case KEY_OK : if(CLK){CLK=0;tiao=flag=key=0;STOPCLK=1;return;} 
            tiao=flag=key=0;CONTIME=0;hour=hour1;minute=min1;/*sec=sec1*/;return;
    case KEY_CANCLE : if(CLK){CLK=0;clkh=24;clkm=0;clks=0;tiao=flag=key=0;return;}
              tiao=flag=key=CONTIME=0;return;
    default: break;
  }    
}
void disply()
{
  uchar i;
  for(i=0;i<4;i++)
  {
    switch(tiao)
    {
      case 1:if(i==3||i==2)
          {
            if(ctiao<50)
            {
              P2=tabwe[i];
              P0=tabdu[n[i]];
            }
          }
          else
          {
            P2=tabwe[i];
            P0=tabdu[n[i]];
          } break;
      case 2:if(i==0||i==1)
          {
            if(ctiao<50)
            {
              P2=tabwe[i];
              P0=tabdu[n[i]];
            }
          }
          else
          {
            P2=tabwe[i];
            P0=tabdu[n[i]];
          }break;     
      default: P2=tabwe[i];P0=tabdu[n[i]];break;
    }    
    delay(1);
  }  
}
/********************T0定时/计数器初始化*******************/
void T0_init()
{
  TMOD=0x11;        //选用T0定时器,工作方式1
  TH0=(65535-46080)/256;
  TL0=(65535-46080)%256;   //赋初值,0.05s中断一次
  TR0=1;   //T0开始工作
  ET0=1;   //允许T0溢出中断
  EA=1;   //开总中断
  PT0=1;   //设置T0中断优先级为高
}
void T1_init()
{
  TH1=(65536-10000)/256;
  TL1=(65536-10000)%256;
  TR1=1;
  ET1=1;
}
void main()
{
  uchar KEY;
  T0_init();
  T1_init();
  feng=1;//关蜂鸣器
  while(1)
  {
    if(KEY=Get_Key())  //如果有键按下
    {
      Key_val(KEY); //按照按键的值进行相关操作
    }
    clock();//闹钟响一分钟后停止
    baoshi();    
  }
}
​
void inter0(void) interrupt 1   //T0中断服务函数
{
  TH0=(65535-46080)/256;
  TL0=(65535-46080)%256;   //每次中断重新装入初值
  t++;
  if(t>=15)
    led=0;
  else
    led=1;
  if(t==20)
  {
    t=0;
    sec++;
  }
  if(sec==60)
  {
    sec=0;
    minute++;
  }
  if(minute==60)
  {
    minute=0;
    hour++;
  }
  if(hour==24)
    hour=0;
}
void iter1(void) interrupt 3    //用于动态显示数码管
{
  TH1=(65536-10000)/256;
  TL1=(65536-10000)%256;
  ctiao++;
  if(ctiao==100)
    ctiao=0;
  getval();  //获取时分秒6位数字,易于数码管的显示
  disply();  //数码管显示函数
}
           

伊斯电子编程—欢迎您的到来。还有更多惊喜等你来拿。

继续阅读