27389|51

1379

帖子

0

TA的资源

裸片初长成(中级)

楼主
 

用单片机做电子钟详解(转) [复制链接]

电路特点

这里介绍的电子钟,电路可称得上极简,它仅使用单片的20引脚单片机完成电子钟的全部功能,而笔者见到的其它设计方案均采用二片以上的多片IC实现。

电路见图1。


一片20引脚的单片机AT89C2051为电子钟主体,其显示数据从P1口分时输出,P3.0~3.3则输出对应的位选通信号。由于LED数码管点亮时耗电较大,故使用了四只PNP型晶体管VT1~VT4进行放大。本来笔者还有一种更简的设计方案(见图2),可省去VT1~VT4及R1~R4八个元件,但这种设计由于单片机输出口的灌入电流有限(约20mA),数码管亮度较暗而不向读者介绍,除非你采用了高亮度的发光数码管。


P3.4、P3.5、3.7外接了三个轻触式按键,这里我们分别命名为:模式设定键set(P3.4)、时调整键hour(P3.5)、分调整键min(P3.7)。C1、R13组成上电复位电路。VT5及蜂鸣器Bz为闹时讯响电路。三端稳压器7805输出的5V电压供整个系统工作。此电子钟可与任何9~20V/100mA的交直流电源适配器配合工作,适应性强。

电子钟功能

1.走时:通过模式设定键set选择为走时,U1、U2显示小时,U3、U4显示分。U2的小数点为秒点,每秒闪烁一次。

2.走时调整:通过模式设定键set选择为走时调整,按下hour键对U1、U2的走时“时”显示进行调整(每0.2秒递加1)。按下min键对U3、U4的走时“分”显示进行调整(每0.2秒递加1)。

3.闹时调整:通过模式设定键set选择为闹时调整,按下hour键对U1、U2的闹时“时”显示进行调整(每0.2秒递加1)。按下min键对U3、U4的闹时“分”显示进行调整(每0.2秒递加1)。

4.闹时启/停设定:通过模式设定键set选择为闹时启/停设定,按下min键U3的小数点点亮,闹时功能启动;按下hour键U3的小数点熄灭,闹时功能关停。

由于电路设计得极其简单,因此丰富的功能只能由软件完成,这里软件设计成为了关键。下面介绍软件设计要点。

图3为主程序状态流程。


 

图3

 

运行时建立的主要状态标志如下:

flag—掉电标志。掉电后,flag内为一随机数;重新设定时间后flag内写入标志数55H。

set—工作模式设定标志。

hour—走时“时”单元。

min—走时“分”单元。

sec—走时“秒”单元。

deda—走时5mS计数单元

t_hour—闹时“时”单元。

t_min—闹时“分”单元。

d_05s—0.5秒位标志。每秒钟的前0.5秒置1,后0.5秒置0,以使秒点闪烁。

o_f—闹时启/停位标志。闹时启动置1,闹时关停置0。

另外将定时器T0设定为5mS的定时中断。这里晶振频率为12MHz,因此5mS的初值为-5000,但实际上程序还要作其它运算,使得时间偏长,经调整为-4800后试验刚好。计时单元deda每次中断均加1。走时函数判断deda>=200时即令秒单元sec加1。同理秒单元sec满60后令分单元min加1。分单元min满60后令时单元hour加1。时单元hour满24后清0。

上电后,首先进行初始化,对各状态标志、输入输出口及定时器T0进行初始化工作,以适应后面程序的要求。

随后程序判断有无set键按下,如按下,则set键值从0起加1。set键值只能从0加到3,然后又回到0。

接下来,根据键值进行散转。若set=0,运行走时程序;若set=1,进入调整闹时时间程序;若set=2,进入调整走时时间程序;若set=3,显示已调好的闹时时间,同时进入启/停闹时程序。

散转完后,进行判断掉电标志flag是否等于55H。若不等,说明刚开机上电或运行过程中掉过电,这时四个数码管以1Hz的频率闪烁四个8字,提示时间不准;若相等,说明未掉电,RAM区内容未变化,时间准确。

再下来程序又转回到初始化之后进行循环运行。

由于使用了四只数码管密集排列,因此只能采用双面印刷板设计,图4、5分别为正面(元件面)、反面的印板图。尺寸3000milx4000mil(7.62cmx10.16cm)。图6为计算机输出的三维仿真印制板。


