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

📄 mainclockwws.c

📁 PIC单片机为基础实现的时钟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************************************
///////////////////////////////////////////////////////////////////////////////////////////////////////
电子时钟程序   王文硕   07-4-1/////////////////////////////////////////////////////////////////////////
//功能:---------完成分钟数的计时功能.可通过按键调整时间和设置闹钟.有2个闹钟可供使用////////////////////
//使用方法:-----时间设置:待通电后数码管显示12.00  则为当前显示时间.可通过按键4切换为时间设置模式,//////
//                       按键1为小时加一,按键2为分钟数加一.按键3退出.//////////////////////////////////
//--------------闹钟1设置:待通电后数码管显示12.00  则为当前显示时间.可通过按键3切换至当前闹钟1时间,////
//                        闹钟1初试值为11.11  则通过按键1来调整小时数加一,按键2来调整分钟数加一,按键4//
//                        退出.////////////////////////////////////////////////////////////////////////
//--------------闹钟2设置:待通电后数码管显示12.00  则为当前显示时间.可通过按键2切换至当前闹钟1时间,////
//                        闹钟2初试值为10.10  则通过按键1来调整进入小时数加一,按键2来调整分钟数加一,///
//                        按键4则退出./////////////////////////////////////////////////////////////////
//注意:---------当闹钟时间设置超过30S则自动退出到当前时钟模式./////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*****************************************************************************************************/

#include<pic.h>

