#include "reg52.h"
#include "eeprom52.h"
#include "Nixie tube.h"
//宏定義
#define uchar unsigned char
#define uint unsigned int
//按鍵定義
sbit key_1 = P1^0; //定義設置時間
sbit key_2 = P1^3; //定義鬧鈴設置
sbit key_3 = P1^1; //定義數據加
sbit key_4 = P1^2; //定義數據減
sbit beep = P3^5; //蜂鳴器設置
sbit dp =P2^7; //數碼管小數點定義
uchar code ss[]=
{
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x80 //0-9不包括小數點
};
uchar code ss1[]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x80}; //0,1,2,3,4,5,6,7,8,9,小數點亮其他滅 0-9包括小數點
uchar put[8],sec,min,hour,N_hour,N_min,ms,state,state1,time; //定義鬧鈴、時間變量
bit mode,s1,beep1,beep2,beep3;
/********************************************************************
* 名稱 : delay()
* 功能 : 小延時。
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void delay(uint ys)
{
while(ys--);
}
/********************************************************************
* 名稱 : show()
* 功能 : 數碼管顯示程序
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void show()
{
uchar i;
if(mode==0) //當前時間顯示
{
if(state==1&s1==1) //設置閃爍處理
{
put[7]=10;
put[6]=10;
}
else
{
put[7]=hour/10%10; //小時顯示暫存數據
put[6]=hour%10;
}
put[5]=0x40;
if(state==2&s1==1) //設置閃爍處理
{
put[4]=10;
put[3]=10;
}
else
{
put[4]=min/10%10; //分鐘顯示暫存數據
put[3]=min%10;
}
put[2]=0x40;
if(state==3&s1==1) //設置閃爍處理
{
put[1]=10;
put[0]=10;
}
else
{
put[1]=sec/10%10; //秒顯示暫存數據
put[0]=sec%10;
}
Nixietube(ss1[put[7]],ss1[put[6]],ss1[put[4]],ss1[put[3]],ss[put[1]],ss[put[0]]) ; //顯示時間
}
else
{ dp=0;
put[7]=0xF7;
put[6]=0xB8;
put[5]=0x40;
if(state1==1&s1==1) //設置閃爍處理
{
put[4]=10;
put[3]=10;
}
else
{
put[4]=N_hour/10%10; //鬧鐘小時顯示暫存數據
put[3]=N_hour%10;
}
put[2]=0x40;
if(state1==2&s1==1) //設置閃爍處理
{
put[1]=10;
put[0]=10;
}
else
{
put[1]=N_min/10%10; //鬧鐘分鐘顯示暫存數據
put[0]=N_min%10;
}
Nixietube(put[7],put[6],ss1[put[4]],ss1[put[3]],ss[put[1]],ss[put[0]]) ; //顯示鬧鈴
}
}
/********************************************************************
* 名稱 : key()
* 功能 : 按鍵控制程序
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void key()
{
if(!key_1)//判斷按鍵是否按下
{
delay(1000); //按鍵延時去抖
if(!key_1) //在次判斷按鍵是否按下
{
while(!key_1) show(); //按鍵判斷釋放 并調用顯示程序 作用:使按按鍵是數碼管顯示無異常
if(mode==0) //執行按鍵對應的控制內容
{
state=(state+1)%4; //切換設置項
}
}
}
if(!key_2) //判斷按鍵是否按下
{
delay(1000); //按鍵延時去抖
if(!key_2) //在次判斷按鍵是否按下
{
while(!key_2) show(); //按鍵判斷釋放 并調用顯示程序 作用:使按按鍵是數碼管顯示無異常
if(state==0) //執行按鍵對應的控制內容
{
state1=(state1+1)%3; //模式切換 設置鬧鐘時間
if(state1==0)
{
mode=0;
}else
{
mode=1;
}
}
}
}
if(!key_3) //判斷按鍵是否按下
{
delay(1000); //按鍵延時去抖
if(!key_3) //在次判斷按鍵是否按下
{
while(!key_3) show(); //按鍵判斷釋放 并調用顯示程序 作用:使按按鍵是數碼管顯示無異常
if(mode==0) //執行按鍵對應的控制內容
{
switch(state) //根據當前的模式和設置項 設置值的大小并保存
{
case 1:
hour++;
if(hour>23) hour=0;
SectorErase(0x2400); //保存數據到單片機EEPROM中
byte_write(0x2400,hour);
break;
case 2:
min++;
if(min>59) min=0;
SectorErase(0x2200); //保存數據到單片機EEPROM中
byte_write(0x2200,min);
break;
case 3:
sec++;
if(sec>59) sec=0;
break;
}
}else
{
switch(state1) //根據當前的模式和設置項 設置值的大小并保存
{
case 1:
N_hour++;
if(N_hour>23) N_hour=0;
SectorErase(0x2600); //保存數據到單片機EEPROM中
byte_write(0x2600,N_hour);
break;
case 2:
N_min++;
if(N_min>59) N_min=0;
SectorErase(0x2800); //保存數據到單片機EEPROM中
byte_write(0x2800,N_min);
break;
}
}
}
}
if(!key_4)//判斷按鍵是否按下
{
delay(1000); //按鍵延時去抖
if(!key_4) //在次判斷按鍵是否按下
{
while(!key_4) show(); //按鍵判斷釋放 并調用顯示程序 作用:使按按鍵是數碼管顯示無異常
beep1=0; //執行按鍵對應的控制內容
if(mode==0) //根據當前的模式和設置項 設置值的大小并保存
{
switch(state)
{
case 1:
if(hour!=0)hour--;
else hour=23;
SectorErase(0x2400); //保存數據到單片機EEPROM中
byte_write(0x2400,hour);
break;
case 2:
if(min!=0)min--;
else min=59;
SectorErase(0x2200); //保存數據到單片機EEPROM中
byte_write(0x2200,min);
break;
case 3:
if(sec!=0)sec--;
else sec=59;
break;
}
}else
{ //根據當前的模式和設置項 設置值的大小并保存
switch(state1)
{
case 1:
if(N_hour!=0)N_hour--;
else N_hour=23;
SectorErase(0x2600); //保存數據到單片機EEPROM中
byte_write(0x2600,N_hour);
break;
case 2:
if(N_min!=0)N_min--;
else N_min=59;
SectorErase(0x2800); //保存數據到單片機EEPROM中
byte_write(0x2800,N_min);
break;
}
}
}
}
}
/********************************************************************
* 名稱 : main()
* 功能 : 主程序
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void main()
{
TMOD=0x01; //定時器0配置 模式0
TH0=0x3c; //定時50ms 賦初值
TL0=0xb0;
EA=1; //打開總中斷
ET0=1; //定時器0中斷
TR0=1; //定時器0啟動定時
min=byte_read(0x2200); //讀取單片機EEPROM中保存的數據
hour=byte_read(0x2400);
N_hour=byte_read(0x2600);
N_min=byte_read(0x2800);
if(sec>59||min>59||hour>23||N_hour>23||N_min>59) //判斷讀出的數據是否正確 如果不正確
{
hour=15; //則重新賦值
min=30;
sec=0;
N_hour=14;
N_min=30;
}
SectorErase(0x2200); //保存數據到單片機EEPROM中
byte_write(0x2200,min);
SectorErase(0x2400); //保存數據到單片機EEPROM中
byte_write(0x2400,hour);
SectorErase(0x2600); //保存數據到單片機EEPROM中
byte_write(0x2600,N_hour);
SectorErase(0x2800); //保存數據到單片機EEPROM中
byte_write(0x2800,N_min);
while(1)
{
show(); //調用數碼管顯示程序
key(); //調用按鍵控制程序
if(state==0&&mode==0) //鬧鐘報警處理部分
{
if(min==N_min&&hour==N_hour)
{
if(beep3==0)
{
beep3=1;
beep1=1;
}
}else
{
beep3=0;
beep1=0;
}
}
}
}
void init_1() interrupt 1 //定時器0中斷服務程序
{
TH0=0x3c; //重新賦值
TL0=0xb0;
ms++; //計時變量計時
if(ms%5==0)
{
if(beep1==1||beep2==1)//蜂鳴器報警處理
{
beep=!beep;
}else
{
beep=1;
}
}
if(ms%10==0) s1=!s1; //數碼管設置閃爍處理
if(ms>19) //1s定時
{
ms=0;
if(time!=0) time--; //倒計時
else beep2=0;
if(state==0)sec++; //非設置狀態計時
if(sec>59) //1min 定時 整點鬧鈴
{
sec=0;
min++;
SectorErase(0x2200); //保存數據到單片機EEPROM中
byte_write(0x2200,min);
if(min>59) //1hour 定時
{
time=2;
beep2=1; //蜂鳴器標志
min=0;
SectorErase(0x2200); //保存數據到單片機EEPROM中
byte_write(0x2200,min);
hour++;
SectorErase(0x2400); //保存數據到單片機EEPROM中
byte_write(0x2400,hour);
if(hour>23)
{
hour=0;
SectorErase(0x2400); //保存數據到單片機EEPROM中
byte_write(0x2400,hour);
}
}
}
}
}
|