⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 4display.c

📁 四位时程序,用于时钟计数,从1点到12点计时,带小数点显示.
💻 C
字号:
#include <reg51.h>
unsigned char ComperHourAlarm,ZeroNoDisplay,flashcount,ZeroYesDisplay;
unsigned int TClock;
unsigned int change;
unsigned int plus;
unsigned int TimerCount;
unsigned char temp[8];
unsigned int PLDELAY;

unsigned code DispTab [] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xbf,0x08,0x03,0x06,0xA1,0x91,
0xC7,};
//字形码0-9,不显示,-,a,b,c,d,Y,L,
unsigned char DispBuf [4] = {0,6,1,0,};//显示缓冲区,


/* 以下是对显示的驱动位作标记*/
 
 sbit Hour1 = P2^1;         //小时显示第一位.
 sbit Hour2 = P2^2;         //小时显示第二位.

 sbit Min1 = P2^3;          //分显示第一位.
 sbit Min2 = P2^4;          //分显示第二位.
 sbit PL = P1^5;            //电源电压低.
 sbit Relay = P3^7; 
 

 /*----------以下是对键所在位作标志------------*/
 sbit SetKey = P3^3;  //功能键所在引脚.
 sbit MoveKey = P3^1;   //位移动键所在引脚.
 sbit IncKey = P3^0;  //加一键所在引脚.
 unsigned char SetFlag;  //定义调整的数据位置.
 unsigned char Set;     //要设置的数据中间传送位.
 unsigned char Mi,Max;  //数据要调整的范围.
 
 /*---------以下是对常量和变量进行定义----------*/
unsigned char DispCount;  //用于显示中对显示位数进行计数.
unsigned char ZeroNoDisplay; //用于显示小时位时如显示为09,则将其中的零不显示.
unsigned char flashcount;    //定时0中断中用到的变量.

/*------------------秒脉冲中断用--------------*/
unsigned char Year,Month,Date,Hour,Min,Sec,Wek;      //计数器.
unsigned int t;
bit Clock;
bit CheckDy;
/*------------------闪烁程序中用到-------------*/
unsigned char FlashSet;   //闪动延时值.
bit FlashFlag;            //闪动标志位.
unsigned char SetFlag;
 
 /*--------------------延时程序---------------------*/
void mDelay (unsigned int Delay)

     {  unsigned int i;

	     for (; Delay>0; Delay--)       //延时时间很难选折.会产生不希望产生的鬼影.
		   {for (i=0;i<100;i++)
		       {;}
		   }
	 }



/*--------------加一程序--------------------*/
 void inc ( void)

   {
      Set++;                    //对设置位加一.

	  if (Set > Max )           //如果设置数大于规定最大值,则归位最小值.

	     {Set = Mi;}           //归位最小值.

	}

	  
	  
/*---------------显示及缓冲区刷新程序---------------------*/
                 
void Display ()

         
      {   switch ( DispCount )

		       { 
			    case 0:                             //小时十位显示.
                   
				   Min2 = 1; //关闭年显示第二位.

                   ZeroNoDisplay =  DispBuf [ DispCount ];  //输出段码.

                   
				   if (ZeroNoDisplay==0)
				     
				     {
					    P0 = DispTab [10];             //小时第一位为零时不显示.
					 }
					 else

					 {
					   P0 = DispTab [ DispBuf [ DispCount ] ];
					 }
             
					Hour1 = 0; //点亮月显示第一位.

                   break;

                case 1:                              //小时位个位显示.

				   Hour1 = 1; //关闭月显示第一位.

				   ZeroNoDisplay =  DispBuf [ DispCount ];  //输出段码.
				   
				   if (Clock == 1)

				        {P0 = ( DispTab[ZeroNoDisplay] & 0x7f );}
				   
				     else
				   
					    {P0 = DispTab [ DispBuf [ DispCount ] ];}  //输出段码.
                   
				   Hour2 = 0; //点亮月显示第二位.

                   break;

                case 2:                            //分位十位显示.

				    Hour2 = 1; //关闭月显示第二位.
				
				    P0 = DispTab [ DispBuf [ DispCount ] ];
                   
					Min1 = 0;   //点亮日显示第一位..

                    break;

                 case 3:                          //分位个位显示.

				   Min1 = 1; //关闭日显示第二位.
				 
				   P0 = DispTab [ DispBuf [ DispCount ] ];
				   
				   Min2 = 0; //点亮小时显示第一位.

                   break;


                  
               }

			    mDelay (1);
				 
				 DispCount++;
  
			      if ( DispCount==4 )     //显示位数计数,以确定下一轮显示哪一位.

			           { 
				          DispCount = 0;

				       }
			 
				  
	         }

	

