(连载1)吴鉴鹰单片机项目精讲(连载)之基于单片机的数字电子钟设计

2014年06月12日 10:53    发布者:吴鉴鹰
(连载1)吴鉴鹰单片机项目精讲(连载)之基于单片机的数字电子钟设计

先关的原理图请点击下载:
136197
     现在来第一讲,详细解析如何制作基于单片机的数字时钟,提供详细的硬件原理图和软件程序。
开关K1:K1 = 0时,时钟正常运行,此时不允许调整时钟。数码管的高两位显示小时,后两位显示分钟,led每闪一次表示时钟运行一次,在调整的过程中,led是停止发亮的。
一、 按键、开关功能说明:
* 按键RESET:按下能复位程序。
* 按键PULSE:提供单脉冲,从而实现单片机对外部脉冲的计数,利用单脉冲实现相应的位加一。
* 开关K0:K0 = 0能调整分位,K0 = 1能调整时位。
* 开关K2:k2为高电平时,使单脉冲输入至INT1,通过外中断实现相应值的加一功能。

二、地址分配和链接
* P2.7: 和写信号一起组成字位口的片选信号,字位口的对应地址为8000H。
* P2.6: 和写信号一起组成字位口的片选信号,字位口的对应地址为4000H。
* D0~D7: 单片机的数据总线,LED显示的内容通过D0~D7数据线从单片机传到LED。
* P2.0~P2.5:单片机的P2口,和2764的高位地址线相连,决定2764中的存储单元的地址。
* P1.4~P1.7: 单片机的P1端口,和发光二极管L1~L4相连,通过单片机的P1.4~P1.7控制,所以显示秒表和时钟的时间变化。
* P1.0: 和开关K0相连,决定时间调整的字位。
* P1.1 : 和开关K1相连,决定时间运行的模式。
* P1.2: 和开关K2相连,决定外中断的模式选择。

三、整体功能简介
LED显示模块与单片机的链接中,对LED显示模块的读写和字位、段码的选择通过口P2.6\P2.7完成的。
外部存储器2764是通过锁存器373和单片机相连,并且通过P2端口的相关信号线进行地址的分配。地址范围是0000H~1FFFH。
四、程序设计
/******************************************************
*程序:吴鉴鹰数字电子钟的设计                                                           
** 这一讲的主要内容: 数字电子钟的设计原理和程序                                                                                
** 功能描述:  
** 输 入:         
** 内容:     
** 输 出:
**         
** 全局变量:
** 调用模块:
**
** 作 者:    吴鉴鹰
** 日 期:     14.02.17

备注:有什么错误的地方,欢迎各大烧友指正

O(∩_∩)O~
*******************************************************/
//变量定义和头文件的调用
//定义头文件和各个输入管脚以及变量声明
#include
#include
#define  uint unsigned int
#define  uchar  unsigned char


/*定义字型字位口*/
#define  DIGPORT  XBYTE  
#define  WORDPORT  XBYTE

/*定义P1口各管脚*/
sbit  K0 = P1^0;
sbit  K1 = P1^1;
sbit  K2 = P1^2;
sbit  BEEP = P1^3;
sbit  L0 = P1^4;
sbit  L1 = P1^5
sbit  L2 = P1^6;
sbit  L3 = P1^7;

uchar  data  BUFFER  = {0,0};  //显示的缓存数组,依次为低位、高位
uchar  data  CLOCK = {0,0,0,0};
uchar  data  SECOND = {0,0};

/*定义运行状态*/
uchar  data  STATE = 0;
/*STATE = 0;秒表*/
/*STATE = 4,或者7,时钟运行*/
/* STATE = 6,时钟时调整 */

bit  bdata  SND = 0;    /*  秒表START(开始)  */
bit  bdata  RST = 0;     /*秒表RESET(复位)*/

/*数码管显示编码“0”-“9”,"A","-"*/
uchar  code  TABLE[] = {0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X77,0X40};

