找回密码
 注册
关于网站域名变更的通知
查看: 206|回复: 2
打印 上一主题 下一主题

一款实用的单片机电子钟制作 附程序原理图

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-9-15 10:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
一、电路图
( |! N4 V5 @  w" l9 {二、使用说明:; `- b/ N! {6 A! t
功能按键说明:S1为功能选择按键和移位的作用,S2为确认作用,S3为数值加一作用。! c! u- B, c  F& f8 p
功能调节说明:
7 F0 K: A* a7 c7 c$ i1 {8 ^0 E1、时钟功能:
0 G5 I6 P2 z3 C( `7 N+ T5 X    如果是芯片内部定时器的时钟,上电后显示00:00:00(掉电后时间不行走不保存,重新上电时间就归0);7 W+ h) q, x+ d! G$ v
    如果是外部时钟DS1302的套件,上电后则显示芯片的内部时间(这个时间掉电后可以保持行走,从新上电显示当前的时间);' F4 j0 s" L# D/ V, C  V4 B" p' {% P
2、校时功能:按一次S1,数码管显示SET1(设置时间),这时按一次S2就进入修改时间,数码管显示00:00(秒位不可调)小时的十位闪烁状态,再次按S1可以移动闪烁的位置,按一次移动一位,按S3时,对应闪烁位置的数据会加1,设置后后再按S2就保存并退出;( |0 e) M; U+ Y
3、闹钟功能:按两次S1,数码管显示SET2(设置闹钟),这时按一次S2就进入修改闹钟,数码管显示00:00 0(秒位不可调,后面的0代表闹钟的状态,0代表闹钟关闭,1表示闹钟开启)小时的十位闪烁状态,再次按S1可以移动闪烁的位置,按一次移动一位,按S3时,对应闪烁位置的数据会加1,设置后后再按S2就保存并退出;# A% P4 x. v# d8 H  n
4、倒计时功能:按三次次S1,数码管显示SET3(设置倒计时),这时按一次S2就进入修改倒计时,数码管显示00:00:00,小时的十位闪烁状态,再次按S1可以移动闪烁的位置,按一次移动一位,按S3时,对应闪烁位置的数据会加1,设置后后再按S2后,系统就开始倒计时;
% X4 ~- k# [; `/ z5、秒表功能:按四次S1,数码管显示SET4(秒表功能),这时按一次S2就秒表功能,此时S2用来开启或关闭秒表,S3退出秒表功能;
+ K0 L5 K4 o; ~$ P& o% h# C: T$ m6、计数器功能:按五次S1,数码管显示SET5(计数器功能),这时按一次S2就进入计数器,按S3计数器的值加1,再次按S2退出计数器,系统恢复;
) b* M+ y4 p+ G7 X8 q
8 c3 r! \$ ?. a; U0 Z3 a电路原理图如下:
0 ^2 R* R9 r: p' y: ?( m7 R2 Q" O2 @5 Y9 J$ A, `) W$ m
0 k: {4 I: [; a7 U) z; d
单片机源程序如下:5 \  _: K8 ]# v. q4 R
  • /*====================================================================
  •   调试要求:
  •   1.mcu:AT89S52芯片或AT89C52
  •   2.晶振:12MHz
  •   功能:启动芯片内部计时
  • ====================================================================*/
  • #include <reg52.h>
  • #include <intrins.h>
  • #define uchar unsigned char
  • #define uint  unsigned int
  • sbit    dis_bit1=P2^7;//定义数码管控制口
  • sbit    dis_bit2=P2^6;//定义数码管控制口
  • sbit    dis_bit3=P2^4;//定义数码管控制口
  • sbit    dis_bit4=P2^3;//定义数码管控制口
  • sbit    dis_bit5=P2^1;//定义数码管控制口
  • sbit    dis_bit6=P2^0;//定义数码管控制口
  • sbit    led1_bit=P2^2;//定时LED的控制口
  • sbit    led2_bit=P2^5;//定时LED的控制口
  • sbit    s1_bit=P1^0;  //定义S1控制口
  • sbit    s2_bit=P1^1;  //定义S2控制口
  • sbit    s3_bit=P1^2;  //定义S3控制口
  • sbit    speak=P3^7;   //定义蜂鸣器控制口
  • #define smg_data    P0//定义数码管数据口
  • void  delay_50us(uint t);//延时50*T微妙函数的声明
  • void  display1(uchar dis_data);//数码管1显示子程序
  • void  display2(uchar dis_data);//数码管2显示子程序
  • void  display3(uchar dis_data);//数码管3显示子程序
  • void  display4(uchar dis_data);//数码管4显示子程序
  • void  display5(uchar dis_data);//数码管5显示子程序
  • void  display6(uchar dis_data);//数码管6显示子程序
  • void  init_t0();//定时器0初始化函数
  • void  dis_led();//LED处理函数
  • void  judge_s1();//S1按键处理函数
  • void  judge_s2();//S2按键处理函数
  • void  judge_s3();//S3按键处理函数
  • void  dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1);//显示子程序
  • void  dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san);//闪烁显示子程序
  • void  judge_dis();//显示处理函数
  • void  judge_clock();//显示处理函数
  • //共阳数码管断码表
  • const unsigned char tabl1[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
  •                                // 0  1    2    3    4    5
  •                                0x82,0xf8,0x80,0x90,0x86,0x87,0xFF,
  •                               //6   7     8    9     E    T   B
  •                                     0xc6,0xa1,0x8e,0xb6};
  •                               //    C     D    F    三
  • uchar t0_crycle;
  • uchar hour_count,minute_count,second_count,msecond_count;
  • uchar clock_hour,clock_minute;
  • uchar clock_en;//闹钟关闭和开启的标志,1开启,0关闭
  • uchar flag1,zancun1,zancun2,zancun3;//,flag2;
  • uchar clock_flag;
  • uint  speak_count;
  • //主程序
  • void main()
  • {
  •     P3=0x00;
  •     flag1=0;
  •     zancun3=0;
  •     speak=1;//关闭蜂鸣器
  •     speak_count=0;
  •     clock_hour=0;
  •     clock_minute=0;
  •     clock_flag=0;
  •     clock_en=0;//开机时默认关闭闹钟
  •     init_t0();
  •     TR0=1;//
  •    //接下来开始编写让数码管显示的程序
  •     while(1)
  •     {
  •       judge_dis();//显示处理
  •       judge_s1();
  •       judge_s2();
  •       judge_s3();
  •       judge_clock();//闹钟处理程序
  •     }
  • }
  • void timer0() interrupt 1
  • {
  •         TH0=(65536-50000)/256;
  •         TL0=(65536-50000)%256;
  •         t0_crycle++;
  •         if(t0_crycle==2)// 0.1秒
  •         {
  •           t0_crycle=0;
  •           msecond_count++;
  •       if(msecond_count==10)//1秒
  •       {
  •         msecond_count=0;
  •         second_count++;
  •         if(second_count==60)
  •         {
  •           second_count=0;
  •           minute_count++;
  •           if(minute_count==60)
  •           {
  •             minute_count=0;
  •             hour_count++;
  •             if(hour_count==24)
  •             {
  •               hour_count=0;
  •             }
  •           }
  •         }
  •       }
  •         }
  • }
  • //**************************************************
  • //显示处理函数
  • void  judge_dis()
  • {
  •     if(flag1==0)
  •     {
  •       dis(hour_count/10,hour_count%10,minute_count/10,minute_count%10,second_count/10,second_count%10);
  •       dis_led();
  •     }
  •     if(flag1!=0)
  •     {
  •        switch(flag1)
  •        {
  •            case 1:
  •                 dis(5,10,11,1,12,12);//显示SET1
  •                 led1_bit=1;
  •                 led2_bit=1;
  •                 break;
  •            case 2:
  •                 dis(5,10,11,2,12,12);//显示SET2
  •                 break;
  •            case 3:
  •                 dis(5,10,11,3,12,12);//显示SET3
  •                 break;
  •            case 4:
  •                 dis(5,10,11,4,12,12);//显示SET4
  •                 break;
  •            case 5:
  •                 dis(5,10,11,5,12,12);//显示SET5
  •                 break;
  •            case 6:
  •                 dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,1);
  •                 break;
  •            case 7:
  •                 dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,2);
  •                 break;
  •            case 8:
  •                 dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,3);
  •                 break;
  •            case 9://进入修改时间,时间分位个位闪烁
  •                 dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,4);
  •                 break;
  •            case 10://进入修改闹钟,闹钟小时十位闪烁
  •                 dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,1);
  •                 break;
  •            case 11://进入修改闹钟,闹钟小时个位闪烁
  •                 dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,2);
  •                 break;
  •            case 12://进入修改闹钟,闹钟小时十位闪烁
  •                 dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,3);
  •                 break;
  •            case 13://进入修改闹钟,闹钟小时个位闪烁
  •                 dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,4);
  •                 break;
  •            case 14://进入修改闹钟的开关
  •                 dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,6);
  •                 break;
  •            default:
  •                 break;
  •         }
  •     }
  • }
  • //**************************************************
  • //S1按键处理函数
  • void  judge_s1()
  • {
  •     s1_bit=1;//置IO为1,准备读入收据
  •     if(s1_bit==0)//判断是否有按键按下
  •     {
  •         delay_50us(1);// 延时,去除机械抖动
  •         if(s1_bit==0)
  •         {
  •            switch(flag1)
  •            {
  •                case 0:
  •                     flag1=1;
  •                     break;
  •                case 1:
  •                     flag1=2;
  •                     break;
  •                case 2:
  •                     flag1=3;
  •                     break;
  •                case 3:
  •                     flag1=4;
  •                     break;
  •                case 4:
  •                     flag1=5;
  •                     break;
  •                case 5:
  •                     flag1=0;
  •                     break;
  •                case 6://在修改时间小时十位下按S1键
  •                     flag1=7;
  •                     break;
  •                case 7:
  •                     flag1=8;
  •                     break;
  •                case 8:
  •                     flag1=9;
  •                     break;
  •                case 9:
  •                     flag1=6;
  •                     break;
  •                case 10:
  •                     flag1=11;
  •                     break;
  •                case 11:
  •                     flag1=12;
  •                     break;
  •                case 12:
  •                     flag1=13;
  •                     break;
  •                case 13:
  •                     flag1=14;
  •                     break;
  •                case 14:
  •                     flag1=10;
  •                     break;
  •                default:
  •                     break;
  •            }
  •            while(s1_bit==0)
  •            {
  •               judge_dis();
  •            }//等待按键释放
  •         }
  •     }
  • }
  • //**************************************************
  • //S2按键处理函数
  • void  judge_s2()
  • {
  •     s2_bit=1;//置IO为1,准备读入收据
  •     if(s2_bit==0)//判断是否有按键按下
  •     {
  •         delay_50us(1);// 延时,去除机械抖动
  •         if(s2_bit==0)
  •         {
  •            switch (flag1)
  •            {
  •               case 1: //在显示SET1状态下按S2件,进入修改时间
  •                  flag1=6;
  •                  zancun1=hour_count;
  •                  zancun2=minute_count;
  •                  break;
  •               case 2://在显示SET2状态下按S2,进入设置闹钟
  •                  zancun1=clock_hour;
  •                  zancun2=clock_minute;
  •                  flag1=10;
  •                  break;
  •               case 6://修改时钟小时十位状态下按S2件
  •                  hour_count=zancun1;
  •                  minute_count=zancun2;
  •                  second_count=0;
  •                  flag1=0;
  •                  break;
  •               case 7://修改时钟小时个位状态下按S2件
  •                  hour_count=zancun1;
  •                  minute_count=zancun2;
  •                  second_count=0;
  •                  flag1=0;
  •                  break;
  •               case 8://修改时钟分钟十位状态下按S2件
  •                  hour_count=zancun1;
  •                  minute_count=zancun2;
  •                  second_count=0;
  •                  flag1=0;
  •                  break;
  •               case 9://修改时钟分钟个位状态下按S2件
  •                  hour_count=zancun1;
  •                  minute_count=zancun2;
  •                  second_count=0;
  •                  flag1=0;
  •                  break;
  •               case 10:
  •                  clock_hour=zancun1;
  •                  clock_minute=zancun2;
  •                  clock_en=zancun3;
  •                  flag1=0;
  •                  break;
  •               case 11:
  •                  clock_hour=zancun1;
  •                  clock_minute=zancun2;
  •                  clock_en=zancun3;
  •                  flag1=0;
  •                  break;
  •               case 12:
  •                  clock_hour=zancun1;
  •                  clock_minute=zancun2;
  •                  clock_en=zancun3;
  •                  flag1=0;
  •                  break;
  •               case 13:
  •                  clock_hour=zancun1;
  •                  clock_minute=zancun2;
  •                  clock_en=zancun3;
  •                  flag1=0;
  •                  break;
  •               case 14:
  •                  clock_hour=zancun1;
  •                  clock_minute=zancun2;
  •                  clock_en=zancun3;
  •                  flag1=0;
  •                  break;
  •               default:
  •                  break;
  •            }
  •            while(s2_bit==0)
  •            {
  •               judge_dis();
  •            }//等待按键释放
  •         }
  •     }
  • }
  • //**************************************************
  • //S3按键处理函数
  • void  judge_s3()
  • {
  •     s3_bit=1;//置IO为1,准备读入收据
  •     if(s3_bit==0)//判断是否有按键按下
  •     {
  •         delay_50us(1);// 延时,去除机械抖动
  •         if(s3_bit==0)
  •         {
  •            switch (flag1)
  •            {
  •               case 6://修改时间小时的十位数
  •                  zancun1+=10;
  •                  if(zancun1>=24)zancun1=zancun1%10;
  •                  break;
  •               case 7://修改时间小时的个位数
  •                  zancun1=zancun1/10*10+(zancun1%10+1)%10;
  •                  if(zancun1>=24)zancun1=20;
  •                  break;
  •               case 8://修改时间分钟的十位数
  •                  zancun2+=10;
  •                  if(zancun2>=60)zancun2-=60;
  •                  break;
  •               case 9://修改时间分钟的个位数
  •                  zancun2=zancun2/10*10+(zancun2%10+1)%10;
  •                  break;
  •               case 10://修改闹钟小时的十位数
  •                  zancun1+=10;
  •                  if(zancun1>=24)zancun1=zancun1%10;
  •                  break;
  •               case 11://修改闹钟小时的个位数
  •                  zancun1=zancun1/10*10+(zancun1%10+1)%10;
  •                  if(zancun1>=24)zancun1=20;
  •                  break;
  •               case 12://修改闹钟分钟的十位数
  •                  zancun2+=10;
  •                  if(zancun2>=60)zancun2-=60;
  •                  break;
  •               case 13://修改闹钟分钟的个位数
  •                  zancun2=zancun2/10*10+(zancun2%10+1)%10;
  •                  break;
  •               case 14:
  •                  zancun3^=1;
  •                  break;
  •               default:
  •                  break;
  •            }
  •            while(s3_bit==0)
  •            {
  •               judge_dis();
  •            }//等待按键释放
  •         }
  •     }
  • }
  • //****************************************
  • //显示处理函数
  • void  judge_clock()
  • {
  •     if(clock_hour==hour_count && clock_minute==minute_count)
  •     {
  •          if(clock_en==1 && clock_flag==0)
  •          {
  •               speak_count=0;//开启蜂鸣器
  •               clock_flag=1;
  •               speak_count=0;
  •          }
  •     }
  •     else
  •     {
  •      clock_flag=0;
  •     }
  •     if(clock_flag==1 && speak_count<400)
  •     {
  •         if(msecond_count<=5)
  •         {
  •            speak=0;
  •            speak_count++;
  •         }
  •         else
  •         {
  •           speak=1;
  •         }
  •     }
  •     else
  •     {
  •         speak=1;
  •     }
  • }
  • //****************************************
  • ////闪烁显示子程序
  • void  dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san)
  • {
  •      if(san==1)
  •      {
  •         if(msecond_count<5)
  •         {
  •            display1(s6);
  •         }
  •      }
  •      else
  •      {
  •          display1(s6);
  •      }
  •      if(san==2)
  •      {
  •         if(msecond_count<5)
  •         {
  •            display2(s5);
  •         }
  •      }
  •      else
  •      {
  •          display2(s5);
  •      }
  •      if(san==3)
  •      {
  •         if(msecond_count<5)
  •         {
  •            display3(s4);
  •         }
  •      }
  •      else
  •      {
  •          display3(s4);
  •      }
  •      if(san==4)
  •      {
  •         if(msecond_count<5)
  •         {
  •            display4(s3);
  •         }
  •      }
  •      else
  •      {
  •          display4(s3);
  •      }
  •      if(san==6)
  •      {
  •         if(msecond_count<5)
  •         {
  •            display6(s1);
  •         }
  •      }
  •      else
  •      {
  •          display6(s1);
  •      }
  •      display5(s2);
  •     // display6(s1);
  • }
  • //****************************************
  • //时钟显示程序
  • void  dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1)
  • {
  •      display1(s6);
  •      display2(s5);
  •      display3(s4);
  •      display4(s3);
  •      display5(s2);
  •      display6(s1);
  • }
  • //********************************************************************************************
  • void init_t0()
  • {
  •            TMOD=0x01;//设定定时器工作方式1,定时器定时50毫秒
  •         TH0=(65536-50000)/256;
  •         TL0=(65536-50000)%256;
  •         EA=1;//开总中断
  •         ET0=1;//允许定时器0中断
  •         t0_crycle=0;//定时器中断次数计数单元
  • }
  • //**************************************************
  • //LED处理函数
  • void  dis_led()
  • {
  •      if(msecond_count<5)
  •      {
  •          led1_bit=1;
  •          led2_bit=1;
  •      }
  •      else
  •      {
  •          led1_bit=0;
  •          led2_bit=0;
  •      }
  • }
  • //***************************************************************
  • //功能:把数据1显示在数码管1上
  • void display6(uchar dis_data)
  • {
  •    smg_data=tabl1[dis_data];//送显示断码
  •    dis_bit6=0;//锁存数据
  •    delay_50us(40);
  •    dis_bit6=1;
  • }
  • //***************************************************************
  • //功能:把数据1显示在数码管1上
  • void display5(uchar dis_data)
  • {
  •    smg_data=tabl1[dis_data];//送显示断码
  •    dis_bit5=0;//锁存数据
  •    delay_50us(40);
  •    dis_bit5=1;
  • }
  • //***************************************************************
  • //功能:把数据1显示在数码管1上
  • void display4(uchar dis_data)
  • {
  •    smg_data=tabl1[dis_data];//送显示断码
  •    dis_bit4=0;//锁存数据
  •    delay_50us(40);
  •    dis_bit4=1;
  • }//***************************************************************
  • //功能:把数据1显示在数码管1上
  • void display3(uchar dis_data)
  • {
  •    smg_data=tabl1[dis_data];//送显示断码
  •    dis_bit3=0;//锁存数据
  •    delay_50us(40);
  •    dis_bit3=1;
  • }
  • //***************************************************************
  • //功能:把数据1显示在数码管1上
  • void display1(uchar dis_data)
  • {
  •    smg_data=tabl1[dis_data];//送显示断码
  •    dis_bit1=0;//锁存数据
  •    delay_50us(40);
  •    dis_bit1=1;
  • }
  • //***************************************************************
  • //功能:把数据1显示在数码管1上
  • void display2(uchar dis_data)
  • {
  •    smg_data=tabl1[dis_data];//送显示断码
  •    dis_bit2=0;//锁存数据
  •    delay_50us(40);
  •    dis_bit2=1;
  • }
  • //**************************************************************************************************
  • //函数名称:void delay_50US(unsigned int t)
  • //功能: 延时50*t(us)
  • void delay_50us(uint t)
  • {
  •   unsigned char j;
  •   for(;t>0;t--)
  •   {
  •     for(j=19;j>0;j--);
  •   }
  • }: T1 n, C' a% h1 c( A

0 B  Z$ c8 {6 g) D  z" i
- K* ^9 {' Z: C7 U; _/ ], m

该用户从未签到

2#
发表于 2022-9-15 11:14 | 只看该作者
分享知识,提高同行之间的技术水平。

该用户从未签到

3#
发表于 2022-9-15 13:54 | 只看该作者
认真学习技术上的知识,维护好这样良好的学习氛围。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-6-5 13:52 , Processed in 0.093750 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表