/*----------------调时中用到的延时---------------------*/

 void lDelay (unsigned int hDelay)

   {   unsigned int i;
        
         for (;hDelay>0; hDelay--)
		   { for (i=0;i<120;i++)
		       {Display ();}
	       }
   }

	 /*--------------缓冲区刷新程序---------------------*/

      void scan()     
           
          {

           DispBuf [1] = Hour%10;

           DispBuf [0] = Hour/10;      //将小时送入缓冲区.

           DispBuf [3] = Min%10;

		   DispBuf [2] = Min/10;       //将分送入缓冲区.   

           
		   }

 /*---------t0中断执行程序,用于t秒脉冲信号产生,按键及定时鸣叫.---------------*/
void t0(void) interrupt 1 using 0  
  {
        t++;

	    if ( t == 2000)          //半秒时指示.

		  {Clock = 0;}           //秒闪指示位.   
		
		if (t ==4000)            //如果计数到1秒,则T清零.

		  {  t=0;
 
	         if ( t == 0)

			   {Clock = 1;}
		  
		     Sec++;
		
	  	     if ( Sec > 59 )     //秒计到59则秒位清零.
		     
		       { CheckDy = 1;
			   
			     Sec = 0;
			   
			     Min++;
			      
				  if ( Min > 59 )  //分计到59则分位清零.
			        
				     { Min = 0 ;
					  
					   Hour++;
					   
					   if ( Hour > 12 )    //小时计到12,则小时位清零.

					     { Hour = 1;
							  
						 }
						 
					 }
			      }
			  }

        }
	
	 

/*----------------t1中断程序----------------------
/*-----t1中断执行程序,用于执行调整参数时的数字闪烁,闪烁时间到自动退出调整程序.--------*/
 void t1 (void) interrupt 3 using 2 
   {
     
        TH1=(65536-50000)/256;            //T1重置定时数据.
	
	    TL1=(65536-50000)%256;

		FlashSet--;

		 if ( FlashSet == 0 )
 
		      {  FlashSet = 6 ;

			     FlashFlag = ~ FlashFlag;   //对闪动位取反,以决定下一轮是否闪动.

				  if ( FlashFlag ==1)

				       {  

                          switch (SetFlag)        //看是要哪一位闪烁.
	                            {
		                          case 0:

		                             DispBuf [0] = 10;
					   
		                             DispBuf [1] = 10;     //年位闪烁.

                                     break;
								   
								   case 1:

		                             DispBuf [2] = 10;
					   
		                             DispBuf [3] = 10;     //月位闪烁.

                                     break; 
								   
								   
									}

                             }
                     else 

				    {  DispBuf [1] = Hour%10;      //调整时的缓冲区刷新程序.

                       DispBuf [0] = Hour/10;      //将小时送入缓冲区.

                       DispBuf [3] = Min%10;

					   DispBuf [2] = Min/10;       //将分送入缓冲区.   

                      
					}
         }

   }
			     

	 


