找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2770|回復(fù): 1
收起左側(cè)

AT89C2051單片機(jī)制作數(shù)字時鐘

[復(fù)制鏈接]
ID:439326 發(fā)表于 2019-7-3 10:19 | 顯示全部樓層 |閱讀模式
本帖最后由 xz318569872 于 2019-7-3 10:27 編輯

單個按鍵實現(xiàn)時鐘的24時轉(zhuǎn)到12時制,年月日顯示,星期顯示,可調(diào)整時間,年月日,星期,有仿真。

#include "reg52.h"
typedef unsigned char uchar;//給數(shù)據(jù)類型重命名
typedef unsigned int  uint;
unsigned char code sh[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共陰數(shù)碼管數(shù)碼0~9
uchar Year1,Year2,Mon,Day,Hour,Min,Sec,Week,Week1;// 年月日時分秒星期
uint  Year;
uchar num;         //計數(shù)值
uchar flag=0;        //功能切換標(biāo)志位
void Delay(unsigned char x)      //延時函數(shù)
{
       unsigned int i;
    for(i=0;i<2;i++)
    {
       while(x--);  
    }
}
void Delay_1(unsigned char x)
{
    unsigned char i;
for(i=0;i<30;i++)
{
   while(x--);
}  
}
void Display_Hour(unsigned char x)//時顯示函數(shù)
{
P3=0x05;       //選中第一位數(shù)碼管
P1=sh[x/10];        //分離十位
    Delay(1);  
P3=0x06;        //選中第二位
P1=sh[x%10];        //分離個位
Delay(1);
}
void Display_Min(unsigned char x)//分顯示函數(shù)
{
P3=0x0c;  
P1=sh[x/10];   
    Delay(1);  
P3=0x14;   
P1=sh[x%10];   
Delay(1);
}
void Display_Sec(unsigned char x)//秒顯示函數(shù)
{
P3=0x24;  
P1=sh[x/10];   
    Delay(1);  
P3=0x84;   
P1=sh[x%10];   
Delay(1);
}
void Exchange_Init()//12小時/24小時轉(zhuǎn)換
{
unsigned char h;
if(Hour<=12)   //判斷為1-12
{
   h=Hour;//12小時制和24小時  時間一樣
   Display_Hour(h);
}
else
{
   h=Hour-12;//減去12轉(zhuǎn)換成12小時制
   Display_Hour(h);
}
}
void Display_Year(unsigned char x)//年顯示函數(shù)
{
      P3=0x05;
   P1=sh[x/10];
   Delay(1);
   P3=0x06;
   P1=sh[x%10];
   Delay(1);
}
void Display_Mon(unsigned char x)//月顯示函數(shù)
{
      P3=0x0C;
   P1=sh[x/10];
   Delay(1);
   P3=0x14;
   P1=sh[x%10];
   Delay(1);
}
void Display_Day(unsigned char x)//日顯示函數(shù)
{
      P3=0x24;
   P1=sh[x/10];
   Delay(1);
   P3=0x84;
   P1=sh[x%10];
   Delay(1);
}
void Display_Week1(unsigned char x)//日顯示函數(shù)
{
   P3=0x24;
  P1=sh[x/10];
  Delay(1);
  P3=0x84;
  P1=sh[x%10];
  Delay(1);
}
void  Display_Week(unsigned char x)//星期顯示函數(shù)
{
      P3=0x84;
   P1=sh[x%10];
   Delay(1);
}
void Charge_init()//自動追蹤
{
  if(((Year%4==0)&&(Year%100!=0))||(Year%400==0))//滿足閏年條件
{
   if(Mon==2)
   { if(Hour>=24){Hour=0;Day++;}if(Day>29){ Day=0;Mon++;}}
   else if(Mon<7)
   {if(Mon%2==1){if(Hour>=24){Hour=0;Day++;}if(Day>31)
   {Day=0;Mon++;}}
    else{if(Hour>=24){Hour=0;Day++;}if(Day>30){Day=0;Mon++;}}
   }
   else if(Mon==7)
   {if(Hour>=24){Hour=0;Day++;}if(Day>31){Day=0;Mon++;}}
   else if(Mon<=12)
   {if(Mon%2==1){if(Hour>=24){Hour=0;Day++;}if(Day>30){Day=0;Mon++;}}
   else{if(Hour>=24){Hour=0;Day++;}if(Day>31){Day=0;Mon++;}}}
   else  { Mon=0;}
}
else
{
   if(Mon==2)
   { if(Hour>=24){Hour=0;Day++;}if(Day>28){ Day=0;Mon++;}}
   else if(Mon<7)
   {if(Mon%2==1){if(Hour>=24){Hour=0;Day++;}if(Day>31)
   {Day=0;Mon++;}}
   else{if(Hour>=24){Hour=0;Day++;}if(Day>30){Day=0;Mon++;}}
   }
   else if(Mon==7)
   {if(Hour>=24){Hour=0;Day++;}if(Day>31){Day=0;Mon++;}}
   else if(Mon<=12)
   {if(Mon%2==1){if(Hour>=24){Hour=0;Day++;}if(Day>30){Day=0;Mon++;}}
   else{if(Hour>=24){Hour=0;Day++;}if(Day>31){Day=0;Mon++;}}}
   else  {Mon=0;Year++;}   
}}
void Exchenang_Hour() //時調(diào)整函數(shù)
{
for(;Hour<=24;Hour++)
   {
   P3=0x05;
   P1=sh[Hour/10];
   Delay_1(10);
   P3=0x06;
   P1=sh[Hour%10];
   Delay_1(10);
   if(flag==7)break; //如果flag=5,退出對時的調(diào)整
   }
   if(Hour==24)
  {Hour=0;}               
}
void Exchenang_Min()//分調(diào)整程序
{
   for(;Min<=60;Min++)
   {  
   P3=0x0C;   
   P1=sh[Min/10];  
   Delay_1(10);
   P3=0x14;     
   P1=sh[Min%10];
   Delay_1(10);
   if(flag==9)break; //如果flag=7,退出對分鐘的調(diào)整
   }
   if(Min==60)   //如果分鐘計時到60分,賦初值0,
  {Min=0;}      
}
void Exchenang_Year()//年調(diào)整程序
{  
      unsigned char y;
   for(;Year<=3000;Year++)
   {
   y=Year%100;   
   P3=0x05;   
   P1=sh[y/10];  
   Delay_1(10);
   P3=0x06;  
   P1=sh[y%10];   
   Delay_1(10);
      if(flag==11)break;  //如果flag=9,退出對分鐘的調(diào)整
   }
   if(Year==3000) //如果年達(dá)到3015年,自動賦初值0
   {Year=0;}         
}
void Exchenang_Week()//日調(diào)整程序
{  
  for(;Week<=6;Week++)
  {
  P3=0x24;  
  P1=sh[Week/10];
  Delay_1(10);
  P3=0x84;   
  P1=sh[Week%10];
  Delay_1(10);
  if(flag==5)break; //如果flag=13時,退出調(diào)整日
  }
  if(Week==7)
{Week=0;} //如果天加到31,重新賦初值0      
}
void Exchenang_Mon()//月調(diào)整程序
{   
   for(;Mon<=12;Mon++)
   {
   P3=0x0C;   
   P1=sh[Mon/10];  
   Delay_1(10);
   P3=0x14;   
   P1=sh[Mon%10];
   Delay_1(10);
   if(flag==13)break; //如果flag=11,退出調(diào)整月
   }
   if(Mon==12)    //如果月到達(dá)12時,重新計數(shù)為0;
   {Mon=0;}         
}
void Exchenang_Day()//日調(diào)整程序
{  
   for(;Day<=31;Day++)
   {
   P3=0x24;  
   P1=sh[Day/10];
   Delay_1(10);
   P3=0x84;   
   P1=sh[Day%10];
   Delay_1(10);
   if(flag==15)break; //如果flag=13時,退出調(diào)整日
   }
   if(Day==31)
{Day=0;} //如果天加到31,重新賦初值0      
}
void Timer0_Init()//常規(guī)初始化
{
    TMOD=0x01;   
TH0=(65535-10000)/256; //20ms
TL0=(65535-10000)%256;
ET0=1;  
EX0=1;   
IT0=1;   
TR0=1;  
EA=1;     
}
void main()
{
  Timer0_Init();
  Year=2019;
  Year1=Year/100;
  Year2=Year%100;
  Mon=7;
  Day=3;
  Hour=20;
  Min=20;
  Sec=50;
  Week=3;
  while(1)
  {
  if(flag==0)
  {
   Display_Hour(Hour);    //顯示時分秒
   Display_Min(Min);
   Display_Sec(Sec);
  }
  else if(flag==1)     //顯示切換
  {
   Exchange_Init();
   Display_Min(Min);
   Display_Sec(Sec);
  }
  else if(flag==2)     //顯示年月日
  {
    Display_Year(Year2);
    Display_Mon(Mon);
    Display_Day(Day);
  }
  else if(flag==3)     //顯示星期
  {
   Display_Week(Week);
  }
  else if(flag==4)     //調(diào)整周
  {
   Exchenang_Week();
  }
  else if(flag==5)     //顯示周
  {
   Display_Week1(Week);
  }
  else if(flag==6)     //調(diào)整時
  {
   Exchenang_Hour();
  }
  else if(flag==7)     //顯示時
  {
   Display_Hour(Hour);
  }
  else if(flag==8)     //調(diào)整分
  {
    Exchenang_Min();
  }
  else if(flag==9)     //顯示分
  {
    Display_Min(Min);
  }
  else if(flag==10)     //調(diào)整年
  {
    Exchenang_Year();
    Year2=Year%100;    //取后兩位
  }
  else if(flag==11)     //顯示年
  {
    Display_Year(Year2);
  }
  else if(flag==12)     //調(diào)整月
  {
    Exchenang_Mon();
  }
  else if(flag==13)     //顯示月
  {
    Display_Mon(Mon);
  }
  else if(flag==14)      //調(diào)整日
  {
   Exchenang_Day();
  }         
  else if(flag==15)      //顯示日
  {
   Display_Day(Day);
  }
  }
}
void timer0() interrupt 1  using 1
{
     TH0=(65535-21535)/256;
  TL0=(65535-21535)%256; //重新賦初值,定時20ms
  num++;
  if(num>=60)
  {
     num=0;
  Sec++;   //如果定時到一秒,秒加1
  }   
  if(Sec>=60)
  {
     Sec=0;
  Min++;   //如果秒計時到60s,則分加1
  }
  if(Min>=60)
  {
    Min=0;
    Hour++;   //如果分計時到60m,則時加1
  }  
Charge_init();
}
void Int0_init() interrupt 0
{
flag++;
if(flag==16)
{
  flag=0;
}
}
[img]file:///D:/QQ/QQ消息記錄/318569872/Image/C2C/H2[]ISYL6RXK]FC__7IYI2J.png[/img]


顯示年月日

顯示年月日
回復(fù)

使用道具 舉報

ID:468878 發(fā)表于 2019-7-3 22:23 | 顯示全部樓層
可以焊個實物出來玩玩,我還真沒焊過數(shù)字鐘
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表