首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

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

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

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




先关的原理图请点击下载:
吴鉴鹰基于单片机的数字电子钟.pdf (295.38 KB, 下载次数: 29)
     现在来第一讲,详细解析如何制作基于单片机的数字时钟,提供详细的硬件原理图和软件程序。
开关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<reg52.h>
  • #include<absacc.h>
  • #define  uint unsigned int
  • #define  uchar  unsigned char
  • /*定义字型字位口*/
  • #define  DIGPORT  XBYTE  [0X8000]
  • #define  WORDPORT  XBYTE [0X4000]
  • /*定义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[2]  = {0,0};  //显示的缓存数组,依次为低位、高位
  • uchar  data  CLOCK[4] = {0,0,0,0};
  • uchar  data  SECOND[2] = {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] = 0;
  •                     SECOND[1] = 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[0] = SECOND[0];
  •          BUFFER[1] = SECOND[1];
  •       }break;
  •       case 5:
  •       {
  •           BUFFER[0] = CLOCK[2];
  •           BUFFER[1] = 101;/*A-*/
  •       }break;
  •       case 6:
  •       {
  •           BUFFER[0] = 110;/*A-*/
  •           BUFFER[1] = CLOCK[3];
  •       }break;
  •       default:
  •       {
  •           BUFFER[0] = CLOCK[2];
  •           BUFFER[1] = CLOCK[3];
  •       }break;
  •       default:
  •       {
  •           BUFFER[0] = CLOCK[2];
  •           BUFFER[1] = CLOCK[3];
  •       }
  •       }
  •      //显示函数
  •      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[0] = CLOCK[0]+1;
  • if((CLOCK[0] == 50) && (STATE >= 4))
  • {
  •     L0 = !L0;
  • }
  • if(CLOCK[0] == 100)
  • {
  •     if(STATE >= 4)  L0 = !L0;
  •     CLOCK[0] = 0;
  •     CLOCK[1] = CLOCK[1] + 1;
  •     if(CLOCK[1] == 60)
  •     {
  •        CLOCK[1] = 0;
  •     CLOCK[2] = CLOCK[2] + 1;
  •     if(CLOCK[2] == 60)
  •     {
  •         CLOCK[2] == 0;
  •      CLOCK[3] == CLOCK[3] + 1;
  •      if(CLOCK[3] == 24)
  •      {
  •         CLOCK[3] = 0;
  •      }
  •     }
  •     }
  • }
  • }
  • /******************************************************
  • *程序:子函数(2):intsvr1(void)
  • ** 功能描述:  对外中断1的按键脉冲进行判断和计数,并完成对应的时间调整功能。
  • ** 输 入:
  • ** 内容:
  • ** 输 出:
  • **
  • ** 全局变量:
  • ** 调用模块:
  • **
  • ** 作 者:    吴鉴鹰
  • ** 日 期:     14.02.17
  • 备注:有什么错误的地方,欢迎各大烧友指正
  • O(∩_∩)O~
  • *******************************************************/
  • void intsvr1(void) interrupt  2  using 2
  • {
  •    if(STATE == 5)
  •    {
  •        CLOCK[2] == CLOCK[2] + 1;
  •     if(CLOCK[2] == 60)  CLOCK[2] == 0;
  •    }
  •    if(STATE == 6)
  •    {
  •        CLOCK[3] == CLOCK[3] + 1;
  •     if(CLOCK[3] == 24)  CLOCK[3] = 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[disp];
  •    for(delay = 0;delay <= 200;delay ++);
  •    digit = digit >> 1;
  •    disp = BUFFER/10;
  •    DIGPORT = digit;
  •    WORDPORT = TABLE[disp];
  •    for(delay = 0;delay <= 200;delay ++);
  •    digit = digit >> 1;
  •    }
  • }

复制代码
返回列表