/*------外部中断1用于执行键盘中断,进行参数调整.----------------------*/

 void int1 () interrupt 2 using 2

  {  
      if ( SetKey ==0 )            //Set键按下进入中断程序.
	    { 
		    lDelay (10);            //延时十毫秒.

		     if ( SetKey == 0)     //再次查询SET键有否按下.

		        {
		           TR0 =0;                   //关闭TR0运行.
				
				   ET0 = 0;                  //关闭TR0中断,以实现调整时的闪烁
				   
				   TR1 = 1;                  //开启TR1运行.
			  
			       ET1 = 1;                  //开TR1中断,以实现调整时的闪烁.    
			  
			       EX1 = 0;                  //关闭外部中断1.

			  //     EX1 = 0;                  //关闭外部中断1.

			      while ( SetKey == 0 )          //设置键按下释放否,未释放则等待.
 			        {
				       Display ();
				    } 
			  
			  
			     while ( SetKey == 1 )       //SetKey键按下,则进入

			          {   Display ();
				         
					     if ( MoveKey == 0)

					           {SetFlag++;           //需移动到的标志位.
							   
							    if (SetFlag==2)
							      
								  {SetFlag=0;}
							   
								}  
						 
						 while ( MoveKey == 0)     //秒位键按下释放否,未释放则等待.
					     
						      {Display ();}
						 
						 if ( IncKey == 0 )
   
					          { switch ( SetFlag )

						           {
                                      case  0:  Mi = 1;

							                    Max = 12;

									            Set = Hour;

									            inc ( );

									            Hour = Set;

									            break;

							           case 1:  Mi = 0;

							                    Max = 59;

										        Set = Min;

										        inc ();

										        Min = Set;

										        break;

								 
									  }
									
							while ( IncKey == 0  )
 			                    {
				                   Display ();
			   	                }		  
							}
								 
								 
						}
						   
			  
			  while ( SetKey == 0 )
 			    {
				  Display ();
				}
				  
			  SetFlag = 0;
				
			  TR0 = 1;                  //开启TR0运行.
				
			  ET0 = 1;                  //开TR0中断,以实现调整时的闪烁.
			  
			  TR1 = 0;                  //关闭TR1运行.
			  
			  ET1 = 0;                  //开TR1中断,以实现调整时的闪烁.    
			  
			  EX1 = 1;                  //开启外部中断1,响应键盘中断.

		
							  
			               }
						 }
					  }

/*---------------------主程序-------------------*/
	  void main (void)

	  {  
	  
	     EA = 1;                    //总中断允许.
	     
	     ET0 = 1;                   //允许定时器0中断.
		 
		 TR0 = 1;                   //开定时器1中断.
		 
		 PT1= 1;                    //定时器1为高优先级.
		 
		 EX1 = 1;                   //允许外部1中断.
		 
		 IT1 = 1;                   //设置外部中断1为外部触发中断.
		 
		 TMOD = 0x12;               //定时器模式.
		 
		 Hour = 8;
		 
		 Min = 18;
		 
		 PLDELAY = 50;
		 
		 Relay = 0;
		 
		 DispCount = 0;
	     
		 SetFlag = 0;
		 
		 FlashSet = 6;               //闪动中用到.
		 
		 TH0=0x06;                   //定时数据.
	
	     TL0=0x06;

	   	TH1=(65536-50000)/256;       //T1重置定时数据.
	
	    TL1=(65536-50000)%256;
	     
		while (1)

		{  

		         Display ();
        
                 scan();

              if ( CheckDy == 1 )      //检查是否使能电源检测.
				 
				  { if ( PL == 0 )     //如果电源电压低则在屏幕上显示电源电压低.

				     { for ( ;PLDELAY > 0;PLDELAY--  )            //屏幕上延时显示电源电压低.
  
					            { DispBuf [1] = 16;      //调整时的缓冲区刷新程序.

                                  DispBuf [0] = 15;      //  电压检测在每分钟的开始开启检测使能,

                                  DispBuf [3] = 17;      //

					              DispBuf [2] = 11;       //
                                 
								  Display ();
								  }
					   }
                
				CheckDy = 0;
	   
                PLDELAY = 50;
			   }
			 }

     }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -