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

📄 main.c

📁 PIC18系列下的DS1302时钟程序 源吗哦 测试通过可以用
💻 C
📖 第 1 页 / 共 3 页
字号:
//定时器低优先级中断入口函数声明
void TMR0_TMR1_IsR(void);
#pragma code low_vector=0x18
void low_interrupt(void)
{
  _asm goto TMR0_TMR1_IsR _endasm	
}
#pragma code
//-------------------------------------------------------------

//-------------------------------------------------------------
//---主程序 main函数
void main(void)
{
  unsigned char i,j;
  unsigned long temp;
  
  INTOsC_Initize();		//初始化时钟源
  TMR0_Initize();		//初始化TMR0定时器
  ADC_Initize();		//初始化A/D模块
  InitizeLED();			//初始化LED数码管显示
  INTCONbits.GIE=1;		//CPU开中断
  INTCONbits.PEIE=1;	//CPU的第二梯队中断允许
  
  while(1)
    {
	  //-------------------------------------------------------
	  //---功能键及数字调节键识别与处理过程
	  //---
	  //-------------------------------------------------------
	  //---闹铃设置功能键
	  if(0==ALARMKEY)	//闹铃设置键是否按下
	    {
		  Delay(1000);	//去抖动
		  if(0==ALARMKEY)//是真得按下了吗
		    {
			  AlarmKeyID++;	//闹铃设置状态变量加1
			  if(1==AlarmKeyID)//在闹铃设置状态为1的情况下,复制当前日历的内容到闹铃变量中
			    {
				  AlarmClock.second=RealClock.second;	//复制秒
				  AlarmClock.Minute=RealClock.Minute;	//复制分
				  AlarmClock.Hour=RealClock.Hour;		//复制时
				  AlarmClock.Week=RealClock.Week;		//复制日
				  AlarmClock.Day=RealClock.Day;			//复制星期
				}
			  if(0==AlarmClock.status)//如果闹铃是关闭的,则
			    {
				  if(2==AlarmKeyID)AlarmKeyID=0;//直接回到正常状态
				}
			    else//如果是闹铃是打开的,则
			      {
				    if(5==AlarmKeyID)AlarmKeyID=0;//可以设置时分秒闹铃时间
				  }
			}
		  while(0==ALARMKEY);	//等待按键释放
		}
	  //-------------------------------------------------------
	  //---校准日期的功能键
	  if(0==DATEKEY)//日期校准按键是否按下
	    {
		  Delay(1000);//去按键抖动
		  if(0==DATEKEY)//再判断是否真得按下
		    {
			  TimeKeyID=0;//其它校准或设置变量状态为正常状态
			  AlarmKeyID=0;
			  DateKeyID++;//校准日期状态变量加1
			  if(5==DateKeyID)DateKeyID=0;//所有校准完毕,回到正常状态			  
			}
		  while(0==DATEKEY);//等待按键释放
		}
	  //-------------------------------------------------------
	  
	  //-------------------------------------------------------
	  //---校准时间的功能键
	  if(0==TIMEKEY)
	    {
		  Delay(1000);
		  if(0==TIMEKEY)
		    {
			  DateKeyID=0;//其它校准或设置变量状态为正常状态
			  AlarmKeyID=0;
			  TimeKeyID++;
			  if(4==TimeKeyID)TimeKeyID=0;			  
			}
		  while(0==TIMEKEY);
		}
	  //-------------------------------------------------------
	  
	  //-------------------------------------------------------
	  //---数字加调节键
	  if(0==NUMBERADDKEY)//数字增调节键按下了
	    {
		  Delay(1000);//去抖动
		  if(0==NUMBERADDKEY)//再判断是否真得按下
		    {
			  if(AlarmKeyID>0)//如果闹铃设置状态是处于设置条件下,则
			    {
				  switch(AlarmKeyID)//根据闹铃状态变量来分析调节哪个功能
				    {
					  case 1://闹铃打开/关闭设置状态
						//如果闹铃关闭则打开,否则关闭
					    if(0==AlarmClock.status)AlarmClock.status=1; 
					      else AlarmClock.status=0;
					    break;
					  case 2://设置闹铃的时状态
					    if(0!=AlarmClock.status) //如果闹铃是打开的,则
					      {
						    AlarmClock.Hour++;//闹铃的时变量加1
						    if(24==AlarmClock.Hour)AlarmClock.Hour=0;//到24归0
						  }
					    break;
					  case 3://设置闹铃的分状态
					    if(0!=AlarmClock.status)//如果闹铃是打开的,则
					      {
						    AlarmClock.Minute++;//闹铃的分变量加1
						    if(60==AlarmClock.Minute)AlarmClock.Minute=0;//到60归0
						  }					  
					    break;
					  case 4://设置闹铃的秒状态
					    if(0!=AlarmClock.status) //如果闹铃是打开的,则
					      {
						    AlarmClock.second++;//闹铃的秒变量加1
						    if(60==AlarmClock.second)AlarmClock.second=0;//到60归0
						  }					  
					    break;					  
					}
				  if((AlarmKeyID>1)&&((0==DateKeyID)||(0==TimeKeyID)))
				    {
			      	  //将调整的结果送到LED显示缓冲区
			      	  LEDBuffer[0]=AlarmClock.second%10;
			           LEDBuffer[1]=AlarmClock.second/10;
			           LEDBuffer[2]=AlarmClock.Minute%10;
			           LEDBuffer[3]=AlarmClock.Minute/10;
			           LEDBuffer[4]=AlarmClock.Hour%10;
			           LEDBuffer[5]=AlarmClock.Hour/10;
					}
				}
			  if(TimeKeyID>0)//如果时间设置状态是处于设置状态条件下,则
			    {
				  switch(TimeKeyID)//根据时间设置状态变量的数值来决定
				    {
					  case 1://时间设置的时状态
					    RealClock.Hour++;//时间设置时加1
					    if(24==RealClock.Hour)RealClock.Hour=0;//到24归0
						//将其转换成16进制,以方便写入Ds1302的时寄存器单元
					    i=((RealClock.Hour/10)<<4)|(RealClock.Hour%10);
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x84,i);//写入Ds1302的时寄存器单元
					    Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;
					  case 2://时间设置的分状态
					    RealClock.Minute++;//时间设置的分加1
					    if(60==RealClock.Minute)RealClock.Minute=0;//到60归0
						//将其转换成16进制,以方便写入Ds1302的分寄存器单元
					    i=((RealClock.Minute/10)<<4)|(RealClock.Minute%10);
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x82,i);//写入Ds1302的分寄存器单元
					    Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;
					  case 3://时间设置的秒状态
					    RealClock.second++;//时间设置的秒变量加1
					    if(60==RealClock.second)RealClock.second=0;//到60归0
						//将其转换成16进制,以方便写入Ds1302的秒寄存器单元
					    i=((RealClock.second/10)<<4)|(RealClock.second%10);
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x80,i);//写入Ds1302的秒寄存器单元
					   Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;    
					}    
				}
			  if(DateKeyID>0)//如果日期设置状态变量处于设置状态条件下,则
			    {
				  switch(DateKeyID)//根据日期设置状态变量的内容来决定
				    {
					  case 1://年份校准状态
					    RealClock.Year++;//设置的年变量加1
					    if(99<RealClock.Year)RealClock.Year=0;//到100归0
					    //将其转换成16进制,以方便写入Ds1302的年寄存器单元
i=((RealClock.Year/10)<<4)|(RealClock.Year%10);
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x8c,i);//写入Ds1302的年寄存器单元
					    Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;
					  case 2://月份校准状态
					    RealClock.Month++;//设置的月变量加1
					    if(12<RealClock.Month)RealClock.Month=1;//到12归1
						//将其转换成16进制,以方便写入Ds1302的月寄存器单元
					    i=((RealClock.Month/10)<<4)|(RealClock.Month%10);
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x88,i);//设置Ds1302的月寄存器单元
					    Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;
					  case 4://星期校准状态
					    RealClock.Week++;//设置星期变量加1
					    if(7<RealClock.Week)RealClock.Week=1;//到8归1
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x8a,RealClock.Week);//写入Ds1302的星期
					    Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;
					  case 3://日期校准状态
					    RealClock.Day++;//设置日的变量加1
					    switch(RealClock.Month)//根据月份来调整日期最大值
					      {
						    case 1://属于一个月中有31天的调整
						    case 3:
						    case 5:
						    case 7:
						    case 8:
						    case 10:
						    case 12:						      
						      if(31<RealClock.Day)RealClock.Day=1;//到32归1
						      break;
						    case 4://属于一个月中有30天的调整
						    case 6:
						    case 9:
						    case 11:
						      if(30<RealClock.Day)RealClock.Day=1;//到31归1
						      break;    
						    case 2://属于2月份根据是平的还是闰年来调整
						      if(0==(RealClock.Year%4))//如果是闰年.则
							    {
								  if(29<RealClock.Day)RealClock.Day=1;//到30归1
								}
							    else//是平年,则
								  {
									if(28<RealClock.Day)RealClock.Day=1;//到29归1
								  }
							  break;
						  }
						//将其转换成16进制,以方便写入Ds1302的日寄存器单元
					    i=((RealClock.Day/10)<<4)|(RealClock.Day%10);
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x86,i);//写入Ds1302的日寄存器单元
					    Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;
					}
				}
			  //在设置状态下将所调节的内容装入显示缓冲区
			  if(((DateKeyID>0)||(TimeKeyID>0))&&(0==AlarmKeyID))
			    {
			      //将调整的结果送到LED显示缓冲区
			      LEDBuffer[0]=RealClock.second%10;	//秒的个位
			      LEDBuffer[1]=RealClock.second/10;	//秒的十位
			      LEDBuffer[2]=RealClock.Minute%10;	//分的个位
			      LEDBuffer[3]=RealClock.Minute/10;	//分的十位
			      LEDBuffer[4]=RealClock.Hour%10;	//时的个位
			      LEDBuffer[5]=RealClock.Hour/10;	//时的十位
			      LEDBuffer[6]=RealClock.Week;		//星期
			      LEDBuffer[7]=RealClock.Day%10;	//日的个位
			      LEDBuffer[8]=RealClock.Day/10;	//日的十位
			      LEDBuffer[9]=RealClock.Month%10;	//月的个位
			      LEDBuffer[10]=RealClock.Month/10;	//月的十位
			      LEDBuffer[11]=RealClock.Year%10;	//年的个位
			      LEDBuffer[12]=RealClock.Year/10;	//年的十位
			    }
			}
		  while(0==NUMBERADDKEY);//等待数字增调节键释放
		}
	  //-------------------------------------------------------
	  
	  //-------------------------------------------------------
	  //---数字减调节键程序段
	  if(0==NUMBERsUBKEY)//数字减调节键按下
	    {
		  Delay(1000);//去抖动
		  if(0==NUMBERsUBKEY)//再判断是否真得按下
		    {
			  if(TimeKeyID>0)//如果时间设置状态变量是处于设置状态条件下,则
			    {
				  switch(TimeKeyID)//根据时间设置状态变量来决定
				    {
					  case 1://时间设置的时状态
					    RealClock.Hour--;//时减1
					    if(0xFF==RealClock.Hour)RealClock.Hour=23;//到-1则归23
						//将其转换成16进制,以方便写入Ds1302的时寄存器单元
					    i=((RealClock.Hour/10)<<4)|(RealClock.Hour%10);
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x84,i);//写入Ds1302的时寄存器单元
					    Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;
					  case 2://时间设置的分状态
					    RealClock.Minute--;//分减1
					    if(0xFF==RealClock.Minute)RealClock.Minute=59;//到-1归59
						//将其转换成16进制,以方便写入Ds1302的分寄存器单元
					    i=((RealClock.Minute/10)<<4)|(RealClock.Minute%10);
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x82,i);//写入Ds1302的分寄存器单元
					    Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;
					  case 3://时间设置的秒状态
					    RealClock.second--;//秒减1
					    if(0xFF==RealClock.second)RealClock.second=59;//到-1归59
						//将其转换成16进制,以方便写入Ds1302的秒寄存器单元
					    i=((RealClock.second/10)<<4)|(RealClock.second%10);
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x80,i);//写入Ds1302的秒寄存器单元
					    Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;    
					}    
				}
			  if(DateKeyID>0)//日期设置状态变量是处于设置条件下,则
			    {
				  switch(DateKeyID)//根据日期设置状态变量来决定
				    {
					  case 1://日期设置的年份
					    RealClock.Year--;//年变量减1
					    if(0xFF==RealClock.Year)RealClock.Year=99;//到-1归99
						//将其转换成16进制,以方便写入Ds1302的年寄存器单元
					    i=((RealClock.Year/10)<<4)|(RealClock.Year%10);
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x8c,i);//写入Ds1302的年寄存器单元
					    Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;
					  case 2://日期设置的月份
					    RealClock.Month--;//月变量减1
					    if(0==RealClock.Month)RealClock.Month=1;//到0归1
						//将其转换成16进制,以方便写入Ds1302的月寄存器单元
					    i=((RealClock.Month/10)<<4)|(RealClock.Month%10);
					    Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
					    Write_Ds1302_RTC(0x88,i);//写入Ds1302的月寄存器单元
					    Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
					    break;

⌨️ 快捷键说明

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