天天看点

基于单片机的数字时钟系统设计(程序)

博主福利:100G+电子设计学习资源包!

#include <reg51.h>

 

#define uchar unsigned char

#define uint  unsigned int

uchar sec = 6, min = 6, hou = 6, a = 0, b = 0, c = 0;

uchar num = 0, cmd = 0;

uint time = 0;

uint flag = 0;

 

sbit P30 = P3^0;

sbit P35 = P3^5;

sbit P32 = P3^2;

sbit P33 = P3^3;

 

uchar code tab[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xbf, 0xff, 0xc6};//数码管显示数字

 

void delay(uchar i);

void time_rec();

void display();

void displaym();

void keyscan();

void led_display();

void init();

 

void delay(uchar i)

{

  uchar j;

  while ((i--) != 0)

  {

    for(j = 0; j < 125; j--);

  }

}

 

void time_rec()

{

  if(sec == 60)

    {

      sec = 0;

      min ++;

      if(min == 60)

      {

        min = 0;

        hou ++;

        if(hou == 24)

        {

          hou = 0;

        }

      }

    }

}

 

void display()

{

  P1 = 0X01;//位选第一个数码管

  P2 = 0x20;//打开段选

  P0 = tab[hou / 10];//显示数字

  P2 &= 0x1f;//关闭段选

  P2 = 0xff;

  delay(4);

  

  P1 = 0x02;

  P2 = 0x20;

  P0 = tab[hou % 10];

  P2 &= 0x1f;

  delay(4);

  

  P1 = 0x04;

  P2 = (P2&0x1f)|0x20;

  P0 = 0xbf;

  P2 &= 0x1f;

  delay(4);

 

  P1 = 0x08;

  P2 = (P2&0x1f)|0x20;

  P0 = tab[min / 10];

  P2 &= 0x1f;

  delay(4);

 

  P1 = 0x10;

  P2 = (P2&0x1f)|0x20;

  P0 = tab[min % 10];

  P2 &= 0x1f;

  delay(4);

  

  P1 = 0x20;

  P2 = (P2&0x1f)|0x20;

  P0 = 0xbf;

  P2 &= 0x1f;

  delay(4);

  

  P1 = 0x40;

  P2 = (P2&0x1f)|0x20;

  P0 = tab[sec / 10];

  P2 &= 0x1f;

  delay(4);

 

  P1 = 0x80;

  P2 = (P2&0x1f)|0x20;

  P0 = tab[sec % 10];

  P2 &= 0x1f;

  delay(4);

 

}

void keyscan()

{ 

  if(P35 == 0)

  {

    delay(5);

    if(P35 == 0)

    {

      cmd = cmd + 1;

    }

    while(P35 == 0) {display();}

  }

  

    if(P32 == 0)

  {

    delay(5);

    if(P32 == 0)

    {

      EX0 = 1;

    }

    while(P32 == 0) {display();}

  }

  

  if(P33 == 0)

  {

    delay(5);

    if(P33 == 0)

    {

      EX1 = 1;

    }

    while(P33 == 0) {display();}

  }

 

}

 

void init()

{   

  ET0 = 1;  

  TMOD = 0x11;     //time0为定时器,方式1

  TH0 = (65535 - 50000) / 256;      //预置计算初值

  TL0 = (65535 - 50000) % 256;  

  

  ET1 = 1;

  TH1 = 0xff;

  TL1 = 0xff;

  

  IT0 = 1;         //低电平有效

  IT1 = 1;

  

  TR0 = 1;         //为1时启动计数  

  TR1 = 1;

  EA = 1;

  

}

 

int main()

{         

  P3 = 0xff;       //初始化P3口,全设为1

  init();

  

  while(1)

  {

    display();    

    time_rec();

    

    keyscan();    

  }

  

  return 0;

}

 

void timer_0() interrupt 1

{

  TH0 = (65535 - 50000) / 256;

  TL0 = (65535 - 50000) % 256;

  time++;

  if(time == 20)

  {

    if(flag == 0)

    {

      sec++;

      time = 0;

    }

    else

    {

      time = 0;

    }

  }

}

 

void T1_int() interrupt 3 using 2        //中断T1 用于 可在时间校准的减

{

  if(cmd != 0)

  {

    cmd = 0;

    TH1=0xff;

    TL1=0xff;

    switch(num)

    {

      case 1:hou = hou - 1;if(hou <= 0) hou = 23;break;

      case 2:min = min - 1;if(min <= 0) min = 59;break;

      case 3:sec = sec - 1;if(sec <= 0) sec = 59;break;

      default:break;

    }

  }

  

}

 

void I0_int() interrupt 0         //外部中断0 用于校准时间在时、分、秒之间进行切换

{   

  num = num + 1;

  if(num == 3)

  {

    flag = 1;

  }

  if(num == 4)

    {

      flag = 0;

      num = 0;                                        //退出调时功能

    }

}

 

 

void I1_int() interrupt 2                       //外部中断1 用于调时的加 

{

  EX1 =0;

  switch(num)

  {

    case 1:hou = hou + 1;if(hou >= 24) hou = 0;break;

       Case 2:min = min + 1;if(min >= 60) min = 0;break;

    case 3:sec = sec + 1;if(sec >= 60) sec = 0;break;

    default:break;

  }

}