图4

 


图5

 


图6

元件选用

为了走时准确,晶振X最好选用温漂小的。四个数码管U1~U4可选用发绿光的,这样光泽较柔和。蜂鸣器Bz要购买绕线型的电动式蜂鸣器(市场上有一种加电压即工作的蜂鸣器这里不适用),因驱动信号为脉冲信号。其它元件一般无特殊要求。

使用方法

上电后,四个LED数码管闪烁四个8字。

按一下set键,闪烁现象消失(此时set=1),U1的小数点亮,说明此刻可以调整闹时时间。按下hour键,U1、U2作加法;按下min键,U3、U4作加法。这些调整好的数据被同时送入RAM区的闹时记忆“时”单元t_hour和闹时记忆“分”单元t_min。

再按一下set键,set=2,U2的小数点亮,此刻可以调整走时时间。按下hour键,U1、U2作加法;按下min键,U3、U4作加法。这些调整好的数据也被同步送入RAM区的“时”记忆单元hour和“分”记忆单元min。

再按一下set键,set=3,显示刚才调整的闹时时间,此刻可以选择启动/关停闹时。按下min键,o_f位标志置1,U3的小数点亮,闹时启动;按下hour键,o_f位标志置0,U3的小数点灭,闹时关闭。

若再按一下set键,set=0,电路进入走时状态,U1、U2显示小时,U3、U4显示分。U2的小数点作秒点闪烁。

在闹时启动的情况下,走时到达设定闹时,则蜂鸣器Bz鸣响一分钟进行提醒。

附:用C51编写的源程序清单(已由实验板运行通过)

#include                        /*包含器件配置文件*/

#define uchar unsigned char

#define uint unsigned int

char DATA_7SEG[10]={0xC0,0xF9,0xA4,0xB0,0x99,

                    0x92,0x82,0xF8,0x80,0x90,};/*0~9的数码管段码*/

uchar hour=0,min=0,sec=0;                /*时、分、秒单元清零*/

uchar deda=0;                                  /*5mS计数单元清零*/

uchar t_hour=0,t_min=0;                   /*闹时时、分单元清零*/

bit d_05s=0;                             /*0.5秒标志*/

bit o_f=0;                                         /*闹时启/停标志*/

uchar set=0;                                      /*模式设定标志*/

uchar m=0;

uchar flag=0;                                     /*RAM掉电标志*/

void delay(uint k);                              /*延时子函数*/

void conv();                                       /*走时单元转换*/

void p_out();                                      /*判别闹时到否子函数*/

void dirve();                                       /*走时时间输出驱动子函数*/

void t_dirve();                                    /*闹时时间输出驱动子函数*/

 

 

/*闹时启/停子函数*/

void time1_of()                                 

{uchar m;

       if(P3_7==0)delay(1);

       if(P3_7==0)o_f=1;

       for(m=0;m<30;m++)

              {

              t_dirve();

              P1=DATA_7SEG[t_min/10];P3=0xfd;delay(1);

              if(P3_1==0){if(o_f==1)P1_7=0;}else P1_7=1;

              delay(1);

              }

             

       if(P3_5==0)delay(1);

       if(P3_5==0)    o_f=0;

       for(m=0;m<30;m++)

              {

              t_dirve();

              P1=DATA_7SEG[t_min/10];P3=0xfd;delay(1);

              if(P3_1==0){if(o_f==1)P1_7=0;else P1_7=1;}

              delay(1);

              }

}

 

/*走时函数*/

void time()

{

conv();                                              /*走时单元转换*/

dirve();                                              /*走时时间输出驱动子函数*/

p_out();                                             /*判别闹时到否子函数*/

}

 

 

/*定时器T0  5mS初始化*/

void init_timer()

{

TMOD=0x01;

TH0=-(4800/256);

TL0=-(4800%256);

IE=0x82;

TR0=1;

}

 

/*扫描按键子函数*/

void scan_key()

{

delay(1);

if(P3_4==0)set++;

if(set>=4)set=0;

if(set==1)flag=0x55;

F0:if(P3_4==0)goto F0;                      /*按键未释放,在此等候*/

}

 

 

/*延时子函数*/

