#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
#include "KeyBoard.h" //键盘头文件
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
void KEY(); //声明按键函数
sbit LSA=P2^2; //数码管管脚定义
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit Led=P2^0;//定义定时时间发光灯
sbit Light=P2^1;//定义开始定时状态指示灯
sbit Beep=P1^5; //定义蜂鸣器
bit noise=0; //定时标志位,用于存储定时开关的状态
u8 flag=1,flag_set=0; //开始暂停变量falg,1是时钟时间暂停 flag_set是设置变量,0是回到正常时钟,不进行时分秒设置
u8 KeyValue,vieset=0; //用来存放读取到的键值
u8 hour=9,min=0,sec=0; //初始时间(正常时钟行走时间)
u8 shi=9;fen=1,miao=0; //开始定时
u8 shi1=9;fen1=3,miao1=0; //结束定时
u8 shi2=9;fen2=7,miao2=0; //开始定时2
u8 shi3=9;fen3=10,miao3=0; //结束定时2
u8 DisplayData[8]; //显示数组
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴极数码管段码
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : datapros
* 函数功能 : 计算函数,计算时分秒个位和十位
*******************************************************************************/
void datapros(u8 a,u8 b,u8 c) //计算函数:个位数值为0 将0的段码赋值为对应数码管显示数组的值
{
DisplayData[0] = smgduan[a/10]; //时 十位
DisplayData[1] = smgduan[a%10]; //时 个位
DisplayData[2] = 0x40; //横杠
DisplayData[3] = smgduan[b/10]; //分 十位
DisplayData[4] = smgduan[b%10]; //分 个位
DisplayData[5] = 0x40; //横杠
DisplayData[6] = smgduan[c/10]; //秒 十位
DisplayData[7] = smgduan[c%10]; //秒 个位
}
/*******************************************************************************
* 函数名 :DigDisplay()
* 函数功能 :数码管显示函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void DigDisplay()
{
u8 i;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示秒的个位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示秒的十位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示横杠
case(3):
LSA=1;LSB=1;LSC=0; break;//显示分的个位
case(4):
LSA=0;LSB=0;LSC=1; break;//显示分的十位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示横杠
case(6):
LSA=0;LSB=1;LSC=1; break;//显示时的个位
case(7):
LSA=1;LSB=1;LSC=1; break;//显示时的十位
}
P0=DisplayData[7-i]; //发送数据
delay(100); //间隔一段时间扫描
P0=0x00; //消隐
}
}
/******定时器0中断初始化******/
void Timer0_Init()
{
TMOD=0X01; //选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
ET0=1; //打开定时器0中断允许
EA=1; //打开总中断
TR0=1; //打开定时器
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
Timer0_Init(); //定时器0中断初始化
while(1) //vieset是切换显示的关键,根据vieset的不同0 1 2 3 4来对显示进行改变
{
KeyValue=KeyBoard();
KEY();
if(vieset==0) //正常时钟行走
{
datapros(hour,min,sec); //数据处理函数
DigDisplay(); //数码管显示函数
}
else if(vieset==1) //第一个定时开始
{
datapros(shi,fen,miao); //数据处理函数
DigDisplay(); //数码管显示函数
}
else if(vieset==2) //第一个定时结束
{
datapros(shi1,fen1,miao1); //数据处理函数
DigDisplay(); //数码管显示函数
}
else if(vieset==3) //第二个定时开始
{
datapros(shi2,fen2,miao2); //数据处理函数
DigDisplay(); //数码管显示函数
}
else if(vieset==4)
{ //第二个定时结束
datapros(shi3,fen3,miao3); //数据处理函数
DigDisplay(); //数码管显示函数
}
}
}
/******T0中断服务函数******/
void Timer0() interrupt 1
{
static u16 i; //定义一个静态变量类累计定时 1ms 次数,当变量等于 1000
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
//定时部分
if((min==fen)&&(hour==shi)&&(noise==1)) //时钟的时和分走到与第一个定时开始的时和分相等时,并且定时开关已经打开
{
Light=0; //状态指示灯亮起
}
else if((min==fen1)&&(hour==shi1)&&(noise==1)) //时钟的时和分走到与第一个定时结束的时和分相等时,并且定时开关已经打开
{
Beep=0; //蜂鸣器响起
Led=~Led; //定时灯亮起
Light=1; //状态指示灯关闭
}
else if((min==fen2)&&(hour==shi2)&&(noise==1)) //时钟的时和分走到与第二个定时开始的时和分相等时,并且定时开关已经打开
{
Light=0; //状态指示灯亮起
}
else if((min==fen3)&&(hour==shi3)&&(noise==1)) //时钟的时和分走到与第一个定时结束的时和分相等时,并且定时开关已经打开
{
Beep=0; //蜂鸣器响起
Led=~Led; //定时灯亮起
Light=1; //状态指示灯关闭
}
else
{
Beep=1;
Led=1;
}
//24小时时钟显示部分
if((flag==0)&&(flag_set==0)) //判断时钟是否已经开始行走 设置键是否被按下
{
i++;
if(i==1000) //1000*1ms 即1秒到
{
i=0; //清零变量
sec++; //秒钟++
if(sec==60) //秒钟为60即需要进位 秒钟置零 分钟加1
{
sec=0;
min++;
if(min==60) // 分钟为60即需要进位 分钟置零 小时加1
{
min=0;
hour++;
if(hour==24) //时钟为24则回到0
{
hour=0;
}
}
}
}
}
}
/******按键函数******/
void KEY()
{
if(KeyValue==1) //开始暂停键
{
if(flag!=0) //按下开始暂停键对flag标志位变量取反
{
flag=0; //时钟开始
}
else
flag=1; //时钟暂停
}
if(KeyValue==2) //显示键
{
vieset++; //vieste变量值0显示时钟 1显示第一个开始定时时间 2显示第一个结束定时时间 3显示第二个开始定时时间 4显示第二个结束定时时间
if(vieset==5)
{
vieset=0; //按下第五次回到正常时钟
}
}
if(KeyValue==3) //复位按下,回到开始时钟
{
hour=9;
min=0;
sec=0;
}
if(KeyValue==4) //设置模式
{
flag_set++; //flag_set变量值,0不进行时分秒设置 1修改秒 2修改分 3修改时
if(flag_set==4) //当按下第四次时,回到0
{
flag_set=0; //时钟正常行走
}
}
if(KeyValue==7) //定时按键
{
noise=1; //打开定时
}
if(KeyValue==8) //人工干预定时停止
{
noise=0; //关闭定时
}
/****加减时间设置****/
if(flag_set==1) //设置按键按下第一次对秒进行设置
{
if(KeyValue==5) //加时间
{
if(vieset==0) //显示时钟, 对时钟的秒进行修改
{
sec++; //sec值加一
if(sec==60) //当秒钟等于60的时候需要置零
{
sec=0;
}
}
else if(vieset==1) //显示第一个开始定时时间,对秒进行修改
{
miao++;
if(miao==60)
{
miao=0;
}
}
else if(vieset==2) //显示第一个结束定时时间,对秒进行修改
{
miao1++;
if(miao1==60)
{
miao1=0;
}
}
else if(vieset==3) //显示第二个开始定时时间,对秒进行修改
{
miao2++;
if(miao2==60)
{
miao2=0;
}
}
else if(vieset==4) //显示第二个结束定时时间,对秒进行修改
{
miao3++;
if(miao3==60)
{
miao3=0;
}
}
}
if(KeyValue==6) //减时间
{
if(vieset==0) //显示时钟, 对时钟的秒进行修改
{
sec--; //sec值减一
if(sec==-1)
{ //当显示0时再按减按键,设置时间回到59
sec=59;
}
}
else if(vieset==1) //显示第一个开始