zoukankan      html  css  js  c++  java
  • 单片机实现的数字钟

    一:电路原理和器件选择

    制作电路:单片机(AT89S52)实现多功能数字钟

    性能指标:该数字钟实现时钟运行,调整,倒计时,秒表功能,且精确度经调试一天的误差在2S内。

     

    实现原理:利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据。同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。

     

    电路主要模块及原理图:

    1.  数码显示硬件驱动

     数码管驱动电路

     

    2.单片机最小系统:

    单片机最小系统

     

    3.LED及单片机电源原理图

    LED及单片机电源

     

    4.外部控制状态输入模块原理图

    外部控制状态输入模块原理图

     

     

    主要元器件选择:

    单片机:AT89S52采用市场上比较常用的AT89S52,这里采用AT89S52而不是AT89S51是为了最大限度减小误差,因为要实现多功能(例如秒表,时钟,倒计时)为了相互之间不干扰而要用到3个定时/计数器,而51系列只有2个,而52系列有3个,故采用52系列

    三极管:用来进行数码管显示的位选,这里采用PNP

    数码管:采用共阳级四位数码管

    晶振:采用的是11.0592MHZ的晶振

    电源部分:采用5V电压供电,采用的是L7805稳压芯片供电(加滤波)

    电阻:大部分时限流电阻,阻值为4.7K10K1K

     

    端口分配及连接:

    P0:LED数码管显示内容通过P1口从单片机传送到数码管

    P2.4-P2.7:数码管位选控制端口

    P2.0-P2.3:分别连接开关K0K1K2K3通过不同的组合实现外部控制程序状态

    P1.0:蜂鸣器,倒计时完毕产生鸣响

    P1.2-P1.5:四个发光二极管,显示当前时钟状态

     

    完整的源程序如下:

    附程序源代码及注释

     

    #include <reg52.h>

    #include <absacc.h>

    #define  uint unsigned int

    #define  uchar unsigned char

     

    /*定义P2口各管脚*/

    sbit K0=P2^2;

    sbit K1=P2^1;

    sbit K2=P2^0;

    sbit K3=P2^3;

     

    sbit D0=P2^4;

    sbit D1=P2^5;

    sbit D2=P2^6;

    sbit D3=P2^7;

     

    /*定义P1口各管脚*/

    sbit beep=P1^0;

    sbit L0=P1^5;

    sbit L1=P1^4;

    sbit L2=P1^3;

    sbit L3=P1^2;

     

    uchar data BUFFER[4]={0,0,0,0};    //显示缓冲区(依次从低位到高位,共四位数码管)

    uchar data CLOCK[4]={0,0,0,0};     //存放时钟时间(依次是百分秒,秒,分,时)

    uchar data SECOND[3]={0,0,0};      //存放秒表时间(依次时百分秒,秒,分)

    uchar data SEVER[4]={0,0,0,0};     //存放倒计时时间(依次是百分秒,秒,分,时)

     

    /*定义程序运行状态*/

    uchar data STATE=0;

    /*STATE=0;时钟运行*/

    /*STATE=1;时钟分调整*/

    /*STATE=2;未定义状态,可添加*/

    /*STATE=3;时钟时调整*/

    /*STATE=4;倒计时分调整*/

    /*STATE=5;倒计时时调整*/

    /*STATE=6;秒表*/

    /*STATE=7;倒计时运行*/

     

    /*定义辅助计时全局变量*/

    uchar m=60;

     

    /*共阳数码管显示"0"-"9","-" */

    uchar code TABLE[]={0xC0,0xf9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98,0xbf};

     

    /*自定义子函数*/

    void display();                         //显示函数

    void delay();                           //显示延时函数

    void intsvr();                          //调整时间时加1子函数

    void delay10ms();                       //延时函数

     

    /*主函数体*/

     

    void main(void)

    {

        EA=1;ET0=1;                          //开总中断源,开T0中断

        TMOD=0x61;                           //T1方式2计数,T0方式1计时

        TH0=-9460/256;TL0=-9460%256;         //初始化计数器初值

        TH1=0xff;TL1=0xff;                

        T2CON=0;TH2=-9452/256;TL2=-9452%256;

     

        K0=1;K1=1;K2=1;                      //初始化控制状态位

        STATE=P2&0x07;

     

        for(;;)

        {

            switch(STATE)

               {

                case 1:                      //时钟分调整程序

                {

                    TR0=0;ET0=0;EX0=0;TR2=0; //关闭定时器,时钟停止运行,同时关闭外中断IT0

                             L3=0;L1=0;L2=0;L0=1;

                    intsvr();                //调用加1函数

                             BUFFER[0]=CLOCK[2]%10;   //数码管显示分钟个位

                    BUFFER[1]=CLOCK[2]/10;   //数码管显示分钟十位

                    BUFFER[2]=10;            //显示""

                    BUFFER[3]=10;            //显示""

                }break;

     

                      case 3:                      //时钟时调整程序

                      {

                          TR0=0;ET0=0;EX0=0;TR2=0; //关闭定时器,时钟停止运行

                             L3=0;L1=0;L2=0;L0=1;

                    intsvr();                //调用加1函数

                             BUFFER[0]=CLOCK[2]%10;   //数码管显示分钟个位

                    BUFFER[1]=CLOCK[2]/10;   //数码管显示分钟十位

                    BUFFER[2]=CLOCK[3]%10;   //数码管显示时钟个位

                    BUFFER[3]=CLOCK[3]/10;   //数码管显示时钟十位

                      }break;

     

                      case 4:                      //倒计时分钟调整程序

                      {

                          TR0=1;ET0=1;EX0=0;TR2=0; //保持T0正常运行,即时钟正常运行,同时关闭外中断IT0

                             L3=0;L2=0;L1=0;   

                    intsvr();                //调用加1函数               

                             BUFFER[0]=SEVER[2]%10;   //数码管显示分钟个位

                    BUFFER[1]=SEVER[2]/10;   //数码管显示分钟十位

                    BUFFER[2]=10;            //显示""

                    BUFFER[3]=10;            //显示""

                   

                             SECOND[1]=0;             //秒表初始化为0

                                  SECOND[2]=0;            

                      }break;

     

                      case 5:                      //倒计时时钟调整程序

                      {

                          TR0=1;ET0=1;EX0=0;TR2=0; //保持T0正常运行,即时钟正常运行,同时关闭外中断IT0

                             L3=0;L2=0;L1=0;    

                    intsvr();                //调用加1子函数

                             BUFFER[0]=SEVER[2]%10;   //数码管显示分钟个位

                    BUFFER[1]=SEVER[2]/10;   //数码管显示分钟十位

                    BUFFER[2]=SEVER[3]%10;   //数码管显示时钟个位

                    BUFFER[3]=SEVER[3]/10;   //数码管显示时钟十位

                            

                    SECOND[1]=0;             //秒表初始化为0

                                  SECOND[2]=0;

                      }break;

     

                      case 6:

                      { 

                             TR0=1;ET0=1;EX0=1;ET2=1;//保持T0正常运行,即时钟正常运行,同时开外中断IT0

                            

                             BUFFER[0]=SECOND[1]%10; //数码管显示秒表秒个位

                    BUFFER[1]=SECOND[1]/10; //数码管显示秒表秒十位

                    BUFFER[2]=SECOND[2]%10; //数码管显示秒表分个位

                    BUFFER[3]=SECOND[2]/10; //数码管显示秒表分十位

                      }break;

     

                      case 7:

                      {

                             TR0=1;ET0=1;EX0=0;ET2=1;   //倒计时运行,同时时钟也正常运行,关闭外中断T0

                             if((SEVER[2]==0)&&(SEVER[3]==0))   //当预置时间(分,时)变为0时,计时完毕

                             {

                                 beep=!beep;                    //蜂鸣器响

                                 BUFFER[0]=10;                  //显示""

                                 BUFFER[1]=10;

                                 BUFFER[2]=10;

                                 BUFFER[3]=10;

                        TR2=0;                         //关闭T2

                          }

                             else

                             {

                                 TR2=1;                         //开启T2 

                             }

                             SECOND[1]=0;                       //秒表时间初始化

                                  SECOND[2]=0;

                      }break;

       

                   default:

                   {

                    ET0=1;TR0=1;EX0=0;                //开启T0,时钟运行,关闭外中断

                             L1=1;L3=1;L2=1;

                   

                             BUFFER[0]=CLOCK[2]%10;            //数码管显示分钟个位

                    BUFFER[1]=CLOCK[2]/10;            //数码管显示分钟十位

                    BUFFER[2]=CLOCK[3]%10;            //数码管显示时钟个位

                    BUFFER[3]=CLOCK[3]/10;            //数码管显示时钟十位  

                      }

            }

               K0=1;K1=1;K2=1;                           //重新预置状态位

               display();                                //调用显示函数

               STATE=P2&0x07;                            //通过P2口提取当前状态

        }

    }

     

    /*T0中断服务*/

     

    void time0(void)   interrupt 1 using 1           //T0中断函数

    {

        TH0=-9460/256;                               //计时器放入预置时间,大概10毫秒

        TL0=-9460%256;

        CLOCK[0]=CLOCK[0]+1;                         //一次中断加1

        if(CLOCK[0]==50)                             //0.5秒到

        {

            L0=!L0;                                  //L0取反

        }

        if(CLOCK[0]==100)                            //1秒到

  • 相关阅读:
    25.大白话说java并发工具类-CountDownLatch,CyclicBarrier,Semaphore,Exchanger
    23.FutureTask基本操作总结
    22.线程池之ScheduledThreadPoolExecutor
    Jenkins + SVN搭建php持续集成
    Django学习系列之Form表单结合ajax
    Django学习系列之模板系统
    Django学习系列之路由系统
    zabbix学习系列之基础概念
    Python学习系列之反射
    Django学习系列之模板
  • 原文地址:https://www.cnblogs.com/love2wllw/p/1845211.html
Copyright © 2011-2022 走看看