void delay(uint k)

{

uint i,j;

for(i=0;i
for(j=0;j<121;j++)

{;}}

}

 

/*5mS定时中断服务子函数*/

void zd(void) interrupt 1

{

TH0=-(4800/256);

TL0=-(4800%256);

deda++;

}

 

/*调整走时时间*/

void time_adj()

{uchar m;

       if(P3_5==0)delay(1);

       if(P3_5==0)hour++;

       if(hour==24)hour=0;

       for(m=0;m<30;m++)

              {

              dirve();

              if(P3_2==0)P1_7=0;

              else P1_7=1;

              delay(1);

              }

             

       if(P3_7==0)delay(1);

       if(P3_7==0)min++;

       if(min==60)min=0;

       for(m=0;m<30;m++)

              {

              dirve();

                     if(P3_2==0)P1_7=0;

              else P1_7=1;

              delay(1);

              }

}

 

 

/*调整闹时时间*/

void time1_adj()

{uchar m;

       if(P3_5==0)delay(1);

       if(P3_5==0)t_hour++;

       if(t_hour==24)t_hour=0;

       for(m=0;m<30;m++)

              {

              t_dirve();

              }

      

       if(P3_7==0)delay(1);

       if(P3_7==0)t_min++;

       if(t_min==60)t_min=0;

       for(m=0;m<30;m++)

              {

              t_dirve();

              }

}    

 

/*时、分、秒单元及走时单元转换*/

void conv()

{

if(deda<=100)d_05s=0;

       else d_05s=1;

if(deda>=200){sec++;deda=0;}

if(sec==60){min++;sec=0;}

if(min==60){hour++;min=0;}

if(hour==24){hour=0;}

}

 

/*走时时间输出驱动子函数*/

void dirve()

{

P1=DATA_7SEG[hour/10];P3=0xf7;delay(1);

P1=DATA_7SEG[hour%10];P3=0xfb;delay(1);

if(d_05s==1){if(P3_2==0)P1_7=0;else P1_7=1;}

delay(1);

P1=DATA_7SEG[min/10];P3=0xfd;delay(1);

if(o_f==1){if(P3_1==0)P1_7=0;else P1_7=1;delay(1);}

P1=DATA_7SEG[min%10];P3=0xfe;delay(1);

}

 

/*闹时时间输出驱动子函数*/

void t_dirve()

{

P1=DATA_7SEG[t_hour/10];P3=0xf7;delay(1);

if(P3_3==0)P1_7=0;else P1_7=1;

delay(1);

P1=DATA_7SEG[t_hour%10];P3=0xfb;delay(1);

P1=DATA_7SEG[t_min/10];P3=0xfd;delay(1);

P1=DATA_7SEG[t_min%10];P3=0xfe;delay(1);

}

 

 

/*判别闹时到否子函数*/

void p_out()

{

if(o_f==1){

       if(t_hour==hour){if(t_min==min)

              if(P3_0==0){P1_7=0;delay(1);}

              else P1_7=1;

                                   }

              }

}

 

/*主函数*/

void main()

{

       init_timer();                       /*定时器T0初始化*/

       while(1)                                     /*无限循环*/

       {

       if(P3_4==0)scan_key();               /*有按键,调用按键扫描子函数*/

switch(set)                                        /*根据set键值散转*/

{

case 0:time();break;                                   /*走时时间程序*/

case 1:time1_adj();break;                     /*闹时时间调整*/

case 2:time_adj();break;                      /*走时时间调整*/

case 3:time1_of();break;                      /*启/停闹时*/

default:break;                                     /*其它退出*/

}

       if(flag!=0x55)                             /*判断掉电标志*/

       {for(m=0;m<100;m++)               /*点亮四个8字400mS*/

              {

              P1=0x80;P3=0xf7;delay(1);

              P1=0x80;P3=0xfb;delay(1);

              P1=0x80;P3=0xfd;delay(1);

              P1=0x80;P3=0xfe;delay(1);

              }

             

              P1=0xff;P3=0xff;delay(400); /*熄灭四个8字400mS*/

       }

       }

}

 

 

 
此帖出自单片机论坛

最新回复