/******************************************************
*程序:主程序                                                                                                                        
** 功能描述: 主干程序
** 输 入:         
** 内容:     
** 输 出:
**         
** 全局变量:
** 调用模块:
**
** 作 者:    吴鉴鹰
** 日 期:     14.02.17

备注:有什么错误的地方,欢迎各大烧友指正

O(∩_∩)O~
*******************************************************/
void  main()
{
      uchar   stabak;
          P1 = 0X0F;
      EA = 1;
      IT1 = 1;
      ET0 = 1;
      TMOD = 0X61;
      TH0 = -5000/256;
      TL0 = -5000%256;
      TH1 = 0XFF;
      TL1 = 0XFF;
      T2CON = 0;
      TH2 = -5000/256;
      TL2 = -5000%256;

       K0 = 1;
       K1 = 1;
       K2 = 1;
       STATE = P1&0X07;
       stabak = STATE;

      for(;;)
    {
           switch()
        {
                case 0:
                {
                    EX1 = 0;
                    ET1 = 1;
                    ET2 = 1;
                    TR1 = 1;
                    SND = 1;
                    L1 = 1;   
                    L0 = 0;
                    L2 = 0;
                    SECOND = 0;
                    SECOND = 0;
                }break;

                 case   5:
                {
                          IE1 = 0;
                          EX1 = 1;
                          ET1 = 0;
                          ET2 = 0;
                          TR0 = 0;
                          L0 = 1;
                          L1 = 0;
                          L2 = 0;
                }break;

                case  6:
               {
                    IE1 = 0;
                    EX1 = 1;
                    ET1 = 0;
                    ET2 = 1;
                    TR0 = 0;
               }break;

                  default:
               {
                   EX1 = 0;
                   ET1 = 0;
                   ET2 = 1;
                   L1 = 0;
                                   L2 = 0;
               }

        }
         while(STATE == stabak)
     {
         switch(STATE)
      {
         case 0:
      {
         BUFFER = SECOND;
         BUFFER = SECOND;
      }break;
      
      case 5:
      {
          BUFFER = CLOCK;
          BUFFER = 101;/*A-*/
      }break;
      
      case 6:
      {
          BUFFER = 110;/*A-*/
          BUFFER = CLOCK;
      }break;
      
      default:
      {
          BUFFER = CLOCK;
          BUFFER = CLOCK;
      }break;
      
      default:
      {
          BUFFER = CLOCK;
          BUFFER = CLOCK;
      }
      
      }
      
     //显示函数
     display();
     K0 = 1;
     K1 = 1;
     K2 = 1;
     STATE = P1&0X07;   
     }
     stabak = STATE;
    }
}

/******************************************************
*程序:子函数(1):timer0(void)                                                                                                                        
** 功能描述:  用定时器0实现24小时的时钟显示
** 输 入:         
** 内容:     
** 输 出:
**         
** 全局变量:
** 调用模块:
**
** 作 者:    吴鉴鹰
** 日 期:     14.02.17

备注:有什么错误的地方,欢迎各大烧友指正

O(∩_∩)O~
*******************************************************/
void  timer0(void)   interrupt  1  using 1
{
    /*重置定时器初值*/
TH0 = -5000/256;
TL0 = -5000%256;


/*定时器处理*/
CLOCK = CLOCK+1;
if((CLOCK == 50) && (STATE >= 4))
{
    L0 = !L0;
}

if(CLOCK == 100)
{
    if(STATE >= 4)  L0 = !L0;
    CLOCK = 0;
    CLOCK = CLOCK + 1;
   
    if(CLOCK == 60)
    {
       CLOCK = 0;
    CLOCK = CLOCK + 1;
    if(CLOCK == 60)
    {
        CLOCK == 0;
     CLOCK == CLOCK + 1;
     if(CLOCK == 24)
     {
        CLOCK = 0;
     }
    }
    }
}
}

/******************************************************
*程序:子函数(2):intsvr1(void)                                                                                                                        
** 功能描述:  对外中断1的按键脉冲进行判断和计数,并完成对应的时间调整功能。
** 输 入:         
** 内容:     
** 输 出:
**         
** 全局变量:
** 调用模块:
**
** 作 者:    吴鉴鹰
** 日 期:     14.02.17

备注:有什么错误的地方,欢迎各大烧友指正

O(∩_∩)O~
*******************************************************/
void intsvr1(void) interrupt  2  using 2  
{
   if(STATE == 5)
   {
       CLOCK == CLOCK + 1;
    if(CLOCK == 60)  CLOCK == 0;
   }
   if(STATE == 6)
   {
       CLOCK == CLOCK + 1;
    if(CLOCK == 24)  CLOCK = 0;
   }
}

/******************************************************
*程序:子函数(3):display(void)                                                                                                                        
** 功能描述:  用动态显示的方法,将当前的时间或秒表内容通过数码管显示。
** 输 入:         
** 内容:     
** 输 出:
**         
** 全局变量:
** 调用模块:
**
** 作 者:    吴鉴鹰
** 日 期:     14.02.17

备注:有什么错误的地方,欢迎各大烧友指正

O(∩_∩)O~
*******************************************************/
void diplay(void)
{
   uchar i;
   uchar delay;
   uchar disp;
   uchar digit;
   digit = 0x08;
   for(i = 0;i < 2; i++)
   {
      if(BUFFET> 100)  
{
   disp = BUFFER%10 + 10;
}
   else  disp = BUFFER%10;
   
   DIGPORT = digit;
   WORDPORT = TABLE;
   
   for(delay = 0;delay <= 200;delay ++);
   digit = digit >> 1;
   disp = BUFFER/10;
   
   DIGPORT = digit;
   WORDPORT = TABLE;
   
   for(delay = 0;delay <= 200;delay ++);
   digit = digit >> 1;
   }
}




该文章有附件资料,如需下载请访问 电脑版

网友评论

liyong7818 2014年07月11日
先谢谢分享,看后在发表意见