📄 main.c
字号:
//定时器低优先级中断入口函数声明
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 + -