单片机电子钟程序_电子钟单片机程序 - CSDN
  • 基于51单片机电子时钟(数码管显示)

    万次阅读 多人点赞 2018-05-20 08:30:59
    此次对于数码管进行一个简单的应用,同时可以设计一个电子小时,增加趣味性。首先我们先进行原理图的讲解,这里我们直接使用的开发板,其原理连接图如下: 从图中,我们可以看到,第一个74HC573是来控制8个数码管...

         此次对于数码管进行一个简单的应用,同时可以设计一个电子小时钟,增加趣味性。

    首先我们先进行原理图的讲解,这里我们直接使用的开发板,其原理连接图如下:





    其中D(0~1)是连接在单片机的P0口上的。

       从图中,我们可以看到,第一个74HC573是来控制8个数码管的位选的,就是说我要选种哪个数码管,这里的WE是低电平有效,比如说我想选中最后一个数码管,那么这里我就要将0x7f送到相应的I/O口。第二个74HC573是来控制数码管显示什么的这里0~9的16进制码如下:

    0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f;

    要想完成电子时钟,我们先要显示一个数值,

    这里我们封装两个函数:

    wirte_address(unsigned char);

    write_date(unsigned int);

    第一个函数是用来写地址的,就是用来选中数码管的;

    第二个函数是用来写数据的,就是选中的数码管显示什么。

    比如我们想在最后一个数码管上显示一个8;

    那么则有:

    write_address(0x7f);

    write_date(0x7f);

    这样就能在相应的位置上显示一个8了;


       然后我们就要多个位置显示,这里我们硬件的P0口接的是数码管,同时我们要引进相应的延时函数delay(unsigned int);

    我们利用发光管的余辉和人眼视觉暂留作用,让人眼无法分辨出来,从而达到“同时显示的效果”。

    但是我们需要注意的是消影,在每次写入之前令P0=0xff,这是为了消除上次段选数据,否则会造成,显示混乱。


      当我们能显示时,就需要了解定时器,让它来计时,然后将数值取出,进行显示。这里我们的晶振是12MHz,所以一个机械周期时1/12MHz=1us,为了使计时较为精确,我们这里选择定时器0的模式2,8位重装定时器,并且我们100us进入一次中断,定时器的初始化就该如下:

    TMOD=0x02;

    TH0=256-100;

    TL0=256-100;

    EA=1;

    ET0=1;

    TR0=1;


        这样我们再定义一个n用来计数进入中断的次数,当n的10000时,就表示1s到了,所以我们需要对相应的变量进行处理。

         那么我们需要对数据进行处理,比如,所得的秒的值,其十位=秒/10,其个位就等于秒%10,其它以此类推。


    那么整个的程序代码如下:

    #include<reg52.h>
    #define uint unsigned int
    #define uchar unsigned char
    
    uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};	 //数码管位选数据
    sbit dula=P2^6;//段选信号,写数码管数据
    sbit wela=P2^7;//位选信号,选择数码管
    
    uint miao=0;		//秒
    uint fen=0;			//分
    uint shi=0;		    //时
    uint n=0;			//计数
    uint date[6]={0,0,0,0,0,0};	  //定义一个有6个地址的数组,分别存时,分,秒的个位和十位。
    void delay(uint z)			 //延时函数
    {
         uint x,y;
    	 for(x=z;x>0;x--)
    	  for(y=50;y>0;y--);
    }
    
    void write_address(uchar address)		 //写地址函数,选择数码管
    {
        wela=1;
    	P0=address;
    	wela=0;
    }
    
    void write_date(uint n)				     //写数据函数,送入段选信号
    {
         dula=1;
    	 P0=table[n];
    	 dula=0;
    }										//显示函数
    void display()
    {	 	 
           write_date(date[0]);
          P0=0xff;
          write_address(0x7f);
           delay(1);
    
    
         write_date(date[1]);
    	 P0=0xff;
    	 write_address(0xbf);
    	 delay(1);
    
    	 write_date(date[2]);
    	 P0=0xff;
    	 write_address(0xef);
    	 delay(1);
    	 
    
    	 write_date(date[3]);
    	 P0=0xff;
    	 write_address(0xf7);
    	 delay(1);
    
    	 write_date(date[4]);
    	 P0=0xff;
    	 write_address(0xfd);
    	 delay(1);
    
    
    	 write_date(date[5]);
    	 P0=0xff;
    	 write_address(0xfe);
    	 delay(1);
    
    	 
    }
    void time_init()						   //定时器初始化函数
    {
        TMOD=0x02;							  //选择方式2
    	TH0=156;							  //重装初值为156
    	TL0=156;							  //运行值为156
    	EA=1;								  //开总中断
    	ET0=1;								  //开定时器0中断
    	TR0=1;								  //开定时器0
    }
    
    void main()
    {
       dula=0;								   //先关闭位选,段选信号。
       wela=0;
       time_init();
       while(1)
       {
           display();
       }
    
        
    }
    
    
    
    void timer() interrupt 1					  //定时器0中断
    {
         n++;
    	 if(n==10000)								 //当n=10000时,表示1s到了
    	 {	 
    	     n=0;
    	     miao++;
    		 if(miao==60)
    		 {
    		     miao=0;
    		     fen++;
    			 if(fen==60)
    			 {
    			     fen=0;
    				 shi++;
    				 if(shi==24)
    				 {
    				    shi=0;
    				 }
    			 }
    		 }
    		 date[0]=miao%10;
    		 date[1]=miao/10;
    		 date[2]=fen%10;
    		 date[3]=fen/10;
    		 date[4]=shi%10;
    		 date[5]=shi/10;
    	
    	 }
    
    	  
    }

    其效果图如下:








    展开全文
  • 电子钟已经全部测试OK,带闹钟功能,年月日时分秒星期温度,四个按键可设置闹钟调节时间,温度可以显示正125度到负的55度之间,时间走时的话,我测试了一个月,误差不到1分钟。本人已经录制成视频,视频里面有详细...
  • 基于51单片机电子时钟

    万次阅读 多人点赞 2020-07-23 20:41:02
    1 基于51单片机用LCD1602实现时-分的显示 2. 按键控制时-分的调整 3. 能实现整时报时的功能(蜂鸣器响) 4. 闹钟模式 5.按键切换模式(模式一:时-分显示,模式二:60秒倒计时) 一、设计思路: 主体: 通过外部中断...

    1 基于51单片机用LCD1602实现时-分的显示
    2. 按键控制时-分的调整
    3. 能实现整时报时的功能(蜂鸣器响)
    4. 闹钟模式
    5.按键切换模式(模式一:时-分显示,模式二:60秒倒计时)

    一、设计思路:
    主体:
    通过外部中断0来控制mod值;mod=0,1.2,3分别对应时钟模式,调整模式,闹钟设置模式,一分钟倒计时模式。
    细节:
    mod0
    通过定时计数器,每一秒增加变量秒(s),每60秒,增加1分(min)并且s置0,每60min,增加1小时h,当h>23,h=0;进行一天循环
    mod1
    按键控制增加min,h和s制0
    mod2
    另外设置变量min1,h1,当min=min1,h=h1时蜂鸣器响
    mod3
    设置变量daojishi=60, 通过定时计数器,每一秒daojishi减1,当daojishi<0时,蜂鸣器响
    另外:
    1.设置外部中断2,关闭蜂鸣器
    2.时间发送一次只能发送一个位

    程序:

    #include<reg52.h>
    //K1后K3加分钟,K4加时间,K2加秒,K1进入闹钟设置,K2退出
    //K2关闭闹钟
    
    typedef unsigned int u16;	  //对数据类型进行声明定义
    typedef unsigned char u8;
    
    #define data8b P1
    
    sbit K1=P3^2;               //外部中断0
    sbit K2=P3^3;               //外部中断1
    sbit K3=P3^0;
    sbit K4=P3^1;
    
    sbit BUZ=P2^4;       //蜂鸣器,0响
    sbit RW=P2^5;        //4脚,数据(1)or命令(0)
    sbit RS=P2^6;        //5脚,读(1)写(0)
    sbit E=P2^7;         //6脚,使能信号
    
    u8 code dat1[]={0X30,0X31,0X32,0X33,
    	                               0X34,0X35,0X36,0X37,
    	                               0X38,0X39};
    
    void delay(u16 i)      //延时函数
    {
    	while(i--);
    }
    
    void open012()   //打开中断0,1,定时器中断0
    {
    	TMOD|=0X01;   //选择为定时器0模式,工作方式1
      
    	
    	ET0=1;        //打开定时器0中断允许
    	
    	EA=1;        //打开总中断
    	
    	TR0=1;       //打开定时器			
    	
    	EX0=1;              //打开外部中断0
    	IT0=1;             //边沿触发方式
    	EX1=1;              //打开外部中断1
    	IT1=1;             //边沿触发
      
    }
    
    
    void wrm(u8 dat)              //写入命令
    {
    	delay(1000);
    	RS=0;
    	RW=0;
    	E=0;
    	data8b=dat;
    	E=1;
    	delay(1000);
    	E=0;
    }
    
    
    void wrd(u8 dat)             //写入数据
    {
    	delay(1000);
    	RS=1;
    	RW=0;
    	E=0;
    	data8b=dat;
    	E=1;
    	delay(1000);
    	E=0;
    }
    
    void zero()
    {
    	wrm(0X38);                 //八位数据,两行显示,5*7
    	wrm(0X0c);                  //无光标,打开显示
    	wrm(0X06);                  //光标右移,屏幕不移动
    	wrm(0X01);                  //清屏
    	wrm(0X80);                  //设置数据指针起点
    }
    
    u8 fg=0,sg=0,bfg=0,bsg=0;
    u16 i=0;
    u8 s=0;
    u8 mod=0;
    char dingshi;
    bit bell=0;
    bit zanting=1;
    
    void fangsong()
    {
      wrd(dat1[sg/10]);                 //时十位
    	wrd(dat1[sg%10]);                 //时个位
    	wrd(0x3A);                     //:
    	wrd(dat1[fg/10]);                 //分十位
    	wrd(dat1[fg%10]);                 //分个位
    	wrd(0x3A);                     //:
    	wrd(dat1[(s/10)]);                 //秒十
    	wrd(dat1[(s%10)]);                 //秒个
    }
    
    
    void fangsong1()
    {
    	wrm(0X80);   
      wrd(dat1[sg/10]);                 //时十位
    	wrd(dat1[sg%10]);                 //时个位
    	wrd(0x3A);                     //:
    	wrd(dat1[fg/10]);                 //分十位
    	wrd(dat1[fg%10]);                 //分个位
    	wrd(0x3A);                     //:
    	wrd(dat1[(s/10)]);                 //秒十
    	wrd(dat1[(s%10)]);                 //秒个
    }
    void chuli()
    {
    	if(fg==60)
    	{
    		sg++;
    		fg=0;
    	}
    
    	if(sg==24)
    	{
    	
    		sg=0;
    	}
    	
    }
    
    
    
    void main()
    {
    	u8 shijian;
    	open012();
    	zero();
    	chuli();
    	fangsong();
    	shijian=100;
    	
    	
    	while(1)
    	{
    		while(mod==0)
    	{
    		EX1=1;              //打开外部中断1
    		if(s==60)
    		 {
    			 fg++;       //60秒转化为1分钟
    			 s=0;
    		 }
    				chuli();
    				if((fg==0)&&(shijian!=sg))
    				 {
    				  BUZ=0;
    					shijian=sg;
    				 }
    				fangsong1();
    				if((BUZ==0)&&(bell==0))
    			  {
    				delay(1000);
    				BUZ=1;
    			  }
    			if((fg==bfg)&&(sg==bsg)&&(bell==1))
    				BUZ=0;
    			else BUZ=1;
    			}
    	
    	
    			
    			while(mod==1)
    		{
    			EX1=0;              //关闭外部中断1
    			zero();
    	    fangsong();
    			if(K3==0)
    			  {
    				  delay(1000);
    				  if(K3==0)
    					  fg++;
    			   }
    			if(K4==0)
    			   {
    				  delay(1000);
    				  if(K4==0)
    					 sg++;
    			   }
    				 if(K2==0)
    			   {
    				  delay(1000);
    				  if(K2==0)
    					 s=0;
    			   }
    				 if(fg>59)
    				 {
    					 fg=0;
    				 }
    				  if(sg>23)
    				 {
    					 sg=0;
    				 }
    				 if(s>=59)
    				 {
    					 s=0;
    				 }
    	     }
    		
    			 
    			 
    			 while(mod==2)   //设置闹钟
    		{
    	    if(bfg==60)
    	    {
    		    bsg++;
    		    bsg=0;
    	    }
    	
    	    if(bsg==24)
    	    {
    		     bsg=0;
    	     }
    	    zero();
    			wrd(0x20);
    			wrd(0x20);
    			wrd(0x20);
    		  wrd(dat1[(bsg/10)]);                 //时十位
    	    wrd(dat1[(bsg%10)]);                 //时个位
    	    wrd(0x3A);                     //:
    	    wrd(dat1[(bfg/10)]);                 //分十位
    	    wrd(dat1[(bfg%10)]);                 //分个位
    			 if(K3==0)
    			{
    				delay(1000);
    				if(K3==0)
    					bfg++;
    			}
    			if(K4==0)
    			{
    				delay(1000);
    				if(K4==0)
    					bsg++;
    			}
    			bell=1;
    			zero();
    }
    		
    while(mod==3)
    {
    	while(zanting)
    	{
    	dingshi=60;
    	EX1=1;              //打开外部中断1
    	wrm(0X80);   
    	 wrd(dat1[(dingshi/10)]);                 //时十位
    	 wrd(dat1[(dingshi%10)]);            	//时个位
       }
       wrm(0X80);   
    	 wrd(dat1[(dingshi/10)]);                 //时十位
    	 wrd(dat1[(dingshi%10)]);            	//时个位	
    	while(dingshi<0)
    	{
    		wrm(0X80);   
    		 wrd(dat1[0]);                 //时十位
    	   wrd(dat1[0]);            	//时个位
    		BUZ=0;
    	}
    }
    }
    }
    
    void time0() interrupt 1
    {
       TH0=0XFC;	     //给定时器赋初值,定时1ms
    	 TL0=0X18;
    	 i++;
    	 if(i==1000)     //ms转化为s
    	 {
    		i=0;
    		 s++;
    		 dingshi--;
    	 }	
    }
    
    void key1() interrupt 0     //外部中断0,调整时间
    {
    	delay(1000);
    	if(K1==0)
    	  { 
    		  mod++;
    			while(!K1);
    	  }
    
    if(mod>3)
    {
    	mod=0;
    }
    	 zero();
    }
    
    void naozhong()  interrupt 2                     //开关闹钟
    {
    	if(K2==0)
    		{
    			delay(1000);           //消抖
    				if(K2==0)
    					{
    						bell=0;
    						BUZ=1;
    						zanting=~zanting;
    					}                       //关闭蜂鸣器
    						while(!K2);          //确认按键松开
         }
    }
    
    
    
    

    在这里插入图片描述

    二、收获
    1.更熟练掌握了定时器中断和外部中断的使用
    在这里插入图片描述

    在这里插入图片描述

    可以通过打开和关闭外部中断使同一个按键实现不同的功能

    2.了解到了一点寄存器操作

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    3.中断配置小结
    外部中断
    在这里插入图片描述
    定时器中断
    在这里插入图片描述

    串口通信
    在这里插入图片描述
    4.更熟练使用proteus
    制作了一个小型软件开发版
    在这里插入图片描述

    5.学会了如何学习一个新元器件(LCD1602)
    1.看说明书,重点是看时序图,真值表等
    2.按照时序图写程序
    3.一二都不成立时,查找相关资料
    6.下载原理
    单片机的烧写原理:
    单片机烧写,又称为单片机程序下载、烧录等,本质上是单片机和PC机按照芯片厂家规定的编程协议,通过芯片厂家规定的接口,把已编译好的程序传输到单片机,单片机把数据存储到自身存储器中。
    理解这个原理需要知道几个知识点:
    单片机内部是有程序的,是出厂时固化在硬件中,用户无法修改的(这也会被认为它内部没有程序),这些程序可以调用各种通信接口、内部存储器等;
    可以下载的通信接口:JTAG,SPI,UART,usb等;(还有很多可以扩展485、以太网等)
    编程协议:一般大厂都会公开的,在芯片的专用技术手册中会有;
    存储器:有很多种,掩膜,EPROM,EEROM,flash等寿命不一样,掩膜只能一次,而且要工厂做,flash擦写次数10000+;
    可以这样比喻性的理解:单片机就是电脑的主板,我们写的程序就是操作系统,主板里面装入引导操作系统的基本程序,下载程序就是给电脑装系统!

    7.其他
    1.理解了现在电子表的操作原理
    2.学会了借助现成品(电子表)作参考,写程序
    3.懂得了与人交流的重要性(受王同学的启发,完善了原有程序)

    三.后期计划
    1、继续32的学习
    2、练习焊功
    3、继续51其他外设的学习
    4、按兴趣学习电路、模电、数电、DXP等相关知识

    展开全文
  • 用51单片机做一个电子钟

    万次阅读 多人点赞 2018-06-04 22:17:25
    学了一个多月51了,终于整了个电子钟出来,个人感觉还是比较有趣的。 需要注意的是我用的是普中的板子,板子类型不同,io口的功能可能会有所差异。然后我这个k1开关和k2开关是接反了的,原本k1应该是接P3^0,k2接P3...

        学了一个多月51了,终于整了个电子钟出来,个人感觉还是比较有趣的。
        需要注意的是我用的是普中的板子,板子类型不同,io口的功能可能会有所差异。然后我这个k1开关和k2开关是接反了的,原本k1应该是接P3^0,k2接P3^1的,结果我一测试才知道k1接到了P3^1,k2接到P3^0了,不过这不要紧,用sbit定义位变量时注意换一下就可以了。然后大概讲讲功能,用8个数码管显示目前时间和闹铃时间,然后用4个独立按键对目前时间和闹铃时间进行调整(k2是加,k3是减 ,k4是用来停止闹铃的),第一次按k1是对目前时间秒数调整,第2次按k1是对目前时间分钟数调整,第三次按k1是对目前时间小时数调整,第4次按k1是对闹铃秒数调整,第5次按k1是对闹铃时间分钟数调整,第6次按k1是对闹铃秒数调整,第7次按k1是调整完毕,进去非调整状态即实时显示目前时间(不过有点差异,时间走的快了一点)。主要用到了数码管动态显示,独立按键,定时器中断这些。

    代码如下:
    #include<reg52.h>
    typedef unsigned int u16;
    typedef unsigned char u8;
    sbit led=P2^0;
    sbit lsa=P2^2;
    sbit lsb=P2^3;
    sbit lsc=P2^4;
    sbit beep=P1^5;
    sbit k1=P3^1;
    sbit k2=P3^0;
    sbit k3=P3^2;
    sbit k4=P3^3;
    sbit dian=P0^7;
    
    u8 keyvalue,alarmexist=0;
    u8 smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x00};//段选码,分别对应0到无
    u16 cnt=0,i=0,j=0,flag=0,time[]={0,0,0,0,0,0,0,0};//只用数码管0,1 3,4 6,7
    u16 alarm[]={0,0,0,0,0,0,1,0};
    u16*p;
    
    
    void delay(u16 mmp);
    void t0andt1init();
    void addproct(int x);						    
    void addproca(int x);
    void reduceproct(int x);
    void reduceproca(int x);
    void keyscan();
    void jia();
    void jian();
    
    void main()
    {
      	led=0;
        t0andt1init();
    	P0=0x00;
    	while(1)
    	{   
    	    
    		if(time[0]==alarm[0]&&time[1]==alarm[1]&&time[3]==alarm[3]&&time[4]==alarm[4]&&time[6]==alarm[6]&&time[7]==alarm[7])//满足条件 蜂鸣器以一定的时间间隔响,只到K4按键并松开,此时数码管任然正常显示当前时间
    		{   
    			alarmexist=0;
    			while(k4)
    			{
    				beep=~beep;
    				delay(25);
    				beep=~beep;
    				delay(25);
    			}
    		}
    		keyscan();
    	}
    }
    void delay(u16 mmp)
    {
    	while(mmp--);
    }
    void t0andt1init()
    {
    	TMOD=0x11;
    	TH0=0xfc;
    	TL0=0x67;//赋定时器初始值,定时1ms
    	TH1=0xfc;
    	TL1=0x67;
    	TR0=1;//T0定时器开始定时
    	EA=1;
    	ET0=1;
    	ET1=1;	
    }
    void addproct(int x)	  //对非调整状态和调整状态的加1处理(仅用于对当前时间)
    {
    	if(x==0||x==3||x==6)
    		if(time[x]==10)
    		{
    			time[x]=0;
    			time[x+1]=time[x+1]+1;
    			addproct(x+1);
    		}
       
       	if(x==1||x==4)
       		if(time[x]==6)
    		{
    			time[x]=0;
    			time[x+2]=time[x+2]+1;
    			addproct(x+2);
    		}
    	if(time[6]==4&&time[7]==2)
    		time[6]=time[7]=0;		
    }
    void addproca(int x)	  //对调整状态的加1处理(仅用于对闹钟时间)
    {
    	if(x==0||x==3||x==6)
    		if(alarm[x]==10)
    		{
    			alarm[x]=0;
    			alarm[x+1]=alarm[x+1]+1;
    			addproca(x+1);
    		}
       
       	if(x==1||x==4)
       		if(alarm[x]==6)
    		{
    			alarm[x]=0;
    			alarm[x+2]=alarm[x+2]+1;
    			addproca(x+2);
    		}
    	if(alarm[6]==4&&alarm[7]==2)
    		alarm[6]=alarm[7]=0;		
    }
    void reduceproct(int x) // 对调整状态的减1处理(仅用于对当前时间)
    {
    	if(time[0]==0&&time[1]==0&&time[3]==0&&time[4]==0&&time[6]==0&&time[7]==0)
    	{
    		time[0]=time[3]=9;
    		time[1]=time[4]=5;
    		time[6]=3;
    		time[7]=2;
    		return ;
    	}
    	if(x==0||x==3||x==6)
    	{
    		if(time[x]>=1)
    			time[x]=time[x]-1;
    		else
    		{   
    			if(time[7]==0&&x==6)
    			{
    				time[6]=3;
    				time[7]=2;
    			}
    			else
    			{
    				time[x]=9;
    				reduceproct(x+1);	
    			}
    		}
    		
    	}
    	else
    	{
    		if(time[x]>=1)
    			time[x]=time[x]-1;
    		else
    		{
    			time[x]=5;
    			if(x!=7)
    				reduceproct(x+2);
    			else
    				time[x]=1;
    		}
    	}
    	
    }
    void reduceproca(int x) // 对调整状态的减1处理(仅用于对闹钟时间)
    {
    	if(alarm[0]==0&&alarm[1]==0&&alarm[3]==0&&alarm[4]==0&&alarm[6]==0&&alarm[7]==0)
    	{
    		alarm[0]=alarm[3]=9;
    		alarm[1]=alarm[4]=5;
    		alarm[6]=3;
    		alarm[7]=2;
    		return ;
    	}
    	if(x==0||x==3||x==6)
    	{
    		if(alarm[x]>=1)
    			alarm[x]=alarm[x]-1;
    		else
    		{   
    			if(alarm[7]==0&&x==6)
    			{
    				alarm[6]=3;
    				alarm[7]=2;
    			}
    			else
    			{
    				alarm[x]=9;
    				reduceproca(x+1);	
    			}
    		}
    		
    	}
    	else
    	{
    		if(alarm[x]>=1)
    			alarm[x]=alarm[x]-1;
    		else
    		{
    			alarm[x]=5;
    			if(x!=7)
    				reduceproca(x+2);
    			else
    				alarm[x]=1;
    		}
    	}
    	
    }
    void keyscan()
    {   
    	flag=0;
    	keyvalue=0;
        if(k1==0)
    	{   
    	    TR0=0;//不在显示当前时间
    		TR1=1;
    	    delay(1000);
    		if(k1==0)
    		{   
    			while(!k1) ;
    			delay(1000);
    			led=~led;
    		    keyvalue++;
    		}
    		else
    			return ;
    		
    		while(keyvalue!=7)
    		{
    			if(k1==0)
    			{   
    			    delay(1000);
    				if(k1==0)
    				{
    					while(!k1) ;
    					led=~led;
    		            keyvalue++;
    					if(keyvalue==4)
    						flag=1;
    				} 
    				
    			}	
    			if(k2==0)
    			{
    				delay(1000);
    				if(k2==0)
    				{
    					while(!k2) ;
    				 	led=~led;
    					jia();
    				}
    			}
    			if(k3==0)
    			{
    				delay(1000);
    				if(k3==0)
    				{
    					while(!k3) ;
    				    led=~led;
    					jian();
    				}
    			}	
    		}
    		TR0=1;
    		TR1=0;
    		if(((alarm[6]+alarm[7]*10)*60+alarm[3]+alarm[4]*10)>((time[6]+time[7]*10)*60+time[3]+time[4]*10))//判断闹钟时间是否大于当前时间,
    			alarmexist=1;
    		else
    			alarmexist=0;
    		
    		
    	}
    }			
    void jia()
    {
    	switch(keyvalue)
    	{
    		case 1:time[0]=time[0]+1;addproct(0);break;
    		case 2:time[3]=time[3]+1;addproct(3);break;
    		case 3:time[6]=time[6]+1;addproct(6);break;
    		case 4:alarm[0]=alarm[0]+1;addproca(0);break;
    		case 5:alarm[3]=alarm[3]+1;addproca(3);break;
    		case 6:alarm[6]=alarm[6]+1;addproca(6);break;
    		
    
    	}
    }
    void jian()
    {
    	switch(keyvalue)
    	{
    		case 1:reduceproct(0);break;
    		case 2:reduceproct(3);break;
    		case 3:reduceproct(6);break;
    		case 4:reduceproca(0);break;
    		case 5:reduceproca(3);break;
    		case 6:reduceproca(6);break;
    		
    
    	}
    	
    }
    void Timer0() interrupt 1//非调整时,执行的中断服务程序
    {
    	TH0=0xfc;
    	TL0=0x67;//赋定时器初始值,定时1ms
    	cnt++;
    	if(1000==cnt)
    	{   
    		cnt=0;
    		time[0]=time[0]+1;
    		addproct(0);
    	}
    	P0=0X00;
    	switch(i)
    	{	
    	    case 0:lsa=0;lsb=0;lsc=0;P0=smgduan[time[0]];dian=(alarmexist==1)?1:0;i++;break;
    		case 1:lsa=1;lsb=0;lsc=0;P0=smgduan[time[1]];i++;i++;break;
    		case 3:lsa=1;lsb=1;lsc=0;P0=smgduan[time[3]];i++;break;
    		case 4:lsa=0;lsb=0;lsc=1;P0=smgduan[time[4]];i++;i++;break;
    		case 6:lsa=0;lsb=1;lsc=1;P0=smgduan[time[6]];i++;break;
    		case 7:lsa=1;lsb=1;lsc=1;P0=smgduan[time[7]];i=0;break;
    	}
    }
    void Timer1() interrupt 3	//调整时,执行的中断服务程序  ,flag=0显示正在调整的time,为1显示正在调整的alarm
    {
        
    	TH1=0xfc;
    	TL1=0x67;//赋定时器初始值,定时1ms
        if(flag==0)
    		p=time;
    	else
    		p=alarm;
    	P0=0X00;
    	switch(j)
    	{	
    	    case 0:lsa=0;lsb=0;lsc=0;P0=smgduan[p[0]];j++;break;
    		case 1:lsa=1;lsb=0;lsc=0;P0=smgduan[p[1]];j++;j++;break;
    		case 3:lsa=1;lsb=1;lsc=0;P0=smgduan[p[3]];j++;break;
    		case 4:lsa=0;lsb=0;lsc=1;P0=smgduan[p[4]];j++;j++;break;
    		case 6:lsa=0;lsb=1;lsc=1;P0=smgduan[p[6]];j++;break;
    		case 7:lsa=1;lsb=1;lsc=1;P0=smgduan[p[7]];j=0;break;
    	}
    }
    

    展开全文
  • 单片机、DS18B20、实时时钟、数码管、独立按键、led 二、功能描述 3.1 初始化 1)关闭蜂鸣器、继电器等无关外设; 2)设备初始化时钟为23 时59 分50 秒,闹钟提醒时间0 时0 分0 秒。 3.2 显示功能 1) 时间显示...

    一、硬件

    单片机、DS18B20、实时时钟、数码管、独立按键、led

    二、功能描述
    3.1 初始化
            1)关闭蜂鸣器、继电器等无关外设;
            2)设备初始化时钟为23 时59 分50 秒,闹钟提醒时间0 时0 分0 秒。
    3.2 显示功能
            1) 时间显示格式
                                    1 2 - 0 0 - 0 2
                                                           12 时间隔0 分间隔2 秒
            2) 温度显示格式
                                     8 8 8 8 8 2 1 C
                                       熄灭        温度

    3.3 按键功能
           1)按键S7 定义为“时钟设置”按键,通过该按键可切换选择待调整的时、分、秒,当前选择的显示单元以1 秒为间隔亮灭,时、分、秒、时钟显示的调整需注意数据边界属性。

           2)按键S6 定义为“闹钟设置”按键,通过该按键可进入闹钟时间设置功能,数码管显示当前设定的闹钟时间。

           3) 按键S5 定义为“加”按键,在“时钟设置” 或“闹钟设置” 状态下,每次按下该按键当前选择的单元(时、分或秒)增加1 个单位。
           4) 按键S4 定义为“减”按键,在“时钟设置” 或“闹钟设置” 状态下,每次按下该按键当前选择的单元(时、分或秒)减少1 个单位。
           5) 按键功能说明:按键S4、S5 的“加”、“减”功能只在“时钟设置”或“闹钟设置”状态下有效;在“时钟显示”状态下,按下S4 按键,显示温度数据,松开按键,返回“时钟显示”界面。
    3.4 闹钟提示功能
           1)指示灯L1 以0.2 秒为间隔闪烁,持续5 秒钟;
           2)闹钟提示状态下,按下任意按键,关闭闪烁提示功能。

    三、代码

    #include<reg52.h>
    #include<stdio.h>
    #define uint unsigned int
    #define uchar unsigned char
    
    sbit dula=P2^6;					  //控制数码管的段选端:当前数码管选中的发光段
    sbit wela=P2^7;					  //控制数码管的位选端:选用什么位置的数码管
    sbit led=P1^0;
    sbit s4=P3^6;					  //减少键、显示温度键
    sbit s5=P3^7;					  //增加键
    sbit s2=P3^4;					  //“闹钟设置”按键
    sbit s3=P3^5;					  //“时钟设置”按键
    sbit DS=P2^2; 					  //ds温度传感器
    sbit buzzer=P2^3;				  //蜂鸣器
              
    uint temp;								   //温度参数
    unsigned char flag = 0;                    //判断数码管的闪烁            
    uchar flag1,shi1,ge1,shi2,ge2,shi3,ge3;	   //时分秒的个十位
    uchar aa,aa1,hour=23,min=59,second=57;	   //时钟初始化: 23:59:50
    uchar nhour=0,nmin=0,nsecond=0;			   //闹钟初始化: 00:00:00
    uchar code table[]={0x3f,0x06,0x5b,0x4f,
                        0x66,0x6d,0x7d,0x07,
                        0x7f,0x6f,0x00};  //定义对应0~9,最后一个是是熄灭数码管
    
    /***************************************************/
    /*             *******温度器*******                */
    /***************************************************/
    void delay1(uint count)     			  //延时函数
    {
      uint i;
      while(count)
      {
        i=200;
        while(i>0)
        i--;
        count--;
      }
    }
    
    void dsreset(void)       				  //初始化函数,温度传感器复位
    {
      uint i;
      DS=0;
      i=103;
      while(i>0)i--;
      DS=1;
      i=4;
      while(i>0)i--;
    }
    
    bit tmpreadbit(void)       				  //读一位数据函数
    {
       uint i;
       bit dat;								  
       DS=0;i++;          					 //i++起到延时作用
       DS=1;i++;i++;
       dat=DS;
       i=8;while(i>0)i--;
       return (dat);
    }
    
    uchar tmpread(void)   					  //读一个字节数据函数
    {
      uchar i,j,dat;
      dat=0;
      for(i=1;i<=8;i++)
      {
        j=tmpreadbit();						   
        dat=(j<<7)|(dat>>1);   				  //读出数据最低位在最前面,这样刚好1字节在dat里
      }
      return(dat);
    }
    
    void tmpwritebyte(uchar dat)   			  //向DS18B20写入一字节数据函数
    {
      uint i;
      uchar j;
      bit testb;
      for(j=1;j<=8;j++)
      {
        testb=dat&0x01;
        dat=dat>>1;
        if(testb)    						  //写1
        {
          DS=0;
          i++;i++;
          DS=1;
          i=8;while(i>0)i--;
        }
        else
        {									  //写0
          DS=0;      
          i=8;while(i>0)i--;
          DS=1;
          i++;i++;
        }
    
      }
    }
    
    void tmpchange(void)  					  //获取温度
    {
      dsreset();
      delay1(1);
      tmpwritebyte(0xcc);  					  //写跳过读rom指令
      tmpwritebyte(0x44); 					  //写温度转换指令
    }
    
    uint tmp()               				  //读取寄存器中存储的温度数据
    {
      float tt;
      uchar a,b;
      dsreset();
      delay1(1);
      tmpwritebyte(0xcc);
      tmpwritebyte(0xbe);
      a=tmpread();							  //读低8位
      b=tmpread();							  //读高8位
      temp=b;
      temp<<=8;           					  //两个字节组合为一个字
      temp=temp|a;
      tt=temp*0.0625;						  //温度在寄存器中为12位,分辨率为0.0625度
      temp=tt*10+0.5;						  //乘以10,表示为小数后面只取一位,加0.5是四舍五入
      return temp;
    }
    
    void DSdisplay(uint temp)					//显示温度函数
    {
       uchar A1,A2,A2t;
       A1=temp/100;
       A2t=temp%100;
       A2=A2t/10;
    
       dula=1;
       P0=table[A1];		
       dula=0;
       wela=1;
       P0=0xf7;
       wela=0;
       delay1(1);
    
       dula=1;
       P0=table[A2];		
       dula=0;
       wela=1;
       P0=0xef;
       wela=0;
       delay1(1);
    	
       dula=1;
       P0=0x58;
       dula=0;
       wela=1;
       P0=0xdf;
       wela=0;
       delay1(1);
    }
    
    void wendu()				                //按键显示温度主函数
    {
       if(!s4)
       {
    	   delay1(10);
    		if(!s4)
    		{
               uchar a=25;
               tmpchange();
    	       while(a>0)  
    		   {
    		       a--;
    			   DSdisplay(tmp());  		 
    		   }
    		   while(!s4);
    	    }
    	}
    }
    
    /***************************************************/
    /*             *******时钟*******                  */
    /***************************************************/         
    void inint()								//定时器的设置
    {											//使用定时器0和1
            TMOD=0x11;
            TH0=(65536-45872)/256;
            TL0=(65536-45872)%256;
    		TH1=(65536-45872)/256;
            TL1=(65536-45872)%256;
            EA=1;
            ET0=1;					 //打开T0定时器中断
    		ET1=1;					 //打开T1定时器中断
            TR0=1;					 //开始启用T0计数器/定时器
            TR1=1;					 //开始启用T1计数器/定时器
    }
    
    void delay(uint z)							//毫秒延时函数
    {
            uint x,y;
            for(x=z;x>0;x--)
              for(y=110;y>0;y--);
    }
    
    
    void displayhour(uchar h)	     //显示小时函数
    {
    	 if(h==-1)
    	 {
    		dula=1;								
            P0=table[10];
            dula=0;
            wela=1;
            P0=0xfe;
            wela=0;
            delay(2);
    
            dula=1;
            P0=table[10];
            dula=0;
            wela=1;
            P0=0xfd;
            wela=0;
            delay(2);
    	 }
    		
    	 else 
    	 {
    		shi1=h/10;
            ge1=h%10;
           								
            dula=1;								
            P0=table[shi1];
            dula=0;
            wela=1;
            P0=0xfe;
            wela=0;
            delay(2);
    
            dula=1;
            P0=table[ge1]|0x80;
            dula=0;
            wela=1;
            P0=0xfd;
            wela=0;
            delay(2);
    	 }
    }
    
    void displaymin(uchar m)	 //显示分钟函数
    {	 
       if(m==-1)
       {
    	  dula=1;
          P0=table[10];
          dula=0;
          wela=1;
          P0=0xfb;
          wela=0;
          delay(2);
    
          dula=1;
          P0=table[10];
          dula=0;
          wela=1;
          P0=0xf7;
          wela=0;
          delay(2);
       }
       else
       {	  
    	  shi2=m/10;
          ge2=m%10;
    
    	  dula=1;
          P0=table[shi2];
          dula=0;
          wela=1;
          P0=0xfb;
          wela=0;
          delay(2);
    
          dula=1;
          P0=table[ge2]|0x80;
          dula=0;
          wela=1;
          P0=0xf7;
          wela=0;
          delay(2);
    	}
    }
    
    void displaysecond(uchar s)	     //显示秒钟函数
    {
      if(s==-1)
      {
        dula=1;
        P0=table[10];
        dula=0;
        wela=1;
        P0=0xef;
        wela=0;
        delay(2);
    
        dula=1;
        P0=table[10];
        dula=0;
        wela=1;
        P0=0xdf;
        wela=0;
        delay(2); 
      }
      else
      {	
    	shi3=s/10;
        ge3=s%10;
    
    	
        dula=1;
        P0=table[shi3];
        dula=0;
        wela=1;
        P0=0xef;
        wela=0;
        delay(2);
    
        dula=1;
        P0=table[ge3];
        dula=0;
        wela=1;
        P0=0xdf;
        wela=0;
        delay(2);
      }
    }
    
    void naozhong()	                 //闹钟函数
    {	
        uint n=15;
        if(hour==nhour&&min==nmin&&second==nsecond)
        while(n--)
        {
    		if(s5==0||s4==0||s2==0||s3==0)
    		{
    			delay(10);
    		    if(s5==0||s4==0||s2==0||s3==0)
    		    {
    			   while((!s4)||(!s5)||(!s2)||(!s3));
    			   break; 
    			}
    		}
    		displayhour(hour);
    		displaymin(min);
    		displaysecond(second);
    		led=0;
    		delay(200);
    		led=1;
    		delay(200); 
    	}
    }
    
    
     /***************时钟设置键*****************/
    void key7()
    {	
         uchar n=1;
    	 ET0=0;										 //中断定时器0
    	 while(1)
    	 {
    	  if(n==1)          
    	  {  
    		while(1)
    		{
    			if(s3==0)
    			{
    				delay(10);
    				if(s3==0)
    				{
    					while(!s3);
    					n++;
    					break;
    				}
    			}
    			if(flag==1)displayhour(hour);			//闪烁数码管
    			else displayhour(-1);
    			displaymin(min);
    			displaysecond(second);
    			if(s5==0)
    			{
    			    delay(10);
    				if(s5==0)
    				{
    					while(!s5);
    					hour++;
    					if(hour==24)hour=0;
    				}
    			}
    			if(s4==0)
    			{
    				delay(10);
    				if(s4==0)
    				{
    					while(!s4);
    					hour--;
    					if(hour==-1)hour=23;
    				}
    			}
    		}
    	  }
    	  else if(n==2)           
    		   {
    			  while(1)
    			  {
    				  if(s3==0)
    				  {
    					  delay(10);
    					  if(s3==0)
    					  {
    						while(!s3);
    						n++;
    						break;
    					  }
    				  }	
    				if(flag==1)displaymin(min);
    		    	else displaymin(-1);
    			    displayhour(hour);
    			    displaysecond(second);
    				if(s5==0)
    				{
    					delay(10);
    					if(s5==0)
    					{
    						while(!s5);
    						min++;
    						if(min==60)min=0;
    					
    					}
    				}
    				if(s4==0)
    				{
    					delay(10);
    					if(s4==0)
    					{
    						while(!s4);
    						min--;
    						if(min==-1)min=59;
    					}
    				}
    			  }
    			}
    			else if(n==3)           //?????
    			{
    				while(1)
    				{
    				  if(s3==0)
    				  {
    					  delay(10);
    					  if(s3==0)
    					  {
    							while(!s3);
    							n++;
    							break;
    					  }
    				  }
    				if(flag==1)displaysecond(second);
    		        else displaysecond(-1);
    			    displayhour(hour);
    			    displaymin(min);
    				if(s5==0)
    				{
    					delay(10);
    					if(s5==0)
    					{
    						while(!s5);
    						second++;
    						if(second==60)second=0;
    					}
    				}
    				if(s4==0)
    				{
    					delay(10);
    					if(s4==0)
    					{
    						while(!s4);
    						second--;
    						if(second==-1)second=59;
    					}
    				}
    			 }
    			}
    			
    			if(n>=4)break;
    		 }
    		 ET0=1;								  //开启定时器1
    }
    
     /***************闹钟设置键*******************/
    void key6()
    {	uchar n=1;
    	 while(1)
    	 {
    	  if(n==1)          
    	  {  
    		while(1)
    		{
    			if(s2==0)
    			{
    				delay(10);
    				if(s2==0)
    				{
    					while(!s2);
    					n++;
    					break;
    				}
    			}
    			if(flag==1)displayhour(nhour);
    			else displayhour(-1);
    			displaymin(nmin);
    			displaysecond(nsecond);
    			if(s5==0)
    			{
    			    delay(10);
    				if(s5==0)
    				{
    					while(!s5);
    					nhour++;
    					if(nhour==24)nhour=0;
    				}
    			}
    			if(s4==0)
    			{
    				delay(10);
    				if(s4==0)
    				{
    					while(!s4);
    					nhour--;
    					if(nhour==-1)nhour=23;
    				}
    			}
    		}
    	  }
    	  else if(n==2)           
    		   {
    			  while(1)
    			  {
    				  if(s2==0)
    				  {
    					  delay(10);
    					  if(s2==0)
    					  {
    						while(!s2);
    						n++;
    						break;
    					  }
    				  }	
    				if(flag==1)displaymin(nmin);
    		    	else displaymin(-1);
    			    displayhour(nhour);
    			    displaysecond(nsecond);
    				if(s5==0)
    				{
    					delay(10);
    					if(s5==0)
    					{
    						while(!s5);
    						nmin++;
    						if(nmin==60)nmin=0;
    					
    					}
    				}
    				if(s4==0)
    				{
    					delay(10);
    					if(s4==0)
    					{
    						while(!s4);
    						nmin--;
    						if(nmin==-1)nmin=59;
    					}
    				}
    			  }
    			}
    			else if(n==3)           //?????
    			{
    				while(1)
    				{
    				  if(s2==0)
    				  {
    					  delay(10);
    					  if(s2==0)
    					  {
    							while(!s2);
    							n++;
    							break;
    					  }
    				  }
    				if(flag==1)displaysecond(nsecond);
    		        else displaysecond(-1);
    			    displayhour(nhour);
    			    displaymin(nmin);
    				if(s5==0)
    				{
    					delay(10);
    					if(s5==0)
    					{
    						while(!s5);
    						nsecond++;
    						if(nsecond==60)nsecond=0;
    					}
    				}
    				if(s4==0)
    				{
    					delay(10);
    					if(s4==0)
    					{
    						while(!s4);
    						nsecond--;
    						if(nsecond==-1)nsecond=59;
    					}
    				}
    			 }
    			}
    			
    			if(n>=4)break;
    		 }
    }		  
    
    void main()
    {
        inint();						 //初始化
    	buzzer=1;						 //初始化蜂鸣器
        while(1)
       {		   
    	    displayhour(hour);
    		displaymin(min);
    		displaysecond(second);
    		if(0==s2)					   //闹钟设置
    		{
    		    delay(10);
    			if(0==s2)
    			{
    				while(!s2);
    				key6();
    			}
    		}
    		if(0==s3)					   //时钟设置
    		{
    			delay(10);
    			if(0==s3)
    			{
    				while(!s3);
    				key7();
    			}
    		}
            naozhong();
    		wendu();
    	}
    } 
    
    void zhongduan1() interrupt 1	  //定时器0中断
    {
        TH0=(65536-45872)/256;
        TL0=(65536-45872)%256;
        aa++;
        if(aa==20)
        {
           aa=0;
           second++;
           if(second==60)
           {
              second=0;
              min++;
              if(min==60)
              {
                 min=0;
                 hour++;
              }
            }
            if(hour==24 && second==0)
            {
               hour=0;
               min=0;
               second=0;                                                                                                                                 
            }                        
        }
    }
    
    void zhongduan2() interrupt 3	  //定时器1中断
    {
       	TH1=(65536-45872)/256;
        TL1=(65536-45872)%256;
    	aa1++;
    	if(aa1==20)
    	{
    	   aa1=0;
    	   if(flag==0)	flag=1;
    	   else  flag=0; 
    	}
    }

     

    展开全文
  • 单片机电子钟程序

    2020-05-30 23:30:14
    运行89c52实现的电子钟程序,可以显示电子钟设置,倒计时等功能
  • 51单片机电子闹钟程序及仿真图 完整的一套程序,下载即可用!
  • 单片机电子闹钟程序

    2020-07-28 23:32:45
    单片机电子闹钟设计,是一个非常厉害的程序
  • 从知道什么是单片机到实现了简单的电子钟表程序竟然比我预期的段了很多时间,我自己参考了很多程序,设计出来了自己的电子钟程序,本着来自网络奉献网络的原则,把源码给大家分享。程序设计参考了郭天祥视频中讲解的...
  • 单片机电子时钟完整版(基于at89c51电子时钟论文,keil程序编写,professional仿真,pcb原理图) 目录 摘要 1 第一章 系统设计要求 2 1.1 基本功能 2 1.2 扩展功能 2 第二章 硬件总体设计方案 3 2.1系统功能实现总体...
  • 15.9 单片机电子时钟程序设计

    千次阅读 2016-07-09 07:17:59
    下边这个程序的功能是一个带日期的电子钟,相当于一个简易万年历了,并且加入了按键调时功能。学有余力的同学看到这里,不妨先不看我们提供的代码,自己写写试试。如果能够独立写一个按键可调的万年历程序单片机...
  • 本文和大家分享一个LCD1602屏幕单片机电子时钟程序,并带有详细注释,感兴趣的朋友可以看看。
  • ; 定时器T0、T1溢出周期为50MS,T0为秒计数用, T1为调整时闪烁用, ; P3.7为调整按钮,P1口 为字符输出口,采用共阳显示管。 ;; 显示数据在70H-75H单元内,用六位LED共阳数码管显示,P1口输出段码数据,P3口作 ...
  • 单片机电子时钟课程设计(含源代码和仿真图)单片机电子时钟课程设计(含源代码和仿真图)单片机电子时钟课程设计(含源代码和仿真图)单片机电子时钟课程设计(含源代码和仿真图)单片机电子时钟课程设计(含源代码...
  • 用c语言编写的单片机电子钟程序,以及在protues中的仿真电路。
  • 基于STC89C52RC单片机和DS1302芯片的电子闹钟设计,具有时间显示和调整、闹钟时间和响铃时长设定、中断响铃等功能,软件部分用汇编语言编写,并可用Protues仿真测试
  • 数码管由于内部由多段LED灯构成,也被称为多段式LED数码管。 从数码管里面包含的LED个数来分,可以分为七段式、八段式、十四段式等。 七段式数码管: 八段式数码管(比七段式右下角多了一个小点): ...
  • 想用51单片机做一个电子钟,但是刚接触单片机,只会编流水灯的程序,请指点一下具体的实现原理
  • 基于单片机电子时钟设计,要求: (1)实时显示当前时间; (2)能够对时间进行设置; (3)包括年月日,小时,分钟,秒. (4)整点提醒功能. 经过一周的时间已实现上述功能,故在此分享一下; 所选用器材 ...
  • 51单片机数字课程设计(带闹钟,还有数字串在数码管上滚动显示的案例),C语言源程序+PROTEUS仿真电路图。
1 2 3 4 5 ... 20
收藏数 4,853
精华内容 1,941
关键字:

单片机电子钟程序