又见时钟!! 大二选的单片机选修课, 就用51做了个时钟, 手工焊接!动态显示, 用的51内部的定时器, 老师很给力的给了个最高分!  详情 回复 发表于 2014-12-19 00:45
点赞 关注
 

回复
举报

1

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

Re: 用单片机做电子钟详解(转)

顶两下。
此帖出自单片机论坛
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

Re: 用单片机做电子钟详解(转)

感谢无私奉献
此帖出自单片机论坛
 
 
 

回复

1284

帖子

0

TA的资源

五彩晶圆(中级)

4
 

Re: 用单片机做电子钟详解(转)

xixi
此帖出自单片机论坛
 
个人签名呼呼...在校应届大四学生,代做电子类毕业设计(测量类、仪器类、控制类、无线通信类、电子产品类、界面设计类、纯论文类等等,一一俱全)。涉及各种单片机软硬件设计、电路模拟分析、FPGA、CPLD、ARM7/ARM9、LINUX、VB/VC++/QT界面等等。包过。。。欢迎咨询。Tel:13957160506。QQ:273437087
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

5
 

Re: 用单片机做电子钟详解(转)

谢谢分享!!!
此帖出自单片机论坛
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(初级)

6
 

Re: 用单片机做电子钟详解(转)

不错啊
此帖出自单片机论坛
 
 
 

回复

105

帖子

0

TA的资源

纯净的硅(中级)

7
 

Re: 用单片机做电子钟详解(转)

程序直接能不能用?
此帖出自单片机论坛
 
个人签名大道至简
 
 

回复

106

帖子

0

TA的资源

纯净的硅(中级)

8
 

Re: 用单片机做电子钟详解(转)

有没有汇编的程序啊
此帖出自单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

9
 

Re: 用单片机做电子钟详解(转)

认真的看~
此帖出自单片机论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

10
 

Re: 用单片机做电子钟详解(转)

认真的看~跟自己的程序对比下~~
此帖出自单片机论坛
 
 
 

回复

1284

帖子

0

TA的资源

五彩晶圆(中级)

11
 

Re: 用单片机做电子钟详解(转)

晕。。。好长
此帖出自单片机论坛
 
个人签名呼呼...在校应届大四学生,代做电子类毕业设计(测量类、仪器类、控制类、无线通信类、电子产品类、界面设计类、纯论文类等等,一一俱全)。涉及各种单片机软硬件设计、电路模拟分析、FPGA、CPLD、ARM7/ARM9、LINUX、VB/VC++/QT界面等等。包过。。。欢迎咨询。Tel:13957160506。QQ:273437087
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

12
 

Re: 用单片机做电子钟详解(转)

不错呀
此帖出自单片机论坛
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(初级)

13
 

Re: 用单片机做电子钟详解(转)

好贴,顶~
此帖出自单片机论坛
 
 
 

回复

6

帖子

0

TA的资源

一粒金砂(初级)

14
 

Re: 用单片机做电子钟详解(转)

好贴好贴!!!顶顶
此帖出自单片机论坛
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(初级)

15
 

Re: 用单片机做电子钟详解(转)

顶起!!
此帖出自单片机论坛
 
 
 

回复

1284

帖子

0

TA的资源

五彩晶圆(中级)

16
 

Re: 用单片机做电子钟详解(转)

扶你一吧
此帖出自单片机论坛
 
个人签名呼呼...在校应届大四学生,代做电子类毕业设计(测量类、仪器类、控制类、无线通信类、电子产品类、界面设计类、纯论文类等等,一一俱全)。涉及各种单片机软硬件设计、电路模拟分析、FPGA、CPLD、ARM7/ARM9、LINUX、VB/VC++/QT界面等等。包过。。。欢迎咨询。Tel:13957160506。QQ:273437087
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

17
 

Re: 用单片机做电子钟详解(转)

好贴!!顶了!
此帖出自单片机论坛
 
 
 

回复

105

帖子

0

TA的资源

纯净的硅(中级)

18
 

Re: 用单片机做电子钟详解(转)

用KEILC编译报错!!
此帖出自单片机论坛
 
个人签名大道至简
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

19
 
谢谢好贴,正是我想要的,再次感谢
此帖出自单片机论坛
 
 
 

回复

6

帖子

0

TA的资源

一粒金砂(初级)

20
 
谢  谢!!
此帖出自单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表