#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);
}
}
}
}
}
|