static char   led[15]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/////////////////////////////////不带小数点的段码
static char   led1[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
/////////////////////////////////带小数点的段码
static char   tab,number,k;       
/////////////////////////////////取LED[]数组中的值用tab,键盘服务程序使用计数值number
static char   clock[4]={0,0,2,1},wakeup1[4]={2,0,2,1},wakeup2[4]={0,1,0,1};
/////////////////////////////////时钟数组,闹钟1和闹钟2数组
static char   mode=0,key=0,clktemp=0,sec=0; 
/////////////////////////////////mode选择设置模式,分为时间设置mode=4,闹钟2设置mode=3,闹钟1设置mode=2
/////////////////////////////////key选择设置增加小时和分钟.clktemp为1分钟到后的中断标志位 
static int   i,time=0;        
/////////////////////////////////循环使用值i,设置调整时间计数值,当调整内循环次数超过3000时.自动跳入主循环      
/**********************************************************************
函数定义                                                             
**********************************************************************/
void initial();                     //初始化函数
void speaker(char i);               //蜂明器鸣响程序
void twinkle(char x);               //RC5端口LED闪烁
void yw1641(char z);                //移位显示函数-1段数码管 
void yw1642(char z);                //移位显示函数-2段数码管
void yw1643(char z);                //移位显示函数-3段数码管
void yw1644(char z);                //移位显示函数-4段数码管
     
void clkcf();                       //时钟数据拆分函数
void checkclock();                  //检测闹钟时间是否到了
        
void keyscan();                    //键盘服务函数寻主键  
void keyscanw();                    //键盘服务函数寻副键
void DELAY2();                      //短延时函数
void DELAY1();                      //长延时函数
void DELAY3();                      //防止按键颤抖延时函数
/************************************************************
==========================主程序==============================
**************************************************************/
void main()
{ 
    initial();       //系统初始化
    speaker(1);      //蜂明器响3声
    twinkle(2);      //闪烁6次
  	INTCON=0xc0;     //中断使能
    PIE1=0x01;       //T1中断使能
    TMR1H=0x80;     //32k晶振.初始值为0x8000.经调整为0x80a0.
    TMR1L=0xa0;
    for(;;)
    {    
        checkclock();
        
             
        switch(1)     //主循环执行时钟数组扫描更新与键盘按键扫描
                {  
                case 1:  yw1641(clock[3]);          //执行第一段数码管显示.显示内容为时钟数组clock[3] .  
                          DELAY2();                       //延时显示.此段延时决定数码管的亮度问题
                case 2:  yw1642(clock[2]);          //执行第二段数码管显示.显示内容为时钟数组clock[2] .
                          DELAY2();                       //延时显示.此段延时决定数码管的亮度问题
                case 3:  yw1643(clock[1]);          //执行第三段数码管显示.显示内容为时钟数组clock[1] .  
                          DELAY2();                       //延时显示.此段延时决定数码管的亮度问题
                case 4:  yw1644(clock[0]);          //执行第四段数码管显示.显示内容为时钟数组clock[0] .  
                          DELAY2();                      //延时显示.此段延时决定数码管的亮度问题   
                case 5:  keyscan();                //外部寻找工作模式,得出工作模式mode的返回值
                          DELAY2();                      //此段延时是为了保证程序的5次循环采用统一延时效果
                   break;
                }

         
         while(mode==2)                        //mode返回值为2--闹钟1调整 
                {    time=time+1;              //时间设置超过3000没有任何操作则自动退出      
	                 switch(1)                 //次循环执行闹钟1时间的调整.即是移位164对时钟1的数组wakeup1[4]的扫描,循环显示
                          {  
                         case 1:  yw1641(wakeup1[3]); //执行第一段数码管显示.显示内容为时钟数组wakeup1[3] . 
                                  DELAY3();           //延时显示.此段延时决定数码管的亮度问题
                         case 2:  yw1642(wakeup1[2]); //执行第二段数码管显示.显示内容为时钟数组wakeup1[2] .
                                  DELAY3();
                         case 3:  yw1643(wakeup1[1]); //执行第三段数码管显示.显示内容为时钟数组wakeup1[1] .
                                  DELAY3();
                         case 4:  yw1644(wakeup1[0]); //执行第四段数码管显示.显示内容为时钟数组wakeup1[0] .  
                                  DELAY3();
                         case 5:  keyscanw();      //内部键盘循环.寻找按键是增加闹钟时间还是减小闹钟时间,跳出键
                                  DELAY3();
                                   break;
                          }
	                 if(key==1)              //按键key=1即是对闹钟1时间的增加.增加分钟时间
                           {    
                             wakeup1[0]=wakeup1[0]+1;    //闹钟时间分钟加一
	                         if(wakeup1[0]==10)          //闹钟分钟个位数满十
	                         {
	                             wakeup1[1]=wakeup1[1]+1; //则分钟数十位加一
	                             wakeup1[0]=0;           //分钟个位数清零
	                             if(wakeup1[1]==6)       //分钟十位满六
		                           {
		                            wakeup1[1]=0;         //则分钟十位清零
		                            wakeup1[0]=0;         //分钟个位清零.相当于调整至59分钟.再从0开始加计数
		                            }
		                     }
		                    key=0;        //消除按键,防治再次跳入更改时间
		                   }
	                 if(key==3)        //按键key=3对闹钟1的小时调整.              
		                   {    
			                wakeup1[2]=wakeup1[2]+1;      //闹钟小时个位加一
		                    if(wakeup1[2]==10)            //闹钟小时个位满十
		                       { 
		                         wakeup1[3]=wakeup1[3]+1;  //小时十位加一
			                     wakeup1[2]=0;             //小时个位清零
			                   } 
			                if(wakeup1[3]==2&&wakeup1[2]==4) //当时间增加为24小时时消为00
			                   {
			                   wakeup1[3]=0;wakeup1[2]=0;     //小时个位十位统一清零
			                   }
				        key=0;   //消除按键,防治再次跳入更改时间                  
		           
		                   }       
	                if(time>3000) mode=0;//时间设置超过3000没有任何操作则自动退出.次循环结束把模式mode值变为0,防止再次进入下模式
	                if(key==4) break;	//按键4出现则调整闹钟结束      
	              }
        
        while(mode==3)       //mode返回值为2--闹钟2调整
                     {     
                           time=time+1;   //时间设置超过3000没有任何操作则自动退出
	                       switch(1)
                              {  
                                case 1:  yw1641(wakeup2[3]); //执行第一段数码管显示.显示内容为时钟数组wakeup1[3] .
                                          DELAY3();
                                case 2:  yw1642(wakeup2[2]); //执行第二段数码管显示.显示内容为时钟数组wakeup1[2] .
                                          DELAY3();
                                case 3:  yw1643(wakeup2[1]); //执行第三段数码管显示.显示内容为时钟数组wakeup1[1] .
                                          DELAY3();
                                case 4:  yw1644(wakeup2[0]); //执行第四段数码管显示.显示内容为时钟数组wakeup1[0] .
                                          DELAY3();
                                case 5:  keyscanw();   //内部键盘循环.寻找按键是增加闹钟时间还是减小闹钟时间,跳出键
                                          DELAY3();
                                         break;
                                }
	                       if(key==1)   //按键key=1即是对闹钟2时间的增加.增加分钟时间
                                {
                                  wakeup2[0]=wakeup2[0]+1;
	                              if(wakeup2[0]==10)   
	                                 {
	                                     wakeup2[1]=wakeup2[1]+1;
	                                     wakeup2[0]=0;
	                                    if(wakeup2[1]==6)   
		                                    {
		                                     wakeup2[1]=0;
		                                     wakeup2[0]=0;
		                                    }
		                              }
		                           key=0; //消除按键,防治再次跳入更改时间
		                         }
	                       if(key==2)           //按键key=2对闹钟2的小时调整.         
		                       {    
		                           wakeup2[2]=wakeup2[2]+1;
		                           if(wakeup2[2]==10)   
		                               { 
		                                  wakeup2[3]=wakeup2[3]+1;
			                              wakeup2[2]=0;} 
			                             if(wakeup2[3]==2&&wakeup2[2]==4) //当时间增加为24小时时消为00
			                                 {
			                                    wakeup2[3]=0;wakeup2[2]=0;
			                                  }
				                   key=0;                     
		                         }       
	                       if(time>3000) mode=0;  //时间设置超过3000没有任何操作则自动退出.次循环结束把模式mode值变为0,防止再次进入下模式
	                       if(key==4) break;	 //按键4出现则调整闹钟结束        
	               }	            
     
      while(mode==4)    //次模式是对时间的更改模式mode=4
                  {    
                           time=time+1;
	                       switch(1)
                                 {  
                                    case 1:  yw1641(clock[3]);
                                              DELAY3();
                                    case 2:  yw1642(clock[2]);
                                              DELAY3();
                                    case 3:  yw1643(clock[1]);
                                              DELAY3();
                                    case 4:  yw1644(clock[0]); 
                                              DELAY3();
                                    case 5:  keyscanw();
                                              DELAY3();
                                              break;
                                   }
	              
	                       if(key==1)   //按键key=1对当前时钟的小时调整.
	                           {         
	                                clock[0]=clock[0]+1;
		                            if(clock[0]==10)
		                                 { 
		                                    clock[1]=clock[1]+1;
		                                    clock[0]=0;
		                                   if(clock[1]==6)   
		                                        {
		                                           clock[1]=0;
		                                           clock[0]=0;
		                                           }
		                                  }
		         
		                             key=0;
		                       } 	               
	              
	                      if(key==2)   //按键key=2对当前时钟的分钟调整.
	                          {         
	                               clock[2]=clock[2]+1;
		                           if(clock[2]==10)
		                               {
		                                 clock[3]=clock[3]+1;
			                             clock[2]=0;}  	                   
	                                     if(clock[3]==2&&clock[2]==4)   //当时间增加为24小时时消为00
	                                          {
	                                             clock[3]=0;
	                                             clock[2]=0;
	                                          }
		              
		                           key=0;
		                      } 
		                 if(time>3000) mode=0;    //时间设置超过3000没有任何操作则自动退出.次循环结束把模式mode值变为0,防止再次进入下模式
		                 if(key==3) break;        //按键3出现则调整闹钟结束   
		           }
		   
	 if(clktemp==1)   //主循环中执行对分钟标志clktemp的寻找.当出现时即对时间数组clock[4]的更新
             { 
               clktemp=0;  //清楚分钟标志
               clkcf();
             }         
          
    } 
}
/********************************************************************
中断程序程序:                                                    
功能:执行对T1的时间溢出中断操作,当中断时再次对TMR1赋值.1S中断响应一次
********************************************************************/

void interrupt INT()
{
  if(TMR1IF&&TMR1IE)
    {   
     TMR1H=0x80;      //T1时间高位赋值
     TMR1L+=0xa0;     //T1时间低位赋初值
     TMR1IF=0;        //清除中断标志位
     sec=sec+1;       //当中断来时,秒加一
	 if(sec==60)      //当秒加到60的时候清零,置分钟位为1
	 {  sec=0;        //秒计数值清零
        clktemp=1;
     }	    

⌨️ 快捷键说明

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