程序清单
本程序用C语言编写,经Keil C51编译成二进制码后写入89C51内的EPROM内即可。
#i nclude "atmel\at89x51.h"
#i nclude "intrins.h"
unsigned char hour,min,sec,year,month,day,weekday
unsigned int count_down
bit LED_on
unsigned char display[8]
unsigned char attr
bit flash
unsigned char show_status
// 0:设置闹钟数据
// 1:显示当前日期及星期
// 2:显示当前时间
// 3:设置当前日期
// 4:设置当前时间
bit km
bit kp
bit sound
bit alarm_stop
struct { unsigned char h
unsigned char m
} alarm[8]
unsigned char alarm_en
unsigned char alarm_wk
unsigned char cur_alarm_set
unsigned char cur_alarm_active
bit new_alarm_info
sbit sound_output = P1^5
sbit SDA_PIN = P1^6
sbit SCL_PIN = P1^7
void I2cDelay() //EEPROM操作时需要的延时函数
{ _nop_()
_nop_()
}
void DelayX1ms(unsigned char count) //延迟函数,参数为毫秒数
{unsigned char i,j
for(i=0
for(j=0
}
void Start() //I2C启动,24C08使用I2C方式
{ SDA_PIN=1
SCL_PIN=1
SDA_PIN=0
SCL_PIN=0
}
void Stop() //I2C停止
{ I2cDelay()
I2cDelay()
I2cDelay()
I2cDelay()
}
bit SendByte(unsigned char value) //发送1字节数据给EEPROM
{unsigned char i
bit no_ack=0
for(i=0
{ I2cDelay()
if(value&0x80) SDA_PIN=1
else SDA_PIN=0
value=value<<1
I2cDelay()
I2cDelay()
I2cDelay()
}
I2cDelay()
I2cDelay()
I2cDelay()
if(SDA_PIN==1) no_ack=1
I2cDelay()
return no_ack
}
void mywrite(unsigned char address,unsigned char value) //向EEPROM写1字节
{ Start()
SendByte(value)
}
unsigned char ReadByte() //从EEPROM接收1字节
{unsigned char i,bval
bval=0
for(i=0
{ I2cDelay()
SDA_PIN=1
I2cDelay()
I2cDelay()
I2cDelay()
}
I2cDelay()
I2cDelay()
I2cDelay()
I2cDelay()
return(bval)
}
unsigned char myread(unsigned char address) //从EEPROM读入1字节数据
{unsigned char tmp
Start()
Start()
Stop()
return(tmp)
}
void Timer0ISR(void) interrupt 1 using 3 //定时器0中断程序,用于走时,1/8000秒一次
{unsigned char tmp,tmp_days
count_down--
if(count_down==1 || count_down==2001 || count_down==4001 || count_down==6001)
{ flash=~flash
if(sound && flash) sound_output=0
else sound_output=1
return
}
if(count_down==3000)
{ if(year==0) weekday=5
else { tmp=(year-1)/4+1
weekday=(tmp+5)%7
}
tmp_days=0
for(tmp=1
if(tmp==1 || tmp==3 || tmp==5 || tmp==7 || tmp==8 || tmp==10)
tmp_days=tmp_days+31
else if(tmp==4 || tmp==6 || tmp==9 || tmp==11)
tmp_days=tmp_days+30
else if(tmp==2)
{ if(year%4==0) tmp_days=tmp_days+29
else tmp_days=tmp_days+28
}
tmp_days=tmp_days+day-1
return
}
if(count_down==5000)
{ if((alarm_stop || sound) && alarm[cur_alarm_active].m!=min) //触发后1分钟
{ alarm_stop=0
if(sound==0 && alarm_stop==0) //没有已触发的闹钟项
for(tmp=0
{ if(((alarm_en>>tmp)&1)==0) continue
if(((alarm_wk>>tmp)&1)==1) //该闹钟项周末有效
{ if(weekday!=6 && weekday!=7) continue
else
{ if(weekday==6 || weekday==7) continue
if(alarm[tmp].h==hour && alarm[tmp].m==min) //比较当前时间与该
{ sound=1
}
return
}
if(count_down==0) //过了一秒钟